Browse Source

check errors

master
Martin Dørum 3 years ago
parent
commit
47e2a5e981
10 changed files with 57 additions and 23 deletions
  1. 1
    1
      cmd/main.c
  2. 2
    2
      include/lang2/bytecode.h
  3. 2
    2
      include/lang2/gen/gen.h
  4. 4
    0
      include/lang2/vm/vm.h
  5. 4
    4
      lib/gen/gen.c
  6. 5
    5
      lib/parse/parse.c
  7. 1
    1
      lib/vm/builtins.c
  8. 4
    4
      lib/vm/print.c
  9. 33
    3
      lib/vm/vm.c
  10. 1
    1
      test/src/examples.t.c

+ 1
- 1
cmd/main.c View File

@@ -13,7 +13,7 @@ void step_through(struct l2_vm *vm) {
l2_vm_print_state(vm);

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

+ 2
- 2
include/lang2/bytecode.h View File

@@ -15,7 +15,7 @@ enum l2_opcode {
* Discard the top element from the stack.
* Pop <word>
*/
L2_OP_POP,
L2_OP_DISCARD,

/*
* Swap the top and second-top elements, then pop the new top element.
@@ -23,7 +23,7 @@ enum l2_opcode {
* Pop <word2>
* Push <word1>
*/
L2_OP_SWAP_POP,
L2_OP_SWAP_DISCARD,

/*
* Duplicate the top element on the stack.

+ 2
- 2
include/lang2/gen/gen.h View File

@@ -24,8 +24,8 @@ void l2_gen_free(struct l2_generator *gen);

void l2_gen_halt(struct l2_generator *gen);
void l2_gen_rjmp(struct l2_generator *gen, l2_word len);
void l2_gen_pop(struct l2_generator *gen);
void l2_gen_swap_pop(struct l2_generator *gen);
void l2_gen_discard(struct l2_generator *gen);
void l2_gen_swap_discard(struct l2_generator *gen);
void l2_gen_ret(struct l2_generator *gen);
void l2_gen_none(struct l2_generator *gen);
void l2_gen_number(struct l2_generator *gen, double num);

+ 4
- 0
include/lang2/vm/vm.h View File

@@ -23,6 +23,8 @@ enum l2_value_type {
L2_VAL_TYPE_ERROR,
};

const char *l2_value_type_name(enum l2_value_type typ);

enum l2_value_flags {
L2_VAL_MARKED = 1 << 6,
L2_VAL_CONST = 1 << 7,
@@ -88,6 +90,7 @@ void l2_vm_namespace_set(struct l2_vm_value *ns, l2_word key, l2_word val);
int l2_vm_namespace_replace(struct l2_vm *vm, struct l2_vm_value *ns, l2_word key, l2_word val);

struct l2_vm {
int halted;
l2_word *ops;
size_t opcount;
l2_word iptr;
@@ -109,6 +112,7 @@ struct l2_vm {
void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount);
l2_word l2_vm_alloc(struct l2_vm *vm, enum l2_value_type typ, enum l2_value_flags flags);
l2_word l2_vm_error(struct l2_vm *vm, const char *fmt, ...);
l2_word l2_vm_type_error(struct l2_vm *vm, struct l2_vm_value *val);
void l2_vm_free(struct l2_vm *vm);
void l2_vm_step(struct l2_vm *vm);
void l2_vm_run(struct l2_vm *vm);

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

@@ -40,12 +40,12 @@ void l2_gen_rjmp(struct l2_generator *gen, l2_word len) {
put(gen, len);
}

void l2_gen_pop(struct l2_generator *gen) {
put(gen, L2_OP_POP);
void l2_gen_discard(struct l2_generator *gen) {
put(gen, L2_OP_DISCARD);
}

void l2_gen_swap_pop(struct l2_generator *gen) {
put(gen, L2_OP_SWAP_POP);
void l2_gen_swap_discard(struct l2_generator *gen) {
put(gen, L2_OP_SWAP_DISCARD);
}

void l2_gen_ret(struct l2_generator *gen) {

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

@@ -52,7 +52,7 @@ static int parse_object_literal(
}

l2_gen_namespace_set(gen, &key);
l2_gen_pop(gen);
l2_gen_discard(gen);

tok = l2_lexer_peek(lexer, 1);
if (tok->kind != L2_TOK_EOL && tok->kind != L2_TOK_CLOSE_BRACE) {
@@ -87,7 +87,7 @@ static int parse_function_literal_impl(
}

if (!first) {
l2_gen_pop(gen);
l2_gen_discard(gen);
}

l2_trace_scope("function literal expression");
@@ -300,7 +300,7 @@ static int parse_arg_level_expression(
}

l2_gen_namespace_set(gen, &ident);
l2_gen_swap_pop(gen);
l2_gen_swap_discard(gen);
} else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) {
l2_trace_scope("namespace lookup");
l2_trace("ident '%s'", tok2->v.str);
@@ -320,7 +320,7 @@ static int parse_arg_level_expression(
}

l2_gen_array_set(gen, number);
l2_gen_swap_pop(gen);
l2_gen_swap_discard(gen);
} else if (tok->kind == L2_TOK_DOT_NUMBER) {
l2_trace_scope("direct array lookup");
int number = tok->v.integer;
@@ -441,7 +441,7 @@ int l2_parse_program(
return -1;
}

l2_gen_pop(gen);
l2_gen_discard(gen);
}

l2_gen_halt(gen);

+ 1
- 1
lib/vm/builtins.c View File

@@ -59,7 +59,7 @@ l2_word l2_builtin_add(struct l2_vm *vm, struct l2_vm_array *args) {
for (size_t i = 0; i < args->len; ++i) {
struct l2_vm_value *val = &vm->values[args->data[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
// TODO: Error
return l2_vm_type_error(vm, val);
}

sum += val->real;

+ 4
- 4
lib/vm/print.c View File

@@ -118,12 +118,12 @@ void l2_vm_print_op(l2_word *ops, size_t opcount, size_t *ptr) {
printf("NOP\n");
return;

case L2_OP_POP:
printf("POP\n");
case L2_OP_DISCARD:
printf("DISCARD\n");
return;

case L2_OP_SWAP_POP:
printf("SWAP_POP\n");
case L2_OP_SWAP_DISCARD:
printf("SWAP_DISCARD\n");
return;

case L2_OP_DUP:

+ 33
- 3
lib/vm/vm.c View File

@@ -121,6 +121,22 @@ static size_t gc_sweep(struct l2_vm *vm) {
return freed;
}

const char *l2_value_type_name(enum l2_value_type typ) {
switch (typ) {
case L2_VAL_TYPE_NONE: return "NONE";
case L2_VAL_TYPE_ATOM: return "ATOM";
case L2_VAL_TYPE_REAL: return "REAL";
case L2_VAL_TYPE_BUFFER: return "BUFFER";
case L2_VAL_TYPE_ARRAY: return "ARRAY";
case L2_VAL_TYPE_NAMESPACE: return "NAMESPACE";
case L2_VAL_TYPE_FUNCTION: return "FUNCTION";
case L2_VAL_TYPE_CFUNCTION: return "CFUNCTION";
case L2_VAL_TYPE_ERROR: return "ERROR";
}

return "(unknown)";
}

void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount) {
if (!stdio_inited) {
std_output.w.write = l2_io_file_write;
@@ -133,6 +149,7 @@ void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount) {
vm->std_output = &std_output.w;
vm->std_error = &std_error.w;

vm->halted = 0;
vm->ops = ops;
vm->opcount = opcount;
vm->iptr = 0;
@@ -215,6 +232,10 @@ l2_word l2_vm_error(struct l2_vm *vm, const char *fmt, ...) {
return id;
}

l2_word l2_vm_type_error(struct l2_vm *vm, struct l2_vm_value *val) {
return l2_vm_error(vm, "Unexpected type %s", l2_value_type_name(l2_vm_value_type(val)));
}

void l2_vm_free(struct l2_vm *vm) {
// Skip ID 0, because that's always NONE
for (size_t i = 1; i < vm->valuessize; ++i) {
@@ -242,7 +263,7 @@ size_t l2_vm_gc(struct l2_vm *vm) {
}

void l2_vm_run(struct l2_vm *vm) {
while ((enum l2_opcode)vm->ops[vm->iptr] != L2_OP_HALT) {
while (!vm->halted) {
l2_vm_step(vm);
}
}
@@ -255,13 +276,21 @@ void l2_vm_step(struct l2_vm *vm) {
case L2_OP_NOP:
break;

case L2_OP_POP:
case L2_OP_DISCARD:
vm->sptr -= 1;
if (l2_vm_value_type(&vm->values[vm->stack[vm->sptr]]) == L2_VAL_TYPE_ERROR) {
l2_io_printf(vm->std_error, "Error: %s\n", vm->values[vm->stack[vm->sptr]].error);
vm->halted = 1;
}
break;

case L2_OP_SWAP_POP:
case L2_OP_SWAP_DISCARD:
vm->stack[vm->sptr - 2] = vm->stack[vm->sptr - 1];
vm->sptr -= 1;
if (l2_vm_value_type(&vm->values[vm->stack[vm->sptr]]) == L2_VAL_TYPE_ERROR) {
l2_io_printf(vm->std_error, "Error: %s\n", vm->values[vm->stack[vm->sptr]].error);
vm->halted = 1;
}
break;

case L2_OP_DUP:
@@ -533,6 +562,7 @@ void l2_vm_step(struct l2_vm *vm) {
break;

case L2_OP_HALT:
vm->halted = 1;
break;
}
}

+ 1
- 1
test/src/examples.t.c View File

@@ -111,7 +111,7 @@ static void check_impl(const char *name) {
vm.std_output = &output.w;

// Run a GC after every instruction to uncover potential GC issues
while (vm.ops[vm.iptr] != L2_OP_HALT) {
while (!vm->halted) {
l2_vm_step(&vm);
l2_vm_gc(&vm);
}

Loading…
Cancel
Save