summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/vm.c b/vm.c
index 00692b0..72f69fa 100644
--- a/vm.c
+++ b/vm.c
@@ -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:;