initial commit

This commit is contained in:
Veit Heller
2014-07-25 02:41:51 +02:00
commit 1b3b1bab8d
13 changed files with 455 additions and 0 deletions

42
nbfi/helloworld.bf Normal file
View File

@@ -0,0 +1,42 @@
++++++++++
[
>
+++++++
>
++++++++++
>
+++
>
+
<<<<
-
]
>
++
.
>
+
.
+++++++
..
+++
.
>
++
.
<<
+++++++++++++++
.
>
.
+++
.
------
.
--------
.
>
+
.
>
.

1
nbfi/hw.bf Normal file
View File

@@ -0,0 +1 @@
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

6
nbfi/main.c Normal file
View File

@@ -0,0 +1,6 @@
#include <stdio.h>
int main(){
printf("Hello, world!\n");
return 0;
}

BIN
nbfi/nbfi Executable file

Binary file not shown.

107
nbfi/nbfi.c Normal file
View File

@@ -0,0 +1,107 @@
#include <stdio.h>
#include <stdlib.h>
#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;
}

35
vvm/Makefile Normal file
View File

@@ -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

BIN
vvm/bin/vvm Executable file

Binary file not shown.

34
vvm/src/main.c Normal file
View File

@@ -0,0 +1,34 @@
#include "vm.h"
int factorial[] = {
LOAD, -3,
ICONST, 2,
ILT,
BRF, 10,
ICONST, 1,
RET,
LOAD, -3,
LOAD, -3,
ICONST, 1,
ISUB,
CALL, 0, 1,
IMULT,
RET,
ICONST, 12,
CALL, 0, 1,
IPRINT,
HALT
};
int main(){
int code[] = { ICONST, 72, PRINT, ICONST, 101, PRINT, ICONST, 108,
PRINT, ICONST, 108, PRINT, ICONST, 111, PRINT, ICONST, 44, PRINT,
ICONST, 32, PRINT, ICONST, 119, PRINT, ICONST, 111, PRINT,
ICONST, 114, PRINT, ICONST, 108, PRINT, ICONST, 100, PRINT,
ICONST, 33, GSTORE, 0, GLOAD, 0, PRINT, ICONST, 10, PRINT, HALT };
vm_execute(factorial, 22, 0, sizeof(factorial) / sizeof(factorial[0]));
printf("\n");
vm_execute(code, 0, 1, sizeof(code) / sizeof(code[0]));
return 0;
}

23
vvm/src/opcode.c Normal file
View File

@@ -0,0 +1,23 @@
#include <stdlib.h>
#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;
}

36
vvm/src/opcode.h Normal file
View File

@@ -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

12
vvm/src/util.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef UTIL_H
#define UTIL_H
#include <stdio.h>
#include <stdlib.h>
#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
static inline void die(int code, const char* message){
fprintf(stderr, "%s", message);
exit(code);
}
#endif

149
vvm/src/vm.c Normal file
View File

@@ -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;
}

10
vvm/src/vm.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef VM_H
#define VM_H
#include <stdio.h>
#include "util.h"
#include "opcode.h"
void vm_execute(int[], int, int, int);
#endif