diff options
| -rw-r--r-- | dis.c | 36 | ||||
| -rw-r--r-- | dis.h | 8 | ||||
| -rw-r--r-- | val.c | 21 | ||||
| -rw-r--r-- | val.h | 2 | ||||
| -rwxr-xr-x | vm | bin | 20840 -> 0 bytes | |||
| -rw-r--r-- | vm.c | 51 | ||||
| -rw-r--r-- | vm.h | 5 | 
7 files changed, 109 insertions, 14 deletions
| @@ -0,0 +1,36 @@ +#include "dis.h" + +#include <stdio.h> +#include <stdint.h> + + + +void disasm_chunk(Chunk *ch) { +	for (size_t ip = 0; ip < ch->blen; ) { +		uint8_t instr = ch->b[ip]; +		printf("%04zd\t",ip); +		ip ++; +#define SIMPLE_INSTR(opcode, str) \ +	case opcode: puts(str); break; +		switch (instr) { +		SIMPLE_INSTR(OP_RET, "ret") +		case OP_LOADK:; +			uint8_t ix = ch->b[ip++]; +			printf("loadk #%d\t; ",ix); +			Val k = ch->c[ix]; +			printf("%-4s : ",valty_str(k.ty)); +			println_val(k); +			break; +		SIMPLE_INSTR(OP_PRINT, "print") +		SIMPLE_INSTR(OP_ADD, "add") +		SIMPLE_INSTR(OP_SUB, "sub") +		SIMPLE_INSTR(OP_MUL, "mul") +		SIMPLE_INSTR(OP_DIV, "div") +		} +	} +#undef SIMPLE_INSTR +} + + + + @@ -0,0 +1,8 @@ +#ifndef _dis_h +#define _dis_h + +#include "vm.h" + +void disasm_chunk(Chunk *ch); + +#endif @@ -4,13 +4,28 @@  void print_val(Val v) {  	switch (v.ty) {  	case TY_NIL: -		printf("nil\n"); +		printf("nil");  		break;  	case TY_NUM: -		printf("%f\n",AS_NUM(v)); +		printf("%f",AS_NUM(v));  		break;  	case TY_BOOL: -		printf("%s\n",AS_BOOL(v) ? "true" : "false"); +		printf("%s",AS_BOOL(v) ? "true" : "false");  		break;  	}  } + +void println_val(Val v) { +	print_val(v); +	putchar('\n'); +} + +static const char *ty_names[] = { +	"nil", +	"num", +	"bool", +}; + +const char *valty_str(ValTy ty) { +	return ty_names[ty]; +} @@ -30,6 +30,8 @@ struct _obj {  };  void print_val(Val v); +void println_val(Val v); +const char *valty_str(ValTy ty);  #define IS_NUM(x) (x.ty == TY_NUM)Binary files differ @@ -6,6 +6,7 @@  #include "val.h"  #include "vm.h" +#include "dis.h"  void *M(void *p, size_t sz) {  	if (sz == 0) { @@ -61,22 +62,26 @@ Vm vm_new(Chunk *ch) {  static void runvm() {  	Chunk ch = chunk_new(); +  	chunk_wbc(&ch, OP_LOADK); -	chunk_wbc(&ch, 1); -	chunk_wbc(&ch, OP_PRINT); -	chunk_wbc(&ch, OP_LOADK); -	chunk_wbc(&ch, 2); +	chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(10.0)));  	chunk_wbc(&ch, OP_LOADK); -	chunk_wbc(&ch, 0); +	chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(3.0))); +	chunk_wbc(&ch, OP_DIV); +	chunk_wbc(&ch, OP_PRINT); +  	chunk_wbc(&ch, OP_RET); -	chunk_wconst(&ch, VAL_BOOL(false)); -	chunk_wconst(&ch, VAL_NIL); -	chunk_wconst(&ch, VAL_NUM(420.69)); + +	disasm_chunk(&ch);  	Vm vm = vm_new(&ch);  #define RBYTE() (vm.ch->b[vm.ip++]) +#define PUSH(v) vm.stack[vm.sp++] = v; +#define POP()   (vm.stack[--vm.sp]) + +	puts("---");  	while (1) {  		uint8_t instr = RBYTE();  		switch (instr) { @@ -84,14 +89,38 @@ static void runvm() {  			printf("done!\n");  			goto done;  			break; -		case OP_LOADK: +		case OP_LOADK:;  			uint8_t cix = RBYTE();  			Val v = vm.ch->c[cix]; -			print_val(v); +			PUSH(v); +			// printf("   (pushing "); +			// print_val(v); +			// printf(")\n");  			break;  		case OP_PRINT: -			printf("print\n"); +			println_val(POP()); +			break; + +#define ARITH_OP(opcode, OP) \ +		case opcode: { \ +			Val b = POP(); \ +			Val a = POP(); \ +			if (!IS_NUM(a) || !IS_NUM(b)) { \ +				printf("can't do arithmetic on %s and %s\n", \ +					valty_str(a.ty), valty_str(b.ty)); \ +				goto done; \ +			} \ +			PUSH(VAL_NUM(AS_NUM(a) OP AS_NUM(b))); \ +			} \  			break; + +			ARITH_OP(OP_ADD, +) +			ARITH_OP(OP_SUB, -) +			ARITH_OP(OP_MUL, *) +			ARITH_OP(OP_DIV, /) +#undef ARITH_OP + +  		}  	}  	done:; @@ -36,6 +36,11 @@ typedef enum {  	OP_RET,  	OP_LOADK,  	OP_PRINT, + +	OP_ADD, +	OP_SUB, +	OP_MUL, +	OP_DIV,  } Op; | 
