*/ | */ | ||||
L2_OP_PUSH, | L2_OP_PUSH, | ||||
/* | |||||
* Push a value to the stack. | |||||
* Push <word1> | |||||
* Push <word2> | |||||
*/ | |||||
L2_OP_PUSH_2, | |||||
/* | /* | ||||
* Discard the top element from the stack. | * Discard the top element from the stack. | ||||
* Pop <word> | * Pop <word> |
void l2_gen_free(struct l2_generator *gen); | void l2_gen_free(struct l2_generator *gen); | ||||
void l2_gen_stack_frame(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_assignment(struct l2_generator *gen, char **ident); | ||||
void l2_gen_number(struct l2_generator *gen, double num); | |||||
#endif | #endif |
#include "lex.h" | #include "lex.h" | ||||
#include "gen/gen.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 | #endif |
put(gen, atom_id); | put(gen, atom_id); | ||||
put(gen, L2_OP_NAMESPACE_SET); | 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); | |||||
} |
#include "gen/gen.h" | #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 *tok = l2_lexer_peek(lexer, 1); | ||||
struct l2_token *tok2 = l2_lexer_peek(lexer, 2); | struct l2_token *tok2 = l2_lexer_peek(lexer, 2); | ||||
if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_COLON_EQ) { | if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_COLON_EQ) { | ||||
parse_expression(lexer, gen); | parse_expression(lexer, gen); | ||||
l2_gen_assignment(gen, &tok->v.str); | 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); | l2_gen_stack_frame(gen); | ||||
while (1) { | while (1) { | ||||
break; | break; | ||||
} | } | ||||
parse_expression(lexer, gen); | |||||
if (parse_expression(lexer, gen) < 0) { | |||||
return -1; | |||||
} | |||||
} | } | ||||
return 0; | |||||
} | } |
vm->iptr += 1; | vm->iptr += 1; | ||||
break; | 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: | case L2_OP_POP: | ||||
vm->sptr -= 1; | vm->sptr -= 1; | ||||
break; | break; | ||||
vm->stackflags[vm->sptr] = 1; | vm->stackflags[vm->sptr] = 1; | ||||
vm->sptr += 1; | vm->sptr += 1; | ||||
} | } | ||||
break; | |||||
case L2_OP_ALLOC_ARRAY: | case L2_OP_ALLOC_ARRAY: | ||||
word = alloc_val(vm); | word = alloc_val(vm); | ||||
vm->sptr += 1; | vm->sptr += 1; | ||||
break; | 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: | case L2_OP_HALT: | ||||
break; | break; | ||||
} | } |