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

void l2_token_print(struct l2_token *tok, struct l2_io_writer *w); void l2_token_print(struct l2_token *tok, struct l2_io_writer *w);


struct l2_lexer { struct l2_lexer {
struct l2_token currtok;
struct l2_token toks[4]; struct l2_token toks[4];
int tokidx; int tokidx;
int line; int line;


void l2_lexer_init(struct l2_lexer *lexer, struct l2_io_reader *r); 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_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 #endif

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

#include <stdlib.h> #include <stdlib.h>


static int parse_number(const char *str, double *num) { static int parse_number(const char *str, double *num) {
// TODO: Floats
size_t len = strlen(str); size_t len = strlen(str);
*num = 0; *num = 0;
int power = 1; int power = 1;
} }


void l2_token_free(struct l2_token *tok) { 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); free(tok->v.str);
} }
} }
} }


void l2_lexer_init(struct l2_lexer *lexer, struct l2_io_reader *r) { 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->tokidx = 0;
lexer->line = 1; lexer->line = 1;
lexer->ch = 1; lexer->ch = 1;
return &lexer->toks[offset]; 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



if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_COLON_EQ) { if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_COLON_EQ) {
char *ident = l2_token_extract_str(tok); 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) { if (parse_expression(lexer, gen, err) < 0) {
free(ident); free(ident);
return 0; return 0;
} else if (tok->kind == L2_TOK_NUMBER) { } else if (tok->kind == L2_TOK_NUMBER) {
l2_gen_number(gen, tok->v.num); l2_gen_number(gen, tok->v.num);
l2_lexer_get(lexer); // number
l2_lexer_consume(lexer); // number
return 0; return 0;
} else if (tok->kind == L2_TOK_IDENT) { } else if (tok->kind == L2_TOK_IDENT) {
char *ident = l2_token_extract_str(tok); char *ident = l2_token_extract_str(tok);
l2_lexer_get(lexer); // ident
l2_lexer_consume(lexer); // ident
l2_gen_namespace_lookup(gen, &ident); l2_gen_namespace_lookup(gen, &ident);
return 0; return 0;
} }

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

return &vm.values[id]; return &vm.values[id];
} }


static int exec(const char *str) {
static int eval(const char *str) {
r.r.read = l2_io_mem_read; r.r.read = l2_io_mem_read;
r.idx = 0; r.idx = 0;
r.len = strlen(str); r.len = strlen(str);
return 0; 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_vm_free(&vm));
defer(l2_gen_free(&gen)); defer(l2_gen_free(&gen));


assert(l2_vm_value_type(var_lookup("foo")) == L2_VAL_TYPE_REAL); assert(l2_vm_value_type(var_lookup("foo")) == L2_VAL_TYPE_REAL);
assert(var_lookup("foo")->real == 10); 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

#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