Browse Source

add error type

master
Martin Dørum 3 years ago
parent
commit
2af11e76a4
4 changed files with 46 additions and 1 deletions
  1. 3
    0
      include/lang2/vm/vm.h
  2. 5
    0
      lib/vm/builtins.c
  3. 4
    0
      lib/vm/print.c
  4. 34
    1
      lib/vm/vm.c

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

@@ -20,6 +20,7 @@ enum l2_value_type {
L2_VAL_TYPE_NAMESPACE,
L2_VAL_TYPE_FUNCTION,
L2_VAL_TYPE_CFUNCTION,
L2_VAL_TYPE_ERROR,
};

enum l2_value_flags {
@@ -52,6 +53,7 @@ struct l2_vm_value {
l2_word ns;
} func;
l2_vm_cfunction cfunc;
char *error;
};
};

@@ -106,6 +108,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, ...);
void l2_vm_free(struct l2_vm *vm);
void l2_vm_step(struct l2_vm *vm);
void l2_vm_run(struct l2_vm *vm);

+ 5
- 0
lib/vm/builtins.c View File

@@ -47,6 +47,10 @@ static void print_val(struct l2_vm *vm, struct l2_io_writer *out, struct l2_vm_v
case L2_VAL_TYPE_CFUNCTION:
l2_io_printf(out, "(function)");
break;

case L2_VAL_TYPE_ERROR:
l2_io_printf(out, "(error: %s)", val->error);
break;
}
}

@@ -105,6 +109,7 @@ l2_word l2_builtin_len(struct l2_vm *vm, struct l2_vm_array *args) {
case L2_VAL_TYPE_REAL:
case L2_VAL_TYPE_FUNCTION:
case L2_VAL_TYPE_CFUNCTION:
case L2_VAL_TYPE_ERROR:
break;

case L2_VAL_TYPE_BUFFER:

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

@@ -72,6 +72,10 @@ void l2_vm_print_val(struct l2_vm_value *val) {
// ISO C doesn't let you cast a function pointer to void*.
printf("C FUNCTION, %jx\n", (uintmax_t)val->cfunc);
break;

case L2_VAL_TYPE_ERROR:
printf("ERROR, %s\n", val->error);
break;
}
}


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

@@ -2,6 +2,7 @@

#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#include "vm/builtins.h"

@@ -96,6 +97,8 @@ static void gc_free(struct l2_vm *vm, l2_word id) {
free(val->buffer);
} else if (typ == L2_VAL_TYPE_NAMESPACE) {
free(val->ns);
} else if (typ == L2_VAL_TYPE_ERROR) {
free(val->error);
}
}

@@ -182,6 +185,36 @@ l2_word l2_vm_alloc(struct l2_vm *vm, enum l2_value_type typ, enum l2_value_flag
return id;
}

l2_word l2_vm_error(struct l2_vm *vm, const char *fmt, ...) {
l2_word id = alloc_val(vm);
struct l2_vm_value *val = &vm->values[id];
val->flags = L2_VAL_CONST | L2_VAL_TYPE_ERROR;

char buf[256];

va_list va;
va_start(va, fmt);
int n = vsnprintf(buf, sizeof(buf), fmt, va);

if (n < 0) {
const char *message = "Failed to generate error message!";
val->error = malloc(strlen(message) + 1);
strcpy(val->error, message);
va_end(va);
return id;
} else if ((size_t)n + 1 < sizeof(buf)) {
val->error = malloc(n + 1);
strcpy(val->error, buf);
va_end(va);
return id;
}

val->error = malloc(n + 1);
vsnprintf(val->error, n + 1, fmt, va);
va_end(va);
return id;
}

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) {
@@ -273,7 +306,7 @@ void l2_vm_step(struct l2_vm *vm) {

// Don't interpret a non-function as a function
if (typ != L2_VAL_TYPE_FUNCTION) {
// TODO: Error mechanism
vm->stack[vm->sptr++] = l2_vm_error(vm, "Attempt to call non-function");
break;
}


Loading…
Cancel
Save