Browse Source

syntax stuff

master
Martin Dørum 3 years ago
parent
commit
fbfafb7013
3 changed files with 58 additions and 5 deletions
  1. 23
    1
      cmd/main.c
  2. 10
    1
      lib/parse/lex.c
  3. 25
    3
      lib/parse/parse.c

+ 23
- 1
cmd/main.c View File

@@ -8,6 +8,21 @@
#include <stdio.h>
#include <string.h>

void step_through(struct l2_vm *vm) {
printf("=====\n\nInitial state:\n");
l2_vm_print_state(vm);

char buf[16];
while ((enum l2_opcode)vm->ops[vm->iptr] != L2_OP_HALT) {
size_t iptr = vm->iptr;
printf("\n======\n\n(%d) Will run instr: ", vm->iptr);
l2_vm_print_op(vm->ops, vm->opcount, &iptr);
fgets(buf, sizeof(buf), stdin);
l2_vm_step(vm);
l2_vm_print_state(vm);
}
}

int main(int argc, char **argv) {
if (argc != 1 && argc != 2) {
fprintf(stderr, "Usage: %s [file]\n", argv[0]);
@@ -52,10 +67,17 @@ int main(int argc, char **argv) {

struct l2_vm vm;
l2_vm_init(&vm, (void *)w.mem, w.len / sizeof(l2_word));
l2_vm_run(&vm);

step_through(&vm);
free(w.mem);

printf("State after executing:\n");
l2_vm_print_state(&vm);

while (l2_vm_gc(&vm));

printf("State after GC:\n");
l2_vm_print_state(&vm);

l2_vm_free(&vm);
}

+ 10
- 1
lib/parse/lex.c View File

@@ -39,7 +39,7 @@ const char *l2_token_kind_name(enum l2_token_kind kind) {
case L2_TOK_PERIOD:
return "period";
case L2_TOK_COLON_EQ:
return "period";
return "colon-equals";
case L2_TOK_EOL:
return "end-of-line";
case L2_TOK_EOF:
@@ -202,6 +202,7 @@ static void read_ident(struct l2_lexer *lexer, struct l2_token *tok) {
case ',':
case '.':
case ':':
case ';':
case EOF:
tok->v.str[idx] = '\0';
return;
@@ -267,6 +268,14 @@ static void read_tok(struct l2_lexer *lexer, struct l2_token *tok) {
tok->kind = L2_TOK_CLOSE_BRACKET;
break;

case ';':
tok->kind = L2_TOK_EOL;
do {
read_ch(lexer);
skip_whitespace(lexer);
} while (peek_ch(lexer) == ';');
break;

case ',':
read_ch(lexer);
tok->kind = L2_TOK_COMMA;

+ 25
- 3
lib/parse/parse.c View File

@@ -17,6 +17,7 @@ static int parse_function_impl(
l2_lexer_consume(lexer); // {
l2_lexer_skip_opt(lexer, L2_TOK_EOL);

int first = 1;
while (1) {
struct l2_token *tok = l2_lexer_peek(lexer, 1);
if (tok->kind == L2_TOK_EOF) {
@@ -27,11 +28,17 @@ static int parse_function_impl(
break;
}

// The previous expr left a value on the stack which we have to pop
if (!first) {
l2_gen_pop(gen);
}

if (parse_expression(lexer, gen, err) < 0) {
return -1;
}

l2_lexer_skip_opt(lexer, L2_TOK_EOL);
first = 0;
}

l2_gen_ret(gen);
@@ -84,11 +91,26 @@ static int parse_sub_expression(

if (tok->kind == L2_TOK_OPEN_PAREN) {
l2_lexer_consume(lexer); // (
tok = l2_lexer_peek(lexer, 1);

// Special case: (foo) should be interpreted as a function call
if (
tok->kind == L2_TOK_IDENT &&
l2_lexer_peek(lexer, 2)->kind == L2_TOK_CLOSE_PAREN) {
char *ident = l2_token_extract_str(tok);
l2_lexer_consume(lexer); // ident
l2_lexer_consume(lexer); // )

l2_gen_push(gen, 0); // Arg count
l2_gen_namespace_lookup(gen, &ident);
l2_gen_func_call(gen);
return 0;
}

if (parse_expression(lexer, gen, err) < 0) {
return -1;
}

tok = l2_lexer_peek(lexer, 1);
if (tok->kind != L2_TOK_CLOSE_PAREN) {
l2_parse_err(err, tok, "In paren expression: Expected close paren, got %s",
l2_token_kind_name(tok->kind));
@@ -160,8 +182,9 @@ static int parse_expression(

int l2_parse_program(
struct l2_lexer *lexer, struct l2_generator *gen, struct l2_parse_error *err) {
int first = 1;
l2_lexer_skip_opt(lexer, L2_TOK_EOL);

int first = 1;
while (1) {
struct l2_token *tok = l2_lexer_peek(lexer, 1);
if (tok->kind == L2_TOK_EOF) {
@@ -180,7 +203,6 @@ int l2_parse_program(
}

l2_lexer_skip_opt(lexer, L2_TOK_EOL);

first = 0;
}


Loading…
Cancel
Save