Browse Source

fix stuff

master
Martin Dørum 3 years ago
parent
commit
840ef19b35
5 changed files with 105 additions and 23 deletions
  1. 1
    2
      include/lang2/parse/lex.h
  2. 7
    13
      lib/parse/lex.c
  3. 4
    4
      lib/parse/parse.c
  4. 12
    4
      test/src/eval.t.c
  5. 81
    0
      test/src/lex.t.c

+ 1
- 2
include/lang2/parse/lex.h View File

@@ -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

+ 7
- 13
lib/parse/lex.c View File

@@ -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));
}

+ 4
- 4
lib/parse/parse.c View File

@@ -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;
}

+ 12
- 4
test/src/eval.t.c View File

@@ -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);
}
}

+ 81
- 0
test/src/lex.t.c View File

@@ -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);
}
}

Loading…
Cancel
Save