@@ -38,7 +38,6 @@ char *l2_token_extract_str(struct l2_token *tok); | |||
void l2_token_print(struct l2_token *tok, struct l2_io_writer *w); | |||
struct l2_lexer { | |||
struct l2_token currtok; | |||
struct l2_token toks[4]; | |||
int tokidx; | |||
int line; | |||
@@ -49,6 +48,6 @@ struct l2_lexer { | |||
void l2_lexer_init(struct l2_lexer *lexer, struct l2_io_reader *r); | |||
struct l2_token *l2_lexer_peek(struct l2_lexer *lexer, int count); | |||
struct l2_token *l2_lexer_get(struct l2_lexer *lexer); | |||
void l2_lexer_consume(struct l2_lexer *lexer); | |||
#endif |
@@ -3,6 +3,7 @@ | |||
#include <stdlib.h> | |||
static int parse_number(const char *str, double *num) { | |||
// TODO: Floats | |||
size_t len = strlen(str); | |||
*num = 0; | |||
int power = 1; | |||
@@ -53,7 +54,7 @@ const char *l2_token_kind_name(enum l2_token_kind kind) { | |||
} | |||
void l2_token_free(struct l2_token *tok) { | |||
if (tok->kind == L2_TOK_STRING) { | |||
if (tok->kind == L2_TOK_STRING || tok->kind == L2_TOK_IDENT) { | |||
free(tok->v.str); | |||
} | |||
} | |||
@@ -65,7 +66,7 @@ char *l2_token_extract_str(struct l2_token *tok) { | |||
} | |||
void l2_lexer_init(struct l2_lexer *lexer, struct l2_io_reader *r) { | |||
lexer->currtok.kind = L2_TOK_EOF, | |||
lexer->toks[0].kind = L2_TOK_EOF, | |||
lexer->tokidx = 0; | |||
lexer->line = 1; | |||
lexer->ch = 1; | |||
@@ -311,15 +312,8 @@ struct l2_token *l2_lexer_peek(struct l2_lexer *lexer, int count) { | |||
return &lexer->toks[offset]; | |||
} | |||
struct l2_token *l2_lexer_get(struct l2_lexer *lexer) { | |||
l2_token_free(&lexer->currtok); | |||
if (lexer->tokidx == 0) { | |||
read_tok(lexer, &lexer->currtok); | |||
} else { | |||
memmove(lexer->toks, lexer->toks + 1, lexer->tokidx - 1); | |||
lexer->tokidx -= 1; | |||
} | |||
return &lexer->currtok; | |||
void l2_lexer_consume(struct l2_lexer *lexer) { | |||
l2_token_free(&lexer->toks[0]); | |||
lexer->tokidx -= 1; | |||
memmove(lexer->toks, lexer->toks + 1, lexer->tokidx * sizeof(*lexer->toks)); | |||
} |
@@ -9,8 +9,8 @@ static int parse_expression( | |||
if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_COLON_EQ) { | |||
char *ident = l2_token_extract_str(tok); | |||
l2_lexer_get(lexer); // ident | |||
l2_lexer_get(lexer); // := | |||
l2_lexer_consume(lexer); // ident | |||
l2_lexer_consume(lexer); // := | |||
if (parse_expression(lexer, gen, err) < 0) { | |||
free(ident); | |||
@@ -21,11 +21,11 @@ static int parse_expression( | |||
return 0; | |||
} else if (tok->kind == L2_TOK_NUMBER) { | |||
l2_gen_number(gen, tok->v.num); | |||
l2_lexer_get(lexer); // number | |||
l2_lexer_consume(lexer); // number | |||
return 0; | |||
} else if (tok->kind == L2_TOK_IDENT) { | |||
char *ident = l2_token_extract_str(tok); | |||
l2_lexer_get(lexer); // ident | |||
l2_lexer_consume(lexer); // ident | |||
l2_gen_namespace_lookup(gen, &ident); | |||
return 0; | |||
} |
@@ -18,7 +18,7 @@ static struct l2_vm_value *var_lookup(const char *name) { | |||
return &vm.values[id]; | |||
} | |||
static int exec(const char *str) { | |||
static int eval(const char *str) { | |||
r.r.read = l2_io_mem_read; | |||
r.idx = 0; | |||
r.len = strlen(str); | |||
@@ -42,13 +42,21 @@ static int exec(const char *str) { | |||
return 0; | |||
} | |||
describe(exec) { | |||
test("exec assignment") { | |||
exec("foo := 10"); | |||
describe(eval) { | |||
test("eval assignment") { | |||
eval("foo := 10"); | |||
defer(l2_vm_free(&vm)); | |||
defer(l2_gen_free(&gen)); | |||
assert(l2_vm_value_type(var_lookup("foo")) == L2_VAL_TYPE_REAL); | |||
assert(var_lookup("foo")->real == 10); | |||
} | |||
test("eval var deref assignment") { | |||
eval("foo := 10\nbar := foo"); | |||
defer(l2_vm_free(&vm)); | |||
defer(l2_gen_free(&gen)); | |||
l2_vm_print_state(&vm); | |||
} | |||
} |
@@ -0,0 +1,81 @@ | |||
#include "parse/lex.h" | |||
#include <stdio.h> | |||
#include <snow/snow.h> | |||
static struct l2_lexer lexer; | |||
static struct l2_io_mem_reader r; | |||
static void lex(const char *str) { | |||
r.r.read = l2_io_mem_read; | |||
r.idx = 0; | |||
r.len = strlen(str); | |||
r.mem = str; | |||
l2_lexer_init(&lexer, &r.r); | |||
} | |||
describe(lex) { | |||
test("lex assignment") { | |||
lex("foo := 10"); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_IDENT); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.str, "foo"); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_COLON_EQ); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_NUMBER); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.num, 10); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_EOF); | |||
} | |||
test("lex var deref assignment") { | |||
lex("foo := 10\nbar := foo"); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_IDENT); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.str, "foo"); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_COLON_EQ); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_NUMBER); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.num, 10); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_IDENT); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.str, "bar"); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_COLON_EQ); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_IDENT); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.str, "foo"); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_EOF); | |||
} | |||
test("lex peek multiple") { | |||
lex("foo := 10"); | |||
l2_lexer_peek(&lexer, 3); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_IDENT); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.str, "foo"); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_COLON_EQ); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_NUMBER); | |||
asserteq(l2_lexer_peek(&lexer, 1)->v.num, 10); | |||
l2_lexer_consume(&lexer); | |||
asserteq(l2_lexer_peek(&lexer, 1)->kind, L2_TOK_EOF); | |||
} | |||
} |