@@ -17,6 +17,13 @@ enum l2_opcode { | |||
*/ | |||
L2_OP_PUSH, | |||
/* | |||
* Push a value to the stack. | |||
* Push <word1> | |||
* Push <word2> | |||
*/ | |||
L2_OP_PUSH_2, | |||
/* | |||
* Discard the top element from the stack. | |||
* Pop <word> |
@@ -14,5 +14,6 @@ void l2_gen_init(struct l2_generator *gen); | |||
void l2_gen_free(struct l2_generator *gen); | |||
void l2_gen_stack_frame(struct l2_generator *gen); | |||
void l2_gen_assignment(struct l2_generator *gen, char **ident); | |||
void l2_gen_number(struct l2_generator *gen, double num); | |||
#endif |
@@ -4,6 +4,6 @@ | |||
#include "lex.h" | |||
#include "gen/gen.h" | |||
void l2_parse_program(struct l2_lexer *lexer, struct l2_generator *gen); | |||
int l2_parse_program(struct l2_lexer *lexer, struct l2_generator *gen); | |||
#endif |
@@ -26,3 +26,12 @@ void l2_gen_assignment(struct l2_generator *gen, char **ident) { | |||
put(gen, atom_id); | |||
put(gen, L2_OP_NAMESPACE_SET); | |||
} | |||
void l2_gen_number(struct l2_generator *gen, double num) { | |||
uint64_t n; | |||
memcpy(&n, &num, sizeof(num)); | |||
put(gen, L2_OP_PUSH_2); | |||
put(gen, n >> 32); | |||
put(gen, n); | |||
put(gen, L2_OP_ALLOC_REAL_64); | |||
} |
@@ -2,17 +2,23 @@ | |||
#include "gen/gen.h" | |||
static void parse_expression(struct l2_lexer *lexer, struct l2_generator *gen) { | |||
static int parse_expression(struct l2_lexer *lexer, struct l2_generator *gen) { | |||
struct l2_token *tok = l2_lexer_peek(lexer, 1); | |||
struct l2_token *tok2 = l2_lexer_peek(lexer, 2); | |||
if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_COLON_EQ) { | |||
parse_expression(lexer, gen); | |||
l2_gen_assignment(gen, &tok->v.str); | |||
return 0; | |||
} else if (tok->kind == L2_TOK_NUMBER) { | |||
l2_gen_number(gen, tok->v.num); | |||
return 0; | |||
} | |||
return -1; | |||
} | |||
void l2_parse_program(struct l2_lexer *lexer, struct l2_generator *gen) { | |||
int l2_parse_program(struct l2_lexer *lexer, struct l2_generator *gen) { | |||
l2_gen_stack_frame(gen); | |||
while (1) { | |||
@@ -21,6 +27,10 @@ void l2_parse_program(struct l2_lexer *lexer, struct l2_generator *gen) { | |||
break; | |||
} | |||
parse_expression(lexer, gen); | |||
if (parse_expression(lexer, gen) < 0) { | |||
return -1; | |||
} | |||
} | |||
return 0; | |||
} |
@@ -159,6 +159,15 @@ void l2_vm_step(struct l2_vm *vm) { | |||
vm->iptr += 1; | |||
break; | |||
case L2_OP_PUSH_2: | |||
vm->stack[vm->sptr] = vm->ops[vm->iptr]; | |||
vm->stack[vm->sptr + 1] = vm->ops[vm->iptr + 1]; | |||
vm->stackflags[vm->sptr] = 0; | |||
vm->stackflags[vm->sptr + 1] = 0; | |||
vm->sptr += 2; | |||
vm->iptr += 2; | |||
break; | |||
case L2_OP_POP: | |||
vm->sptr -= 1; | |||
break; | |||
@@ -255,6 +264,7 @@ void l2_vm_step(struct l2_vm *vm) { | |||
vm->stackflags[vm->sptr] = 1; | |||
vm->sptr += 1; | |||
} | |||
break; | |||
case L2_OP_ALLOC_ARRAY: | |||
word = alloc_val(vm); | |||
@@ -274,6 +284,16 @@ void l2_vm_step(struct l2_vm *vm) { | |||
vm->sptr += 1; | |||
break; | |||
case L2_OP_NAMESPACE_SET: | |||
{ | |||
l2_word key = vm->stack[vm->sptr - 1]; | |||
l2_word val = vm->stack[vm->sptr - 2]; | |||
l2_word ns = vm->stack[vm->sptr - 3]; | |||
l2_vm_namespace_set(&vm->values[ns], key, val); | |||
vm->sptr -= 1; | |||
} | |||
break; | |||
case L2_OP_HALT: | |||
break; | |||
} |