@@ -1,3 +1,4 @@ | |||
includes := include/lang2 | |||
files := lib cmd | |||
warnings := all extra no-unused-parameter pedantic | |||
cflags := -g |
@@ -1,10 +1,10 @@ | |||
// X macro: Define a macro named X, then include this file, then undef X. | |||
#ifdef X | |||
X("+", l2_builtin_add); | |||
X("-", l2_builtin_sub); | |||
X("*", l2_builtin_mul); | |||
X("/", l2_builtin_div); | |||
X("print", l2_builtin_print); | |||
X("len", l2_builtin_len); | |||
X("+", l2_builtin_add) | |||
X("-", l2_builtin_sub) | |||
X("*", l2_builtin_mul) | |||
X("/", l2_builtin_div) | |||
X("print", l2_builtin_print) | |||
X("len", l2_builtin_len) | |||
#endif |
@@ -12,7 +12,7 @@ int l2_io_printf(struct l2_io_writer *w, const char *fmt, ...) { | |||
if (n < 0) { | |||
va_end(va); | |||
return n; | |||
} else if (n + 1 < sizeof(buf)) { | |||
} else if ((size_t)n + 1 < sizeof(buf)) { | |||
w->write(w, buf, n); | |||
va_end(va); | |||
return n; | |||
@@ -90,7 +90,7 @@ size_t l2_io_mem_read(struct l2_io_reader *self, void *buf, size_t len) { | |||
len = r->len - r->idx; | |||
} | |||
memcpy(buf, r->mem + r->idx, len); | |||
memcpy(buf, (char *)r->mem + r->idx, len); | |||
r->idx += len; | |||
return len; | |||
} |
@@ -21,7 +21,7 @@ void l2_parse_err(struct l2_parse_error *err, struct l2_token *tok, const char * | |||
va_end(va); | |||
l2_trace("Parse error: %s", err->message); | |||
return; | |||
} else if (n + 1 < sizeof(buf)) { | |||
} else if ((size_t)n + 1 < sizeof(buf)) { | |||
err->message = malloc(n + 1); | |||
strcpy(err->message, buf); | |||
va_end(va); |
@@ -82,6 +82,8 @@ const char *l2_token_kind_name(enum l2_token_kind kind) { | |||
case L2_TOK_ERROR: | |||
return "error"; | |||
} | |||
return "(unknown)"; | |||
} | |||
void l2_token_free(struct l2_token *tok) { | |||
@@ -153,7 +155,7 @@ static int skip_whitespace(struct l2_lexer *lexer) { | |||
static int read_integer(struct l2_lexer *lexer) { | |||
char buffer[16]; // Should be enough | |||
int len = 0; | |||
size_t len = 0; | |||
while (len < sizeof(buffer) - 1 && is_numeric(peek_ch(lexer))) { | |||
buffer[len++] = read_ch(lexer); |
@@ -41,3 +41,11 @@ void l2_trace_cleanup(void *unused) { | |||
} | |||
#endif | |||
// ISO C forbids an empty translation unit | |||
// (and GCC warns on usude variables, but __attribute__((unused)) isn't ISO C) | |||
#ifdef __GNUC__ | |||
__attribute__((unused)) static int make_compiler_happy; | |||
#else | |||
static int make_compiler_happy; | |||
#endif |
@@ -2,6 +2,7 @@ | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <stdint.h> | |||
void l2_vm_print_val(struct l2_vm_value *val) { | |||
@@ -68,7 +69,8 @@ void l2_vm_print_val(struct l2_vm_value *val) { | |||
break; | |||
case L2_VAL_TYPE_CFUNCTION: | |||
printf("C FUNCTION, %p\n", val->cfunc); | |||
// ISO C doesn't let you cast a function pointer to void*. | |||
printf("C FUNCTION, %jx\n", (uintmax_t)val->cfunc); | |||
break; | |||
} | |||
} | |||
@@ -103,14 +105,6 @@ void l2_vm_print_fstack(struct l2_vm *vm) { | |||
} | |||
} | |||
static void print_op_num(l2_word *ops, size_t opcount, size_t ptr) { | |||
if (ptr >= opcount) { | |||
printf("<EOF>"); | |||
} else { | |||
printf("%i", ops[ptr]); | |||
} | |||
} | |||
void l2_vm_print_op(l2_word *ops, size_t opcount, size_t *ptr) { | |||
enum l2_opcode opcode = (enum l2_opcode)ops[(*ptr)++]; | |||
@@ -26,12 +26,6 @@ static l2_word alloc_val(struct l2_vm *vm) { | |||
return (l2_word)id; | |||
} | |||
static float u32_to_float(uint32_t num) { | |||
float f; | |||
memcpy(&f, &num, sizeof(num)); | |||
return f; | |||
} | |||
static double u32s_to_double(uint32_t high, uint32_t low) { | |||
double d; | |||
uint64_t num = (uint64_t)high << 32 | (uint64_t)low; | |||
@@ -297,7 +291,7 @@ void l2_vm_step(struct l2_vm *vm) { | |||
break; | |||
case L2_OP_RJMP: | |||
vm->iptr += vm->ops[vm->iptr++]; | |||
vm->iptr += vm->ops[vm->iptr] + 1; | |||
break; | |||
case L2_OP_STACK_FRAME_LOOKUP: |
@@ -34,7 +34,7 @@ static int eval_impl(const char *str, struct l2_parse_error *err) { | |||
return -1; | |||
} | |||
l2_vm_init(&vm, (l2_word *)w.mem, w.len / sizeof(l2_word)); | |||
l2_vm_init(&vm, w.mem, w.len / sizeof(l2_word)); | |||
l2_vm_run(&vm); | |||
free(w.mem); |
@@ -107,7 +107,7 @@ static void check_impl(const char *name) { | |||
}; | |||
struct l2_vm vm; | |||
l2_vm_init(&vm, (l2_word *)bytecode.mem, bytecode.len / sizeof(l2_word)); | |||
l2_vm_init(&vm, bytecode.mem, bytecode.len / sizeof(l2_word)); | |||
vm.std_output = &output.w; | |||
// Run a GC after every instruction to uncover potential GC issues |