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

l2_vm_print_state(vm); l2_vm_print_state(vm);


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

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

* Discard the top element from the stack. * Discard the top element from the stack.
* Pop <word> * Pop <word>
*/ */
L2_OP_POP,
L2_OP_DISCARD,


/* /*
* Swap the top and second-top elements, then pop the new top element. * Swap the top and second-top elements, then pop the new top element.
* Pop <word2> * Pop <word2>
* Push <word1> * Push <word1>
*/ */
L2_OP_SWAP_POP,
L2_OP_SWAP_DISCARD,


/* /*
* Duplicate the top element on the stack. * Duplicate the top element on the stack.

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



void l2_gen_halt(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_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_ret(struct l2_generator *gen);
void l2_gen_none(struct l2_generator *gen); void l2_gen_none(struct l2_generator *gen);
void l2_gen_number(struct l2_generator *gen, double num); void l2_gen_number(struct l2_generator *gen, double num);

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

L2_VAL_TYPE_ERROR, L2_VAL_TYPE_ERROR,
}; };


const char *l2_value_type_name(enum l2_value_type typ);

enum l2_value_flags { enum l2_value_flags {
L2_VAL_MARKED = 1 << 6, L2_VAL_MARKED = 1 << 6,
L2_VAL_CONST = 1 << 7, L2_VAL_CONST = 1 << 7,
int l2_vm_namespace_replace(struct l2_vm *vm, 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 { struct l2_vm {
int halted;
l2_word *ops; l2_word *ops;
size_t opcount; size_t opcount;
l2_word iptr; l2_word iptr;
void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount); 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_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_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_free(struct l2_vm *vm);
void l2_vm_step(struct l2_vm *vm); void l2_vm_step(struct l2_vm *vm);
void l2_vm_run(struct l2_vm *vm); void l2_vm_run(struct l2_vm *vm);

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

put(gen, 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) { void l2_gen_ret(struct l2_generator *gen) {

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

} }


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


tok = l2_lexer_peek(lexer, 1); tok = l2_lexer_peek(lexer, 1);
if (tok->kind != L2_TOK_EOL && tok->kind != L2_TOK_CLOSE_BRACE) { if (tok->kind != L2_TOK_EOL && tok->kind != L2_TOK_CLOSE_BRACE) {
} }


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


l2_trace_scope("function literal expression"); l2_trace_scope("function literal expression");
} }


l2_gen_namespace_set(gen, &ident); 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) { } else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) {
l2_trace_scope("namespace lookup"); l2_trace_scope("namespace lookup");
l2_trace("ident '%s'", tok2->v.str); l2_trace("ident '%s'", tok2->v.str);
} }


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


l2_gen_pop(gen);
l2_gen_discard(gen);
} }


l2_gen_halt(gen); l2_gen_halt(gen);

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

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


sum += val->real; sum += val->real;

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

printf("NOP\n"); printf("NOP\n");
return; return;


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


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


case L2_OP_DUP: case L2_OP_DUP:

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

return freed; 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) { void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount) {
if (!stdio_inited) { if (!stdio_inited) {
std_output.w.write = l2_io_file_write; std_output.w.write = l2_io_file_write;
vm->std_output = &std_output.w; vm->std_output = &std_output.w;
vm->std_error = &std_error.w; vm->std_error = &std_error.w;


vm->halted = 0;
vm->ops = ops; vm->ops = ops;
vm->opcount = opcount; vm->opcount = opcount;
vm->iptr = 0; vm->iptr = 0;
return id; 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) { void l2_vm_free(struct l2_vm *vm) {
// Skip ID 0, because that's always NONE // Skip ID 0, because that's always NONE
for (size_t i = 1; i < vm->valuessize; ++i) { for (size_t i = 1; i < vm->valuessize; ++i) {
} }


void l2_vm_run(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); l2_vm_step(vm);
} }
} }
case L2_OP_NOP: case L2_OP_NOP:
break; break;


case L2_OP_POP:
case L2_OP_DISCARD:
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; break;


case L2_OP_SWAP_POP:
case L2_OP_SWAP_DISCARD:
vm->stack[vm->sptr - 2] = vm->stack[vm->sptr - 1]; vm->stack[vm->sptr - 2] = vm->stack[vm->sptr - 1];
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; break;


case L2_OP_DUP: case L2_OP_DUP:
break; break;


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

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

vm.std_output = &output.w; vm.std_output = &output.w;


// Run a GC after every instruction to uncover potential GC issues // 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_step(&vm);
l2_vm_gc(&vm); l2_vm_gc(&vm);
} }

Loading…
Cancel
Save