fix silly missing `get_reg` error. all non gui ones are working now

This commit is contained in:
zongor 2025-12-03 21:45:03 -08:00
parent 9218051b87
commit 07528b1f3f
5 changed files with 431 additions and 671 deletions

View File

@ -129,8 +129,7 @@ const char *opcode_to_string(Opcode op) {
[OP_REAL_TO_STRING] = "real-to-string", [OP_REAL_TO_STRING] = "real-to-string",
[OP_STRING_TO_INT] = "string-to-int", [OP_STRING_TO_INT] = "string-to-int",
[OP_STRING_TO_NAT] = "string-to-nat", [OP_STRING_TO_NAT] = "string-to-nat",
[OP_STRING_TO_REAL] = "string-to-real" [OP_STRING_TO_REAL] = "string-to-real"};
};
if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) { if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) {
return "<invalid-opcode>"; return "<invalid-opcode>";
@ -161,7 +160,28 @@ void symbol_table_init(SymbolTable *table) {
table->capacity = 16; table->capacity = 16;
} }
Symbol *symbol_table_lookup(SymbolTable *table, const char *name, u32 length) {
for (u32 i = 0; i < table->count; i++) {
if (table->symbols[i].name_length == length) {
if (strleq(table->symbols[i].name, name, length)) {
return &table->symbols[i];
}
}
}
return nil;
}
u32 symbol_table_add(SymbolTable *table, Symbol s) { u32 symbol_table_add(SymbolTable *table, Symbol s) {
Symbol *sym = symbol_table_lookup(table, s.name, s.name_length);
if (sym != nil) {
fprintf(stderr,
"Error: Symbol '%.*s' already defined, the assembler is not smart "
"enough to do scope properly so please pick a different variable "
"name (hard I know)\n",
s.name_length, s.name);
exit(1);
}
if (table->count >= table->capacity) { if (table->count >= table->capacity) {
table->capacity *= 2; table->capacity *= 2;
table->symbols = realloc(table->symbols, table->capacity * sizeof(Symbol)); table->symbols = realloc(table->symbols, table->capacity * sizeof(Symbol));
@ -182,17 +202,6 @@ u32 symbol_table_add(SymbolTable *table, Symbol s) {
return index; return index;
} }
Symbol *symbol_table_lookup(SymbolTable *table, const char *name, u32 length) {
for (u32 i = 0; i < table->count; i++) {
if (table->symbols[i].name_length == length) {
if (strleq(table->symbols[i].name, name, length)) {
return &table->symbols[i];
}
}
}
return nil;
}
u32 get_ref(SymbolTable *st, const char *name, u32 length) { u32 get_ref(SymbolTable *st, const char *name, u32 length) {
Symbol *sym = symbol_table_lookup(st, name, length); Symbol *sym = symbol_table_lookup(st, name, length);
if (!sym) { if (!sym) {
@ -591,6 +600,109 @@ void define_branch(VM *vm, SymbolTable *st) {
symbol_table_add(st, s); symbol_table_add(st, s);
} }
int get_instruction_byte_size(const char *opname) {
// Return (1 + 1)
if (strcmp(opname, "return") == 0) {
return 2; // 1 byte opcode + 1 byte return register
}
if (strcmp(opname, "neg_int") == 0 || strcmp(opname, "abs_int") == 0 ||
strcmp(opname, "neg_nat") == 0 || strcmp(opname, "abs_nat") == 0 ||
strcmp(opname, "neg_real") == 0 || strcmp(opname, "abs_real") == 0 ||
strcmp(opname, "int_to_string") == 0 ||
strcmp(opname, "load_indirect_8") == 0 ||
strcmp(opname, "nat_to_string") == 0 ||
strcmp(opname, "load_indirect_16") == 0 ||
strcmp(opname, "real_to_string") == 0 ||
strcmp(opname, "load_indirect_32") == 0 ||
strcmp(opname, "int_to_real") == 0 ||
strcmp(opname, "store_indirect_8") == 0 ||
strcmp(opname, "nat_to_real") == 0 ||
strcmp(opname, "store_indirect_16") == 0 ||
strcmp(opname, "real_to_int") == 0 ||
strcmp(opname, "store_indirect_32") == 0 ||
strcmp(opname, "real_to_nat") == 0 || strcmp(opname, "nat_to_int") == 0 ||
strcmp(opname, "int_to_nat") == 0 ||
strcmp(opname, "string_length") == 0 ||
strcmp(opname, "store_absolute_32") == 0 ||
strcmp(opname, "store_absolute_8") == 0 ||
strcmp(opname, "store_absolute_16") == 0 ||
strcmp(opname, "memset") == 0 || strcmp(opname, "memset") == 0 ||
strcmp(opname, "memset_8") == 0 || strcmp(opname, "memset_16") == 0 ||
strcmp(opname, "register_move") == 0 || strcmp(opname, "malloc") == 0) {
return 3;
}
// Register_register_register opcodes (4 bytes: 1 + 3)
if (strcmp(opname, "add_int") == 0 || strcmp(opname, "sub_int") == 0 ||
strcmp(opname, "mul_int") == 0 || strcmp(opname, "div_int") == 0 ||
strcmp(opname, "add_nat") == 0 || strcmp(opname, "sub_nat") == 0 ||
strcmp(opname, "mul_nat") == 0 || strcmp(opname, "div_nat") == 0 ||
strcmp(opname, "add_real") == 0 || strcmp(opname, "sub_real") == 0 ||
strcmp(opname, "bit_shift_left") == 0 ||
strcmp(opname, "bit_shift_right") == 0 ||
strcmp(opname, "bit_shift_r_ext") == 0 ||
strcmp(opname, "bit_and") == 0 || strcmp(opname, "bit_or") == 0 ||
strcmp(opname, "bit_xor") == 0 || strcmp(opname, "mul_real") == 0 ||
strcmp(opname, "div_real") == 0) {
return 4;
}
// (5 bytes: 1 + 4)
if (strcmp(opname, "halt") == 0 || strcmp(opname, "jump_if_flag") == 0 ||
strcmp(opname, "jump") == 0) {
return 5;
}
// Load, Load_immediate (6 bytes: 1 + 1 + 4)
if (strcmp(opname, "load_absolute_32") == 0 ||
strcmp(opname, "load_immediate") == 0 ||
strcmp(opname, "load_address") == 0 ||
strcmp(opname, "load_absolute_16") == 0 ||
strcmp(opname, "load_absolute_8") == 0) {
return 6;
}
// jump compare (7 bytes: 1 + 4 + 1 + 1)
if (strcmp(opname, "jump_eq_int") == 0 ||
strcmp(opname, "jump_neq_int") == 0 ||
strcmp(opname, "jump_gt_int") == 0 ||
strcmp(opname, "jump_lt_int") == 0 ||
strcmp(opname, "jump_le_int") == 0 ||
strcmp(opname, "jump_ge_int") == 0 ||
strcmp(opname, "jump_eq_nat") == 0 ||
strcmp(opname, "jump_neq_nat") == 0 ||
strcmp(opname, "jump_gt_nat") == 0 ||
strcmp(opname, "jump_lt_nat") == 0 ||
strcmp(opname, "jump_le_nat") == 0 ||
strcmp(opname, "jump_ge_nat") == 0 ||
strcmp(opname, "jump_eq_real") == 0 ||
strcmp(opname, "jump_neq_real") == 0 ||
strcmp(opname, "jump_gt_real") == 0 ||
strcmp(opname, "jump_lt_real") == 0 ||
strcmp(opname, "jump_le_real") == 0 ||
strcmp(opname, "jump_ge_real") == 0 ||
strcmp(opname, "store_offset_8") == 0 ||
strcmp(opname, "store_offset_16") == 0 ||
strcmp(opname, "store_offset_32") == 0 ||
strcmp(opname, "load_offset_8") == 0 ||
strcmp(opname, "load_offset_16") == 0 ||
strcmp(opname, "load_offset_32") == 0) {
return 7;
}
fprintf(stderr, "Unknown opcode for sizing: %s\n", opname);
exit(-1);
}
#define FAKE_OP(op) \
} \
else if (strleq(token.start, op, token.length)) { \
while (token.type != TOKEN_SEMICOLON) \
token = next_token(); \
vm->cp += get_instruction_byte_size(op);
/** /**
* Build the symbol table and calculate the types/size/offsets of all values. * Build the symbol table and calculate the types/size/offsets of all values.
*/ */
@ -604,10 +716,7 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
exit(1); exit(1);
} }
printf("Line %d [%s]: %.*s cp=%d mp=%d\n", token.line, if (token.type != TOKEN_EOF) {
token_type_to_string(token.type), token.length, token.start, vm->cp,
vm->mp);
if (token.type == TOKEN_KEYWORD_GLOBAL) { if (token.type == TOKEN_KEYWORD_GLOBAL) {
define_global(vm, st); define_global(vm, st);
continue; continue;
@ -654,6 +763,7 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
if (token.type == TOKEN_IDENTIFIER) { if (token.type == TOKEN_IDENTIFIER) {
// check to see if it is an opcode first // check to see if it is an opcode first
if (strleq(token.start, "exit", token.length)) { if (strleq(token.start, "exit", token.length)) {
vm->cp++; vm->cp++;
next_token(); next_token();
@ -661,12 +771,14 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
next_token_is(TOKEN_SEMICOLON); next_token_is(TOKEN_SEMICOLON);
} else if (strleq(token.start, "call", token.length)) { } else if (strleq(token.start, "call", token.length)) {
vm->cp++; vm->cp++;
next_token_is(TOKEN_IDENTIFIER); next_token_is(TOKEN_IDENTIFIER);
vm->cp += 4; vm->cp += 4;
bool has_return = false; bool has_return = false;
u8 arg_count = 0;
vm->cp++; vm->cp++;
Token next = next_token(); Token next = next_token();
@ -674,17 +786,20 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
if (next.type != TOKEN_ARROW_RIGHT) { if (next.type != TOKEN_ARROW_RIGHT) {
get_reg(next, st); get_reg(next, st);
vm->cp++; vm->cp++;
arg_count++;
} else { } else {
has_return = true; has_return = true;
arg_count--; // is a return not an arg
} }
next = next_token(); next = next_token();
} }
if (!has_return) { if (!has_return) {
vm->cp+=2; vm->cp++;
continue; continue;
} }
} else if (strleq(token.start, "syscall", token.length)) { } else if (strleq(token.start, "syscall", token.length)) {
vm->cp++; vm->cp++;
Token next = next_token(); Token next = next_token();
@ -693,447 +808,97 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
next = next_token(); next = next_token();
while (next.type != TOKEN_SEMICOLON) { while (next.type != TOKEN_SEMICOLON) {
if (next.type != TOKEN_ARROW_RIGHT) { if (next.type != TOKEN_ARROW_RIGHT) {
get_reg(next, st);
vm->cp++; vm->cp++;
} }
next = next_token(); next = next_token();
} }
} else if (strleq(token.start, "load_immediate", token.length)) { FAKE_OP("load_immediate")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("load_address")
vm->cp++; FAKE_OP("malloc")
vm->cp += 4; FAKE_OP("memset_8")
vm->cp++; FAKE_OP("memset_16")
} else if (strleq(token.start, "load_address", token.length)) { FAKE_OP("memset_32")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("load_offset_8")
vm->cp++; FAKE_OP("load_offset_16")
vm->cp += 4; FAKE_OP("load_offset_32")
vm->cp++; FAKE_OP("load_indirect_8")
} else if (strleq(token.start, "malloc", token.length)) { FAKE_OP("load_indirect_16")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("load_indirect_32")
vm->cp++; FAKE_OP("load_absolute_8")
vm->cp++; FAKE_OP("load_absolute_16")
vm->cp++; FAKE_OP("load_absolute_32")
} else if (strleq(token.start, "memset_8", token.length)) { FAKE_OP("store_absolute_8")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("store_absolute_16")
vm->cp++; FAKE_OP("store_absolute_32")
vm->cp++; FAKE_OP("store_indirect_8")
vm->cp++; FAKE_OP("store_indirect_16")
vm->cp++; FAKE_OP("store_indirect_32")
} else if (strleq(token.start, "memset_16", token.length)) { FAKE_OP("store_offset_8")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("store_offset_16")
vm->cp++; FAKE_OP("store_offset_32")
vm->cp++; FAKE_OP("register_move")
vm->cp++; FAKE_OP("add_int")
vm->cp++; FAKE_OP("sub_int")
} else if (strleq(token.start, "memset_32", token.length)) { FAKE_OP("mul_int")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("div_int")
vm->cp++; FAKE_OP("abs_int")
vm->cp++; FAKE_OP("neg_int")
vm->cp++; FAKE_OP("add_nat")
vm->cp++; FAKE_OP("sub_nat")
} else if (strleq(token.start, "load_offset_8", token.length)) { FAKE_OP("mul_nat")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("div_nat")
vm->cp++; FAKE_OP("abs_nat")
vm->cp++; FAKE_OP("neg_nat")
vm->cp += 4; FAKE_OP("add_real")
vm->cp++; FAKE_OP("sub_real")
} else if (strleq(token.start, "load_offset_16", token.length)) { FAKE_OP("mul_real")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("div_real")
vm->cp++; FAKE_OP("abs_real")
vm->cp++; FAKE_OP("neg_real")
vm->cp += 4; FAKE_OP("int_to_real")
vm->cp++; FAKE_OP("nat_to_real")
} else if (strleq(token.start, "load_offset_32", token.length)) { FAKE_OP("real_to_int")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("real_to_nat")
vm->cp++; FAKE_OP("bit_shift_left")
vm->cp++; FAKE_OP("bit_shift_right")
vm->cp += 4; FAKE_OP("bit_shift_r_ext")
vm->cp++; FAKE_OP("bit_and")
} else if (strleq(token.start, "load_indirect_8", token.length)) { FAKE_OP("bit_or")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("bit_xor")
vm->cp++; FAKE_OP("jump")
vm->cp+=4; FAKE_OP("jump_if_flag")
vm->cp++; FAKE_OP("jump_eq_int")
} else if (strleq(token.start, "load_indirect_16", token.length)) { FAKE_OP("jump_neq_int")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("jump_gt_int")
vm->cp++; FAKE_OP("jump_lt_int")
vm->cp+=4; FAKE_OP("jump_le_int")
vm->cp++; FAKE_OP("jump_ge_int")
} else if (strleq(token.start, "load_indirect_32", token.length)) { FAKE_OP("jump_eq_nat")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("jump_neq_nat")
vm->cp++; FAKE_OP("jump_gt_nat")
vm->cp += 4; FAKE_OP("jump_lt_nat")
vm->cp++; FAKE_OP("jump_le_nat")
} else if (strleq(token.start, "load_absolute_8", token.length)) { FAKE_OP("jump_ge_nat")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("jump_eq_real")
vm->cp++; FAKE_OP("jump_neq_real")
vm->cp += 4; FAKE_OP("jump_ge_real")
vm->cp++; FAKE_OP("jump_gt_real")
} else if (strleq(token.start, "load_absolute_16", token.length)) { FAKE_OP("jump_lt_real")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("jump_le_real")
vm->cp++; FAKE_OP("string_length")
vm->cp += 4; FAKE_OP("int_to_string")
vm->cp++; FAKE_OP("nat_to_string")
} else if (strleq(token.start, "load_absolute_32", token.length)) { FAKE_OP("real_to_string")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("string_eq")
vm->cp++; FAKE_OP("string_concat")
vm->cp += 4; FAKE_OP("string_get_char")
vm->cp++; FAKE_OP("string_find_char")
} else if (strleq(token.start, "store_absolute_8", token.length)) { FAKE_OP("string_slice")
while (token.type != TOKEN_SEMICOLON) token = next_token(); FAKE_OP("string_to_int")
vm->cp++; FAKE_OP("string_to_nat")
vm->cp++; FAKE_OP("string_to_real")
vm->cp += 4;
} else if (strleq(token.start, "store_absolute_16", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
} else if (strleq(token.start, "store_absolute_32", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
} else if (strleq(token.start, "store_indirect_8", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
} else if (strleq(token.start, "store_indirect_16", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
} else if (strleq(token.start, "store_indirect_32", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
} else if (strleq(token.start, "store_offset_8", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
vm->cp++;
} else if (strleq(token.start, "store_offset_16", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
vm->cp++;
} else if (strleq(token.start, "store_offset_32", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp += 4;
vm->cp++;
} else if (strleq(token.start, "register_move", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "add_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "sub_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "mul_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "div_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "abs_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "neg_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "add_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "sub_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "mul_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "div_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "abs_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "neg_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "add_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "sub_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "mul_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "div_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "abs_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "neg_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "int_to_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "nat_to_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "real_to_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "real_to_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "bit_shift_left", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "bit_shift_right", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "bit_shift_r_ext", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "bit_and", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "bit_or", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "bit_xor", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
} else if (strleq(token.start, "jump_if_flag", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
} else if (strleq(token.start, "jump_eq_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_neq_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_gt_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_lt_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_le_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_ge_int", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_eq_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_neq_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_gt_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_lt_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_le_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_ge_nat", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_eq_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_neq_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_ge_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_gt_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_lt_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "jump_le_real", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp+=4;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "string_length", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "int_to_string", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "nat_to_string", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "real_to_string", token.length)) {
while (token.type != TOKEN_SEMICOLON) token = next_token();
vm->cp++;
vm->cp++;
vm->cp++;
} else if (strleq(token.start, "string_eq", token.length)) {
} else if (strleq(token.start, "string_concat", token.length)) {
} else if (strleq(token.start, "string_get_char", token.length)) {
} else if (strleq(token.start, "string_find_char", token.length)) {
} else if (strleq(token.start, "string_slice", token.length)) {
} else if (strleq(token.start, "string_to_int", token.length)) {
} else if (strleq(token.start, "string_to_nat", token.length)) {
} else if (strleq(token.start, "string_to_real", token.length)) {
} else { } else {
// some other identifier // some other identifier
printf("Unknown id at line %d: %.*s\n", token.line, token.length, printf("Unknown id at line %d: %.*s\n", token.line, token.length,
@ -1141,6 +906,7 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
exit(1); exit(1);
} }
} }
}
} while (token.type != TOKEN_EOF); } while (token.type != TOKEN_EOF);
} }
@ -1148,8 +914,6 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
* 2nd pass, emit the bytecode * 2nd pass, emit the bytecode
*/ */
void emit_bytecode(VM *vm, char *source, SymbolTable *st) { void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
USED(st);
Token token; Token token;
init_lexer(source); init_lexer(source);
do { do {
@ -1159,9 +923,6 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
break; break;
} }
if (token.type != TOKEN_EOF) { if (token.type != TOKEN_EOF) {
//printf("[Generate Bytecode cp=%d mp=%d ] Line %d [%s]: %.*s\n", vm->cp,
// vm->mp, token.line, token_type_to_string(token.type), token.length,
// token.start);
if (token.type == TOKEN_KEYWORD_GLOBAL) { if (token.type == TOKEN_KEYWORD_GLOBAL) {
// ignore, already processed // ignore, already processed
@ -1269,7 +1030,7 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
printf("^vm->code[%d] = %d\n", arg_pos, arg_count); printf("^vm->code[%d] = %d\n", arg_pos, arg_count);
if (!has_return) { if (!has_return) {
vm->cp+=2; vm->cp++;
emit_byte(vm, 255); emit_byte(vm, 255);
continue; continue;
} }

View File

@ -2,13 +2,12 @@ global str terminal_namespace = "/dev/term/0";
global str new_line = "\n"; global str new_line = "\n";
function main () function main ()
int n $0;
int str_n $1; int str_n $1;
load_immediate 35 -> n; load_immediate 36 -> $0;
call fib n -> n; call fib $0 -> $0;
int_to_string n -> str_n; int_to_string $0 -> str_n;
call pln str_n -> void; call pln str_n;
exit 0; exit 0;
function fib (int n $0) function fib (int n $0)

View File

@ -1,12 +1,12 @@
global str terminal_namespace = "/dev/term/0"; global str terminal_namespace = "/dev/term/0";
global str new_line = "\n"; global str new_line = "\n";
global str message = "nuqneH 'u'?"; global str hello = "nuqneH 'u'?";
function main () function main ()
str hello $0; str msg $0;
load_address message -> hello; load_address hello -> msg;
call pln hello; call pln msg;
exit 0; exit 0;
function pln (str message $0) function pln (str message $0)

View File

@ -5,8 +5,8 @@ global str new_line = "\n";
function main () function main ()
real a $0; real a $0;
int i $1; int i $1;
int mode $11; int in_mode $11;
str term $10; str in_term $10;
load_immediate 5.0 -> a; load_immediate 5.0 -> a;
load_immediate 5000 -> i; load_immediate 5000 -> i;
@ -18,20 +18,20 @@ function main ()
add_int i $3 -> i; add_int i $3 -> i;
jump_ge_int loop_body i $2; jump_ge_int loop_body i $2;
load_address terminal_namespace -> term; load_address terminal_namespace -> in_term;
load_immediate 0 -> mode; load_immediate 0 -> in_mode;
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0); syscall OPEN in_term in_mode -> in_term; // Terminal term = open("/dev/term/0", 0);
nat b $1; nat b $1;
real_to_nat a -> b; real_to_nat a -> b;
load_address prompt -> $7; load_address prompt -> $7;
string_length $7 -> $8; string_length $7 -> $8;
syscall WRITE term $7 $8; // print prompt syscall WRITE in_term $7 $8; // print prompt
str user_string $9; str user_string $9;
load_immediate 32 -> $8; load_immediate 32 -> $8;
malloc $8 -> user_string; malloc $8 -> user_string;
syscall READ term user_string $8; // read in max 32 byte string syscall READ in_term user_string $8; // read in max 32 byte string
call pln user_string; call pln user_string;
nat_to_string b -> $4; nat_to_string b -> $4;

View File

@ -3,23 +3,23 @@ global str prompt = "Enter a string:";
global str new_line = "\n"; global str new_line = "\n";
function main () function main ()
int mode $11; int in_mode $11;
str term $10; str in_term $10;
load_immediate terminal_namespace -> term; load_address terminal_namespace -> in_term;
load_immediate 0 -> mode; load_immediate 0 -> in_mode;
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0); syscall OPEN in_term in_mode -> in_term; // Terminal term = open("/dev/term/0", 0);
load_immediate prompt -> $7; load_address prompt -> $7;
string_length $7 -> $8; string_length $7 -> $8;
syscall WRITE term $7 $8; // print prompt syscall WRITE in_term $7 $8; // print prompt
str user_string $9; str user_string $9;
load_immediate 32 -> $8; load_immediate 32 -> $8;
malloc $8 -> user_string; malloc $8 -> user_string;
syscall READ term user_string $8; // read in max 32 byte string syscall READ in_term user_string $8; // read in max 32 byte string
call pln user_string -> void; call pln user_string;
exit 0; exit 0;
function pln (str message $0) function pln (str message $0)