summaryrefslogtreecommitdiff
path: root/vm.c
blob: 00692b05e993288d7e64f51299f4c309c7bc3c7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>

#include "val.h"
#include "vm.h"

void *M(void *p, size_t sz) {
	if (sz == 0) {
		free(p);
		return NULL;
	} else {
		return realloc(p, sz);
	}
}


Chunk chunk_new() {
	return (Chunk){
		.blen = 0, .bcap = 0, .b = NULL,
		.clen = 0, .ccap = 0, .c = NULL,
	};
}
size_t chunk_wbc(Chunk *ch, uint8_t byte) {
	if (ch->blen == ch->bcap) {
		size_t newsz = (ch->bcap == 0 ? 8 : ch->bcap * 2);
		ch->b = M(ch->b, newsz * sizeof(uint8_t));
		ch->bcap = newsz;
	}
	size_t ix = ch->blen;
	ch->b[ix] = byte;
	ch->blen ++;
	return ix;
}
size_t chunk_wconst(Chunk *ch, Val v) {
	if (ch->clen == ch->ccap) {
		size_t newsz = (ch->ccap == 0 ? 8 : ch->ccap *2);
		ch->c = M(ch->c, newsz * sizeof(Val));
		ch->ccap = newsz;
	}
	size_t ix = ch->clen;
	ch->c[ix] = v;
	ch->clen ++;
	return ix;
}

Vm vm_new(Chunk *ch) {
	Vm vm = (Vm){ 
		.ch = ch,
		.ip = 0,
		.sp = 0
	};
	for (int i = 0; i < STACKSIZE; i++) {
		vm.stack[i] = VAL_NIL;
	}
	return vm;
}


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, OP_LOADK);
	chunk_wbc(&ch, 0);
	chunk_wbc(&ch, OP_RET);

	chunk_wconst(&ch, VAL_BOOL(false));
	chunk_wconst(&ch, VAL_NIL);
	chunk_wconst(&ch, VAL_NUM(420.69));

	Vm vm = vm_new(&ch);
#define RBYTE() (vm.ch->b[vm.ip++])

	while (1) {
		uint8_t instr = RBYTE();
		switch (instr) {
		case OP_RET:
			printf("done!\n");
			goto done;
			break;
		case OP_LOADK:
			uint8_t cix = RBYTE();
			Val v = vm.ch->c[cix];
			print_val(v);
			break;
		case OP_PRINT:
			printf("print\n");
			break;
		}
	}
	done:;
}

int main() { runvm(); }