fix silly missing `get_reg` error. all non gui ones are working now
This commit is contained in:
parent
9218051b87
commit
07528b1f3f
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue