summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--com.c19
-rw-r--r--dis.c11
-rw-r--r--state.h1
-rw-r--r--vm.c16
-rw-r--r--vm.h2
5 files changed, 44 insertions, 5 deletions
diff --git a/com.c b/com.c
index b97ffc0..ba45975 100644
--- a/com.c
+++ b/com.c
@@ -9,9 +9,11 @@
static void compile_node(State *S, Chunk *ch, AstNode a) {
switch (a.ty) {
- case AST_IDENT:
- printf("can't compile ident\n");
- exit(1);
+ case AST_IDENT:;
+ size_t len = strlen(a.as.str);
+ ObjString *o = objstring_copy(S, a.as.str, len);
+ chunk_wbc(S, ch, OP_GETGLOBAL);
+ chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_OBJ(o)));
break;
case AST_NUM:
chunk_wbc(S, ch, OP_LOADK);
@@ -67,6 +69,17 @@ int main() {
Chunk ch = chunk_new(S);
th.ch = &ch;
+ char n1[] = "foo";
+ char n2[] = "bar";
+ char n3[] = "baz";
+ ObjString *o1 = objstring_copy(S, n1, 3);
+ ObjString *o2 = objstring_copy(S, n2, 3);
+ ObjString *o3 = objstring_copy(S, n3, 3);
+
+ ht_put(S, &st.globals, o1, VAL_NUM(69));
+ ht_put(S, &st.globals, o2, VAL_NUM(2));
+ ht_put(S, &st.globals, o3, VAL_NUM(3));
+
AstNode an = read();
compile_node(S, &ch, an);
diff --git a/dis.c b/dis.c
index 6ba934d..16c5b0e 100644
--- a/dis.c
+++ b/dis.c
@@ -14,13 +14,22 @@ void disasm_chunk(Chunk *ch) {
case opcode: puts(str); break;
switch (instr) {
SIMPLE_INSTR(OP_RET, "ret")
- case OP_LOADK:;
+ case OP_LOADK: {
uint8_t ix = ch->bc.d[ip++];
printf("loadk #%d\t; ",ix);
Val k = ch->consts.d[ix];
printf("%-4s : ",typename_str(k));
println_val(k);
break;
+ }
+ case OP_GETGLOBAL: {
+ uint8_t ix = ch->bc.d[ip++];
+ printf("getglobal #%d\t; ",ix);
+ Val k = ch->consts.d[ix];
+ printf("%-4s : ",typename_str(k));
+ println_val(k);
+ break;
+ }
SIMPLE_INSTR(OP_PRINT, "print")
SIMPLE_INSTR(OP_ADD, "add")
SIMPLE_INSTR(OP_SUB, "sub")
diff --git a/state.h b/state.h
index 2316d1e..9563376 100644
--- a/state.h
+++ b/state.h
@@ -9,6 +9,7 @@ typedef struct _state State;
struct _state {
Thread *th;
Ht strings;
+ Ht globals;
};
State state_new();
diff --git a/vm.c b/vm.c
index eb041a0..00ba397 100644
--- a/vm.c
+++ b/vm.c
@@ -65,7 +65,7 @@ void runvm(State *S) {
printf("done!\n");
goto done;
break;
- case OP_LOADK:;
+ case OP_LOADK: {
uint8_t cix = RBYTE();
Val v = ch->consts.d[cix];
PUSH(v);
@@ -73,10 +73,24 @@ void runvm(State *S) {
// print_val(v);
// printf(")\n");
break;
+ }
case OP_PRINT:
println_val(POP());
break;
+ case OP_GETGLOBAL: {
+ uint8_t cix = RBYTE();
+ Val varname = ch->consts.d[cix];
+ if (!IS_STRING(varname)) {
+ printf("global names must be string, not %s\n",
+ typename_str(varname));
+ goto done;
+ }
+ Val v = ht_get(S, &S->globals, AS_STRING(varname));
+ PUSH(v);
+ break;
+ }
+
#define ARITH_OP(opcode, OP) \
case opcode: { \
Val b = POP(); \
diff --git a/vm.h b/vm.h
index 4400564..bce1923 100644
--- a/vm.h
+++ b/vm.h
@@ -44,6 +44,8 @@ typedef enum {
OP_SUB,
OP_MUL,
OP_DIV,
+
+ OP_GETGLOBAL,
} Op;
void runvm(State *S);