From 1b3b1bab8d6bade72495fad32c8a8b17f1e9d92f Mon Sep 17 00:00:00 2001 From: Veit Heller Date: Fri, 25 Jul 2014 02:41:51 +0200 Subject: [PATCH] initial commit --- nbfi/helloworld.bf | 42 +++++++++++++ nbfi/hw.bf | 1 + nbfi/main.c | 6 ++ nbfi/nbfi | Bin 0 -> 8988 bytes nbfi/nbfi.c | 107 ++++++++++++++++++++++++++++++++ vvm/Makefile | 35 +++++++++++ vvm/bin/vvm | Bin 0 -> 14244 bytes vvm/src/main.c | 34 +++++++++++ vvm/src/opcode.c | 23 +++++++ vvm/src/opcode.h | 36 +++++++++++ vvm/src/util.h | 12 ++++ vvm/src/vm.c | 149 +++++++++++++++++++++++++++++++++++++++++++++ vvm/src/vm.h | 10 +++ 13 files changed, 455 insertions(+) create mode 100644 nbfi/helloworld.bf create mode 100644 nbfi/hw.bf create mode 100644 nbfi/main.c create mode 100755 nbfi/nbfi create mode 100644 nbfi/nbfi.c create mode 100644 vvm/Makefile create mode 100755 vvm/bin/vvm create mode 100644 vvm/src/main.c create mode 100644 vvm/src/opcode.c create mode 100644 vvm/src/opcode.h create mode 100644 vvm/src/util.h create mode 100644 vvm/src/vm.c create mode 100644 vvm/src/vm.h diff --git a/nbfi/helloworld.bf b/nbfi/helloworld.bf new file mode 100644 index 0000000..f079b46 --- /dev/null +++ b/nbfi/helloworld.bf @@ -0,0 +1,42 @@ +++++++++++ +[ + > + +++++++ + > + ++++++++++ + > + +++ + > + + + <<<< + - +] +> +++ +. +> ++ +. ++++++++ +.. ++++ +. +> +++ +. +<< ++++++++++++++++ +. +> +. ++++ +. +------ +. +-------- +. +> ++ +. +> +. diff --git a/nbfi/hw.bf b/nbfi/hw.bf new file mode 100644 index 0000000..265e751 --- /dev/null +++ b/nbfi/hw.bf @@ -0,0 +1 @@ +++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. diff --git a/nbfi/main.c b/nbfi/main.c new file mode 100644 index 0000000..fc073e0 --- /dev/null +++ b/nbfi/main.c @@ -0,0 +1,6 @@ +#include + +int main(){ + printf("Hello, world!\n"); + return 0; +} diff --git a/nbfi/nbfi b/nbfi/nbfi new file mode 100755 index 0000000000000000000000000000000000000000..86346afec8afcd1f529ef1a58dc83bb09642584f GIT binary patch literal 8988 zcmeHNU2Ggz6~43CO$=Fkoi>1hR+^Ru9Fp2;X&Zy6u-j}pQ6q2@hnBuf_Gi}KdUs|u zJJZCdrcO6byKG!6)CVL4ic|?`0Pzy3Nc_}LAvX$w5DC;E1O`E~qcv5;Ls*62;X8Nk z?9c2rQpE#2?2+%>bME=M=bm%!?C!n(_4U7RY++2=#MnZJF}4luYJ{;xCIe&agJ=qx zs!mQk5`Qv&=yNpM4pKYWl_EQDLQqww;!jMqi*WtH_Aw@C_{QK4ZzQ3rmUi4C%!8o4 zbF>(+)<_9JG_9)vVYbk~fv9THvXjNeP|)5>{hqy#3kje075ap|&0@f_r_N}(f@WeY zXm3T>`@E1R`sV(nik6wxryKU$<2N+m`S%aOCmOkIK$~rhs;V}lX3Ruh^F)IF4aPis zSA_+lTkSOr3#6IXeG^j?EnMV}=k@4iZ_v+gOJ2#YNE7^;Hd@jOy1TtTe+t-X^^4+9 zwc>-S>N&MImroiwwP2YY_WFc>zFR~G?KS3tQB}<)Zf0*t*c%fL5Z!8ze0#6&9JiM& z79VI11lPMD?CqZt@q?&eW2D7n+f;{tuy=2BAZYK6^kuFSZi=+kUCD2QeBG#}OL5Zdq^ z-n-}-7&rrZE7~L)0jBTFWtBQn_oTg+;1k6#k(+$)L>F%6OG;roTf1V*0w-;G3@JBpn0e^h(~Lbr0-)1 zQgd$1e|WBFY59?dM&L&_2_XRKjidQ`UUZ>n6s*ylkxJya=a8RHr3gi*7Dw*!ZG05E zaJ4#-q`a$09js9mbNdF zy0R3x1zjZ^Qc@Q|zywpIi|$%fVl0QY8|@(4X{f#1whm*Y^GngcTmAn^Uikbr`q-=S z4drVsOP<9WEVCL8NzD0PH~yo7A7akwZv0(>zlk}yZv3r+A7&24u4Dch-tshmggLvr z@h=GeX68h@@xLqhTUaG><;lzJ!H=9h$n0&(()~N}!g&oUtooyWyKW_N9^9o#sre$Wm}6s^<0~9j zD)B0|LG?UUGzxsa?#32x;VxhL0H(a;F$D^2vQo-2y*ZJl-vA*Ws zgCW{GtMU33cZk*cv41kFC*v~vmCINuUzac$vmNKDZrSPQ-iNWQl~TPg_WVu=we7g= z6mfsYp;Wvbmst)&@Gg*dqtVv}`Z%WVm#5Lrpj|>M#p{w&B?MkLe*yyEVy}9>A=Bh( z`6ceD^Rpn=ZRNh)&V{##Wf?9wWpJu<YGsc~zKGDbfkUPD4y^`Fu(`hu~V}ft_y-P z$LskUWDkv1zYTjL&82m@Jim@t>so1kJ;W=eDfcYoP+e3tRL{S>Lh2i;2(gF_pbgrij!mKUw3zW2}^W$Eb!-Z{CSc;Px0pq{P|@( z@%~-9{Q!`O!|skxqFtmN3)BPsxX^L~2&f7Uhhc%Z$?6C@qR;BaFD z=e4|H&W*qY4v(9LJ}v8ZKB<|qk&zSTw4K*c?#L;H_F`r;ub9Uqhiqg(oxk;dH^yAADR9pM4&B_RUZm~3G1R49ysWBquo zakvl9gJ=~Y{~&P*g7V=pa4?C-Wu$i!ZTVl`JXgp(L5JR7z-ia}F~mNDG9p;yO5OAp zFxb@d#e)4s@jLbRqW`Pt-xhsc^da&4Gb;L^ogUqbKraHl2=pS*i$E^|y$JLo(2GDX z0=)?IBG8LKF9QGj2yDA^=yCF5+qg7{44>lUW_(Y?uElt(g2#hq|i z&Cg&KEoEC8?$Q%9{U=gJzJTK!wpTFNr}K%d&L-#_Y!j=+@c7RA@%RcIcb$vv{mJGl zo7nX~MseiI_Mwp+0UhJ;Qx))t9u_nm-H^=Ima90Bum~W=0JQx7FQB8@0bD#T;PQ-& z(H)vck8_$1_6Bf3=HI*0ePT=^DNlZs(~Q+%i1fz?F2L`3y_K@@o5{&cO=mTx z7QC}ThHAq>Ai4ssvpWkw^$WnS45sn|XenH;GX0tq)!3**uLAj#img#~9hHtX5c~&B CWWF>2 literal 0 HcmV?d00001 diff --git a/nbfi/nbfi.c b/nbfi/nbfi.c new file mode 100644 index 0000000..9ec8aee --- /dev/null +++ b/nbfi/nbfi.c @@ -0,0 +1,107 @@ +#include +#include + +#define OP_END 0 +#define OP_INC_DP 1 +#define OP_DEC_DP 2 +#define OP_INC_VAL 3 +#define OP_DEC_VAL 4 +#define OP_OUT 5 +#define OP_IN 6 +#define OP_JMP_FWD 7 +#define OP_JMP_BCK 8 + +#define PROGRAM_SIZE 1048576 +#define MAX_SIZE 5024291 +#define DATA_SIZE 1638375 + +#define STACK_PUSH(A) (stack[sp++] = A) +#define STACK_POP() (stack[--sp]) +#define STACK_EMPTY() (sp == 0) +#define STACK_FULL() (sp == MAX_SIZE) + +static inline void die(int code, char* message){ + fprintf(stderr, message); + exit(code); +} + +struct instruction_t{ + unsigned short operator; + unsigned short operand; +}; + +static struct instruction_t program[PROGRAM_SIZE]; +static unsigned short stack[MAX_SIZE]; +static unsigned int sp = 0; + +void compile(FILE* fp){ + unsigned short pc = 0, jmp_pc; + int ip; + while ((ip = getc(fp)) != EOF && pc < MAX_SIZE){ + switch (ip) { + case '>': program[pc].operator = OP_INC_DP; break; + case '<': program[pc].operator = OP_DEC_DP; break; + case '+': program[pc].operator = OP_INC_VAL; break; + case '-': program[pc].operator = OP_DEC_VAL; break; + case '.': program[pc].operator = OP_OUT; break; + case ',': program[pc].operator = OP_IN; break; + case '[': + program[pc].operator = OP_JMP_FWD; + if (STACK_FULL()) + die(1, "Cannot jump forwards: Stack is full.\n"); + STACK_PUSH(pc); + break; + case ']': + if (STACK_EMPTY()) + die(1, "Cannot jump backwards: Stack is full.\n"); + jmp_pc = STACK_POP(); + program[pc].operator = OP_JMP_BCK; + program[pc].operand = jmp_pc; + program[jmp_pc].operand = pc; + break; + default: + pc--; + break; + } + pc++; + } + if(!STACK_EMPTY()) + die(1, "Program ends with non-empty stack."); + if(pc == MAX_SIZE) + die(1, "Program exceeds maximum program size."); + program[pc].operator = OP_END; +} + +void execute(){ + unsigned short data[DATA_SIZE], pc = 0; + unsigned int ptr = DATA_SIZE; + while (--ptr) data[ptr] = 0; + while (program[pc].operator != OP_END && ptr < DATA_SIZE){ + switch (program[pc].operator){ + case OP_INC_DP: ptr++; break; + case OP_DEC_DP: ptr--; break; + case OP_INC_VAL: data[ptr]++; break; + case OP_DEC_VAL: data[ptr]--; break; + case OP_OUT: putchar(data[ptr]); break; + case OP_IN: data[ptr] = (unsigned int)getchar(); break; + case OP_JMP_FWD: if(!data[ptr]) { pc = program[pc].operand; } break; + case OP_JMP_BCK: if(data[ptr]) { pc = program[pc].operand; } break; + default: die(2, "Unknown instruction."); + } + pc++; + } + if(ptr == DATA_SIZE) + die(1, "Program used up too much memory."); +} + +int main(int argc, const char * argv[]){ + FILE *fp; + if(argc != 2) + die(1, "Wrong number of arguments supplied.\n"); + if(!(fp = fopen(argv[1], "r"))) + die(1, "File could not be opened.\n"); + compile(fp); + fclose(fp); + execute(); + return 0; +} diff --git a/vvm/Makefile b/vvm/Makefile new file mode 100644 index 0000000..ff3b524 --- /dev/null +++ b/vvm/Makefile @@ -0,0 +1,35 @@ +override CFLAGS+=-Werror -Wall -g -fPIC -O2 -DNDEBUG -std=c99 -ftrapv -Wfloat-equal -Wundef -Wwrite-strings -Wconversion -Wuninitialized +PREFIX=/usr/bin +BUILDDIR=bin/ +CC=gcc-mp-4.9 + +TARGET=vvm +SOURCES=$(wildcard src/*.c) + +#Makes everything +all: + mkdir $(BUILDDIR) 2> /dev/null || true + $(CC) $(CFLAGS) $(SOURCES) -o $(BUILDDIR)$(TARGET) + +#Uses picky extensions and makes everything(Extensions may break compiling) +dev: + make all CFLAGS+=-Wshadow -Wunreachable-code -Wswitch-enum -Wswitch-default -Wcast-align -Winit-self -Wpointer-arith -Weffc++ + +#Cleans directory(no uninstall!) +clean: + rm -rf bin + +#Installs into specified(or default) directory +install: + install -d $(PREFIX)/VVM + install $(BUILDDIR)$(TARGET) $(PREFIX)/VVM + +#Uninstalls from specified(or default)directory +uninstall: + rm -rf $(PREFIX)/VVM + +#Checks for bad functions +BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)' +check: + @echo Files with potentially dangerous functions: + @grep $(BADFUNCS) $(SOURCES) || echo None diff --git a/vvm/bin/vvm b/vvm/bin/vvm new file mode 100755 index 0000000000000000000000000000000000000000..4ddd801733bb7b8767ccbd5b48aa3731b8478677 GIT binary patch literal 14244 zcmeHOeQZ=!7QX|7pdcM~#f7XaqbrCX+i3+96k?~$ls9!~E1hyzI-E>*cTJ41>nh=Iy)+{J!v0d}?$*?37lq^fQ2JXT zH7wpTm?q=H6mU=xT6e43p~t%PBqW9YX3P`uSt%i&=5Z7zj8{u^rY!A={xZ_v+tLB? zRxG1FZG@_7sdO^h*)C;;@vZooi0>8IPP`q)#fk=1)jQO-WH_!1twMjM^mj%&As%b@ zyg=*jV=M?&^?5^Ho0?n1#avPbo`d9Ry^&v9djzW58B(6pW>(?F^ z89=<sh1W@IDs>B2X1EF}7usCFoF^kd6_`QbkAXA5v|i_+?5JdH39xS| zV=WL)2i<@|aJ4Md*CG`AJb@htCY=0aoJ24)f!ru$>*-DW(VqL849)07#)tC*ybE# zeWU-zo>W?omsgh~j%X{C0AyE%V%dr8!Yy3s0txOiXG-Nct#5tLqYAJw>Lkx?D3s=#`PIz0@{kcpyPP{_`r4u z8tB0nWfvacTTommhj5TGfYN~S0eJ)-!V_i}iVI~I4kNlCZUJ_qke{!>@4~|_|7htc=GvX3nFr7{}1^-+Vsr%f9_A_c-Xw?&dL@=a6ZkfaoyZej2v$CsUPj8BO& zSe*@3PBXTO*k~nWb7CHj?WMCPWzg6x+I$oXi70miu&7w#W~U6bNf!bhWYuH z4_wZ!`2=~DNKa%k>5By^5wVIWm4Rpt`OSUdc_s%z=|pB`wZq* z#(l=u<{eN#kRwkEXEL5*>wPvfC$7)u_l->FD+6i1AYVVnpoxGy;qVfxAHTra`W6b`TV;$%4TLWNsZ%gcu47+H+f7)(W*SMe~3gw z_Y4o@7x-Y5Ur@tqh1a#b4)VH=*A2X0%j*!Yn^7Zgxq1J_n7xhp1z!LUbdYf5%X~iH zF^i~Ah`NTT!$d76>L5{f5Ve=6I-+(HbuUqWAnJaiwiDGu)Kf$~PSj>lbbhX&PzOZo zHkxu`$?bH)Ccnu>yKVG?HrlRF?+}amjM(H?gXZrLfayI1fn`HeK{Q^gvVhm;V}Zt| zY8F`26b!L|FVGCK9zx>$cd@|g5UXB`KSDJuu&TbUF~oxPULRY{>&8(1T0dJYP{Z0l zU5GW*H!#Hu2SGSkjk3xc46?O;coYgX{?ICgEr_tD&ZMp-+B>5U>5<#q3nG^>|Hf$A zo#=FTB@^vm^y6$YlzE{9`EtQ$m&gYMOQ8B+3{z9Pba6UWIBRki>gxvxB(B>fHcx;lB zrsDEToLHG`%Va0L-~Nr$iC=^)H)ZoBPSWq4>UJU{g|a^VXKX7XulvJ zU78)zr*xa8Ter`FzcE*cUKHfYN79G31(HP^vQWdPbRzAT}jtK6@7FnK0Basb}=wb$en+xLIF-x#W`0Q@A1QihIIH@7+WuV)-@Bw+c zjo2z;A52EmI&liPc0H|igpMt*eK)b>PMfTZrqnR51{TidT$N)p!TG(zWii zj&JD06#l&_9bfvZQG5lT?AFpzd=AfAHpDG8rpLq4PWG#|u$E3Fqv04!bcU1dDV9!j zX^DuQVm1^kr-{QLs`x&pqU zfL~U?R~7Jq0-i3i>rv=?@|#e8fr4XUMsE`;P%2SwMp=vksJa2w#oD-;rzxc;Q=U{b zf~_hY_V^N7cU + +#include "opcode.h" + +const char* opcodes[] = {"IADD", "ISUB", "IMULT", "IDIV", "IMOD", + "ILT", "IEQ", "IGT", "BR", "BRT", "BRF", "ICONST", "LOAD", "GLOAD", + "STORE", "GSTORE", "PRINT", "POP", "HALT", "LEQ", "GEQ", "CALL", "RET", + "IPRINT", "FETCH"}; + +int nargs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 2, 0, 0, 0 }; + +instruction* setup_instructions(){ + int i; + static instruction ins[FETCH+1]; + ins[0].operands = 0; + ins[0].name = NULL; + for(i = 1; i <= FETCH; i++){ + ins[i].operands = nargs[i-1]; + ins[i].name = opcodes[i-1]; + } + return ins; +} diff --git a/vvm/src/opcode.h b/vvm/src/opcode.h new file mode 100644 index 0000000..85cb319 --- /dev/null +++ b/vvm/src/opcode.h @@ -0,0 +1,36 @@ +#ifndef OPCODE_H +#define OPCODE_H +#define IADD 1 +#define ISUB 2 +#define IMULT 3 +#define IDIV 4 +#define IMOD 5 +#define ILT 6 +#define IEQ 7 +#define IGT 8 +#define BR 9 +#define BRT 10 +#define BRF 11 +#define ICONST 12 +#define LOAD 13 +#define GLOAD 14 +#define STORE 15 +#define GSTORE 16 +#define PRINT 17 +#define POP 18 +#define HALT 19 +#define LEQ 20 +#define GEQ 21 +#define CALL 22 +#define RET 23 +#define IPRINT 24 +#define FETCH 25 + +typedef struct{ + int operands; + const char* name; +}instruction; + +instruction* setup_instructions(); + +#endif diff --git a/vvm/src/util.h b/vvm/src/util.h new file mode 100644 index 0000000..e46d3bf --- /dev/null +++ b/vvm/src/util.h @@ -0,0 +1,12 @@ +#ifndef UTIL_H +#define UTIL_H +#include +#include + +#define LENGTH(x) (sizeof(x) / sizeof(x[0])) + +static inline void die(int code, const char* message){ + fprintf(stderr, "%s", message); + exit(code); +} +#endif diff --git a/vvm/src/vm.c b/vvm/src/vm.c new file mode 100644 index 0000000..7211b98 --- /dev/null +++ b/vvm/src/vm.c @@ -0,0 +1,149 @@ +#include "vm.h" + +#define MAX_SIZE 4096 +#define TRUE 1 +#define FALSE 0 +#define DEBUG FALSE + +static inline void disassemble(int sp, int fp, int ip, int opcode, instruction* ins, int code[], int stack[]){ + if(opcode > 0 && opcode < 24) + printf("%04d: %s(%d)\n", ip, ins[opcode].name, opcode); + if(ins[opcode].operands == 1) + printf("\t%d\n", code[ip+1]); + else if(ins[opcode].operands == 2) + printf("\t%d, %d\n", code[ip+1], code[ip+2]); + int i; + printf("\n===Stack trace===\n"); + for(i = sp; i >= 0; i--) + printf("%04d: %d\n", i, stack[i]); + printf("\n"); +} + +void vm_execute(int code[], int ip, int datasize, int length){ + int data[datasize]; + int stack[MAX_SIZE]; + int sp = -1; + int fp = -1; + int nargs, addr, a, b; + instruction* ins = setup_instructions(); + while(ip < length){ + int opcode = code[ip]; + ip++; + if(DEBUG){ + if(ip+2 != length) + disassemble(sp, fp, ip, opcode, ins, code, stack); + } + switch(opcode){ + case LOAD: + stack[++sp] = stack[code[ip++]+fp]; + break; + case STORE: + stack[fp+code[ip++]] = stack[sp--]; + case BR: + ip = code[ip]; + break; + case BRT: + addr = code[ip++]; + if(stack[sp--] == TRUE) ip = addr; + break; + case BRF: + addr = code[ip++]; + if(stack[sp--] == FALSE) ip = addr; + break; + case IADD: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a + b; + break; + case ISUB: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a - b; + break; + case IMULT: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a * b; + break; + case IDIV: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a / b; + break; + case IMOD: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a % b; + break; + case ILT: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a < b ? TRUE : FALSE; + break; + case IEQ: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a == b; + break; + case IGT: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a > b ? TRUE : FALSE; + break; + case LEQ: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a <= b ? TRUE : FALSE; + break; + case GEQ: + b = stack[sp--]; + a = stack[sp--]; + stack[++sp] = a >= b ? TRUE : FALSE; + break; + case ICONST: + stack[++sp] = code[ip++]; + break; + case GLOAD: + stack[++sp] = data[code[ip++]]; + break; + case GSTORE: + data[code[ip++]] = stack[sp--]; + break; + case IPRINT: + printf("%d", stack[sp--]); + break; + case PRINT: + putchar(stack[sp--]); + break; + case FETCH: + stack[++sp] = getchar(); + break; + case HALT: + return; + case CALL: + addr = code[ip++]; + nargs = code[ip++]; + stack[++sp] = nargs; + stack[++sp] = fp; + stack[++sp] = ip; + fp = sp; + ip = addr; + break; + case RET: + addr = stack[sp--]; + sp = fp; + ip = stack[sp--]; + fp = stack[sp--]; + nargs = stack[sp--]; + sp -= nargs; + stack[++sp] = addr; + break; + case POP: + sp--; + default: + fprintf(stderr, "Unrecognized: %d\n", opcode); + die(1, "Exit on program failure."); + } + } + return; +} diff --git a/vvm/src/vm.h b/vvm/src/vm.h new file mode 100644 index 0000000..8a56428 --- /dev/null +++ b/vvm/src/vm.h @@ -0,0 +1,10 @@ +#ifndef VM_H +#define VM_H + +#include + +#include "util.h" +#include "opcode.h" + +void vm_execute(int[], int, int, int); +#endif