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

L2_VAL_TYPE_NAMESPACE, L2_VAL_TYPE_NAMESPACE,
L2_VAL_TYPE_FUNCTION, L2_VAL_TYPE_FUNCTION,
L2_VAL_TYPE_CFUNCTION, L2_VAL_TYPE_CFUNCTION,
L2_VAL_TYPE_ERROR,
}; };


enum l2_value_flags { enum l2_value_flags {
l2_word ns; l2_word ns;
} func; } func;
l2_vm_cfunction cfunc; l2_vm_cfunction cfunc;
char *error;
}; };
}; };




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, ...);
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);

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

case L2_VAL_TYPE_CFUNCTION: case L2_VAL_TYPE_CFUNCTION:
l2_io_printf(out, "(function)"); l2_io_printf(out, "(function)");
break; break;

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


case L2_VAL_TYPE_REAL: case L2_VAL_TYPE_REAL:
case L2_VAL_TYPE_FUNCTION: case L2_VAL_TYPE_FUNCTION:
case L2_VAL_TYPE_CFUNCTION: case L2_VAL_TYPE_CFUNCTION:
case L2_VAL_TYPE_ERROR:
break; break;


case L2_VAL_TYPE_BUFFER: case L2_VAL_TYPE_BUFFER:

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

// ISO C doesn't let you cast a function pointer to void*. // ISO C doesn't let you cast a function pointer to void*.
printf("C FUNCTION, %jx\n", (uintmax_t)val->cfunc); printf("C FUNCTION, %jx\n", (uintmax_t)val->cfunc);
break; break;

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



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



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


#include "vm/builtins.h" #include "vm/builtins.h"


free(val->buffer); free(val->buffer);
} else if (typ == L2_VAL_TYPE_NAMESPACE) { } else if (typ == L2_VAL_TYPE_NAMESPACE) {
free(val->ns); free(val->ns);
} else if (typ == L2_VAL_TYPE_ERROR) {
free(val->error);
} }
} }


return id; 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) { 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) {


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



Loading…
Cancel
Save