diff --git a/src/tools/compiler/compiler.c b/src/tools/compiler/compiler.c index fff5266..91e2ade 100644 --- a/src/tools/compiler/compiler.c +++ b/src/tools/compiler/compiler.c @@ -50,7 +50,8 @@ u8 symbol_table_add(ScopeTable *table, Symbol s) { exit(1); } - if (table->scopes[table->scope_ref].count + 1 > 255) { + u8 current_index = table->scopes[table->scope_ref].count; + if (current_index + 1 > 255) { fprintf(stderr, "Error: Only 255 symbols are allowed per scope" " first off: impressive; secondly:" " just create a new scope and keep going.\n"); @@ -67,7 +68,11 @@ u8 symbol_table_add(ScopeTable *table, Symbol s) { table->count, table->capacity); exit(1); } -#ifdef DEBUG_PRINT + + /* set ref to current count for local */ + s.ref = current_index; + +#ifdef DEBUG_COMPILER if (s.scope == VAR) { printf("$%d = %s\n", s.ref, s.name); } else if (s.scope == GLOBAL) { @@ -76,10 +81,10 @@ u8 symbol_table_add(ScopeTable *table, Symbol s) { printf("code[%d] = %s\n", s.ref, s.name); } #endif - table->scopes[table->scope_ref].symbols[table->scopes[table->scope_ref].count] = s; - u8 index = table->scopes[table->scope_ref].count; + + table->scopes[table->scope_ref].symbols[current_index] = s; table->scopes[table->scope_ref].count++; - return index; + return current_index; } u32 get_ref(ScopeTable *st, const char *name, u32 length) { @@ -172,181 +177,12 @@ Token next_token_is(TokenType type) { return token; } -/** - * Global . - */ -bool define_global(VM *vm, ScopeTable *st) { - Symbol s; - - Token token_type = next_token(); - switch (token_type.type) { - case TOKEN_TYPE_BOOL: - s.type = BOOL; - s.size = 1; - break; - case TOKEN_TYPE_I8: - s.type = I8; - s.size = 1; - break; - case TOKEN_TYPE_U8: - s.type = U8; - s.size = 1; - break; - case TOKEN_TYPE_I16: - s.type = I16; - s.size = 2; - break; - case TOKEN_TYPE_U16: - s.type = U16; - s.size = 2; - break; - case TOKEN_TYPE_INT: - s.type = I32; - s.size = 4; - break; - case TOKEN_TYPE_NAT: - s.type = U32; - s.size = 4; - break; - case TOKEN_TYPE_REAL: - s.type = F32; - s.size = 4; - break; - case TOKEN_TYPE_STR: - s.type = STR; - break; - case TOKEN_IDENTIFIER: - break; - default: - return false; - } - - Token name = next_token_is(TOKEN_IDENTIFIER); - if (name.length > MAX_SYMBOL_NAME_LENGTH) { - return false; - } - - memcpy(s.name, name.start, name.length); - s.name_length = name.length; - s.name[name.length] = '\0'; - - u32 addr = vm->mp; - s.ref = addr; - s.scope = GLOBAL; - - next_token_is(TOKEN_EQ); - - Token value = next_token(); - switch (value.type) { - case TOKEN_KEYWORD_TRUE: { - u32 addr = vm->mp; - write_u8(vm, memory, addr, 1); - - vm->mp += s.size; - vm->frames[vm->fp].end += s.size; - break; - } - case TOKEN_KEYWORD_FALSE: { - u32 addr = vm->mp; - write_u8(vm, memory, addr, 0); - - vm->mp += s.size; - vm->frames[vm->fp].end += s.size; - break; - } - case TOKEN_LITERAL_INT: { - i32 out = atoi(value.start); - - u32 addr = vm->mp; - write_u32(vm, memory, addr, out); - - vm->mp += s.size; - vm->frames[vm->fp].end += s.size; - break; - } - case TOKEN_LITERAL_NAT: { - char *endptr; - u32 out = (u32)strtoul(value.start, &endptr, 10); - if (endptr == value.start || *endptr != '\0') { - fprintf(stderr, "Invalid decimal literal: %s\n", value.start); - exit(1); - } - - u32 addr = vm->mp; - write_u32(vm, memory, addr, out); - - vm->mp += s.size; - vm->frames[vm->fp].end += s.size; - break; - } - case TOKEN_LITERAL_REAL: { - r32 out = float_to_real(atof(value.start)); - - u32 addr = vm->mp; - write_u32(vm, memory, addr, out); - - vm->mp += s.size; - vm->frames[vm->fp].end += s.size; - break; - } - case TOKEN_LITERAL_STR: { - const char *src = value.start; - i32 len = 0; - i32 i = 0; - - while (i < value.length) { - char c = src[i++]; - if (c == '"') { - continue; - } - if (c == '\\' && i < value.length) { - switch (src[i++]) { - case 'n': - c = '\n'; - break; - case 't': - c = '\t'; - break; - case 'r': - c = '\r'; - break; - case '\\': - case '"': - case '\'': - break; - default: - i--; /* Rewind for unknown escapes */ - } - } - write_u8(vm, memory, addr + 4 + len, c); - len++; - } - - u32 size = len + 5; /* 4 (len) + dst_len + 1 (null) */ - s.size = size; - - vm->mp += size; - vm->frames[vm->fp].end += size; - - write_u32(vm, memory, addr, len); - write_u8(vm, memory, addr + 4 + len, '\0'); - break; - } - default: - return false; - } - next_token_is(TOKEN_SEMICOLON); - - symbol_table_add(st, s); - return true; -} - /** * Var . */ void define_var(ScopeTable *st, Token regType) { Symbol s; - s.scope = VAR; + s.scope = (st->depth) ? VAR : GLOBAL; switch (regType.type) { case TOKEN_KEYWORD_PLEX: { s.type = PLEX; @@ -415,19 +251,24 @@ void define_var(ScopeTable *st, Token regType) { s.name[name.length] = '\0'; s.name_length = name.length; - next_token_is(TOKEN_BIG_MONEY); - - Token reg_num = next_token_is(TOKEN_LITERAL_INT); - s.ref = atoi(reg_num.start); symbol_table_add(st, s); } + /** - * function . + * Plex . + */ +void define_plex(VM *vm, ScopeTable *st) { + +} + + +/** + * Function . */ void define_function(VM *vm, ScopeTable *st) { Symbol s; - s.scope = LOCAL; + s.scope = GLOBAL; s.type = FUNCTION; Token name = next_token_is(TOKEN_IDENTIFIER); @@ -463,7 +304,6 @@ void define_function(VM *vm, ScopeTable *st) { } } s.ref = vm->cp; - next = next_token_is(TOKEN_LBRACE); st->scope_ref = temp; // need to add to the parents scope symbol_table_add(st, s); @@ -498,9 +338,12 @@ int get_instruction_byte_size(const char *opname) { return 2; } - 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 || + 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 || @@ -513,30 +356,42 @@ int get_instruction_byte_size(const char *opname) { 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, "real_to_nat") == 0 || + strcmp(opname, "nat_to_int") == 0 || strcmp(opname, "int_to_nat") == 0 || - strcmp(opname, "string_length") == 0 || strcmp(opname, "memset") == 0 || - strcmp(opname, "memset") == 0 || strcmp(opname, "memset_8") == 0 || + strcmp(opname, "string_length") == 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) { + strcmp(opname, "register_move") == 0 || + strcmp(opname, "malloc") == 0) { return 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 || + 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, "mul_real") == 0 || + strcmp(opname, "div_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) { + strcmp(opname, "bit_and") == 0 || + strcmp(opname, "bit_or") == 0 || + strcmp(opname, "bit_xor") == 0) { return 4; } - if (strcmp(opname, "halt") == 0 || strcmp(opname, "jump_if_flag") == 0 || + if (strcmp(opname, "halt") == 0 || + strcmp(opname, "jump_if_flag") == 0 || strcmp(opname, "jump") == 0) { return 5; } @@ -583,25 +438,12 @@ int get_instruction_byte_size(const char *opname) { exit(-1); } -#define FAKE_OP(op) \ - } \ - else if (strleq(token.start, op, token.length)) { \ - do { \ - while (token.type != TOKEN_SEMICOLON) { \ - token = next_token(); \ - } \ - /*printf("code[%d]=%s\n %d + %d = %d\n", vm->cp, op, \ - * get_instruction_byte_size(op), vm->cp, vm->cp + \ - * get_instruction_byte_size(op)); */ \ - vm->cp += get_instruction_byte_size(op); \ - } while (0); - /** * Build the symbol table and calculate the types/size/offsets of all values. */ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { Token token; - init_lexer(source); + init_parser(source); do { token = next_token(); if (token.type == TOKEN_ERROR) { @@ -615,6 +457,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { st->count++; st->scopes[st->count].parent = st->scope_ref; st->scope_ref = (i32)st->count; + st->depth++; continue; } @@ -623,11 +466,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { i32 parent = st->scopes[current_scope].parent; if (parent < 0) parent = 0; st->scope_ref = parent; - continue; - } - - if (token.type == TOKEN_KEYWORD_GLOBAL) { - define_global(vm, st); + st->depth--; continue; } @@ -636,18 +475,29 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { continue; } - if (token.type == TOKEN_KEYWORD_PLEX || token.type == TOKEN_TYPE_I8 || - token.type == TOKEN_TYPE_I16 || token.type == TOKEN_TYPE_INT || - token.type == TOKEN_TYPE_U8 || token.type == TOKEN_TYPE_U16 || - token.type == TOKEN_TYPE_NAT || token.type == TOKEN_TYPE_REAL || - token.type == TOKEN_TYPE_STR || token.type == TOKEN_TYPE_BOOL) { + if (token.type == TOKEN_KEYWORD_PLEX) { + define_plex(vm, st); + continue; + } + + if (token.type == TOKEN_TYPE_I8 || + token.type == TOKEN_TYPE_I16 || + token.type == TOKEN_TYPE_INT || + token.type == TOKEN_TYPE_U8 || + token.type == TOKEN_TYPE_U16 || + token.type == TOKEN_TYPE_NAT || + token.type == TOKEN_TYPE_REAL || + token.type == TOKEN_TYPE_STR || + token.type == TOKEN_TYPE_BOOL) { define_var(st, token); next_token_is(TOKEN_SEMICOLON); continue; } - if (token.type == TOKEN_KEYWORD_LOOP || token.type == TOKEN_KEYWORD_IF || - token.type == TOKEN_KEYWORD_ELSE || token.type == TOKEN_KEYWORD_DO || + if (token.type == TOKEN_KEYWORD_LOOP || + token.type == TOKEN_KEYWORD_IF || + token.type == TOKEN_KEYWORD_ELSE || + token.type == TOKEN_KEYWORD_DO || token.type == TOKEN_KEYWORD_FOR) { define_branch(vm, st); continue; @@ -731,91 +581,6 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { printf("code[%d] = syscall\n", vm->cp); #endif continue; - FAKE_OP("load_immediate") - FAKE_OP("load_address") - FAKE_OP("malloc") - FAKE_OP("memset_8") - FAKE_OP("memset_16") - FAKE_OP("memset_32") - FAKE_OP("load_offset_8") - FAKE_OP("load_offset_16") - FAKE_OP("load_offset_32") - FAKE_OP("load_indirect_8") - FAKE_OP("load_indirect_16") - FAKE_OP("load_indirect_32") - FAKE_OP("load_absolute_8") - FAKE_OP("load_absolute_16") - FAKE_OP("load_absolute_32") - FAKE_OP("store_absolute_8") - FAKE_OP("store_absolute_16") - FAKE_OP("store_absolute_32") - FAKE_OP("store_indirect_8") - FAKE_OP("store_indirect_16") - FAKE_OP("store_indirect_32") - FAKE_OP("store_offset_8") - FAKE_OP("store_offset_16") - FAKE_OP("store_offset_32") - FAKE_OP("register_move") - FAKE_OP("add_int") - FAKE_OP("sub_int") - FAKE_OP("mul_int") - FAKE_OP("div_int") - FAKE_OP("abs_int") - FAKE_OP("neg_int") - FAKE_OP("add_nat") - FAKE_OP("sub_nat") - FAKE_OP("mul_nat") - FAKE_OP("div_nat") - FAKE_OP("abs_nat") - FAKE_OP("neg_nat") - FAKE_OP("add_real") - FAKE_OP("sub_real") - FAKE_OP("mul_real") - FAKE_OP("div_real") - FAKE_OP("abs_real") - FAKE_OP("neg_real") - FAKE_OP("int_to_real") - FAKE_OP("nat_to_real") - FAKE_OP("real_to_int") - FAKE_OP("real_to_nat") - FAKE_OP("bit_shift_left") - FAKE_OP("bit_shift_right") - FAKE_OP("bit_shift_r_ext") - FAKE_OP("bit_and") - FAKE_OP("bit_or") - FAKE_OP("bit_xor") - FAKE_OP("jump") - FAKE_OP("jump_if_flag") - FAKE_OP("jump_eq_int") - FAKE_OP("jump_neq_int") - FAKE_OP("jump_gt_int") - FAKE_OP("jump_lt_int") - FAKE_OP("jump_le_int") - FAKE_OP("jump_ge_int") - FAKE_OP("jump_eq_nat") - FAKE_OP("jump_neq_nat") - FAKE_OP("jump_gt_nat") - FAKE_OP("jump_lt_nat") - FAKE_OP("jump_le_nat") - FAKE_OP("jump_ge_nat") - FAKE_OP("jump_eq_real") - FAKE_OP("jump_neq_real") - FAKE_OP("jump_ge_real") - FAKE_OP("jump_gt_real") - FAKE_OP("jump_lt_real") - FAKE_OP("jump_le_real") - FAKE_OP("string_length") - FAKE_OP("int_to_string") - FAKE_OP("nat_to_string") - FAKE_OP("real_to_string") - FAKE_OP("string_eq") - FAKE_OP("string_concat") - FAKE_OP("string_get_char") - FAKE_OP("string_find_char") - FAKE_OP("string_slice") - FAKE_OP("string_to_int") - FAKE_OP("string_to_nat") - FAKE_OP("string_to_real") } else { /* some other identifier */ printf("Unknown id at line %d: %.*s\n", token.line, token.length, @@ -832,7 +597,7 @@ void build_symbol_table(VM *vm, char *source, ScopeTable *st) { */ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { Token token; - init_lexer(source); + init_parser(source); do { token = next_token(); if (token.type == TOKEN_ERROR) { @@ -845,6 +610,7 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { st->count++; st->scopes[st->count].parent = st->scope_ref; st->scope_ref = (i32)st->count; + st->depth++; continue; } @@ -853,16 +619,7 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { i32 parent = st->scopes[current_scope].parent; if (parent < 0) parent = 0; st->scope_ref = parent; - continue; - } - - if (token.type == TOKEN_KEYWORD_GLOBAL) { - /* ignore, already processed */ - next_token(); /* type */ - next_token(); /* var */ - next_token(); /* eq */ - next_token(); /* value */ - next_token(); /* ; */ + st->depth--; continue; } @@ -875,10 +632,19 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { continue; } - if (token.type == TOKEN_KEYWORD_PLEX || token.type == TOKEN_TYPE_I8 || - token.type == TOKEN_TYPE_I16 || token.type == TOKEN_TYPE_INT || - token.type == TOKEN_TYPE_U8 || token.type == TOKEN_TYPE_U16 || - token.type == TOKEN_TYPE_NAT || token.type == TOKEN_TYPE_REAL || + if (token.type == TOKEN_KEYWORD_PLEX) { + /* ignore, already processed */ + /* FIXME: consume all tokens for this plex */ + continue; + } + + if (token.type == TOKEN_TYPE_I8 || + token.type == TOKEN_TYPE_I16 || + token.type == TOKEN_TYPE_INT || + token.type == TOKEN_TYPE_U8 || + token.type == TOKEN_TYPE_U16 || + token.type == TOKEN_TYPE_NAT || + token.type == TOKEN_TYPE_REAL || token.type == TOKEN_TYPE_STR) { /* ignore, already processed */ next_token(); /* type */ @@ -888,8 +654,10 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { continue; } - if (token.type == TOKEN_KEYWORD_LOOP || token.type == TOKEN_KEYWORD_IF || - token.type == TOKEN_KEYWORD_ELSE || token.type == TOKEN_KEYWORD_DO || + if (token.type == TOKEN_KEYWORD_LOOP || + token.type == TOKEN_KEYWORD_IF || + token.type == TOKEN_KEYWORD_ELSE || + token.type == TOKEN_KEYWORD_DO || token.type == TOKEN_KEYWORD_FOR) { /* ignore, already processed */ next_token(); /* id */ @@ -918,1405 +686,8 @@ void emit_bytecode(VM *vm, char *source, ScopeTable *st) { printf("-- %.*s --\n", token.length, token.start); #endif if (token.type == TOKEN_IDENTIFIER) { - /* check to see if it is an opcode first */ - if (strleq(token.start, "exit", token.length)) { + if (false) { - emit_op(vm, OP_EXIT); - vm->cp++; - - Token next = next_token(); - u32 ptr = get_ptr(next, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "call", token.length)) { - - emit_op(vm, OP_CALL); - vm->cp++; - - Token id = next_token_is(TOKEN_IDENTIFIER); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - u8 arg_count = 0; - u32 arg_pos = vm->cp++; - Token next = next_token_is(TOKEN_LPAREN); - next = next_token(); - while (next.type != TOKEN_RPAREN) { - u8 arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - arg_count++; - next = next_token(); - } - - vm->code[arg_pos] = arg_count; - -#ifdef DEBUG_PRINT - printf("^code[%d] = %d\n", arg_pos, arg_count); -#endif - - next = next_token(); - if (next.type == TOKEN_SEMICOLON) { - emit_byte(vm, 255); - vm->cp++; - } else { - next = next_token(); - u8 arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - } - - continue; - } else if (strleq(token.start, "syscall", token.length)) { - - emit_op(vm, OP_SYSCALL); - vm->cp++; - - Token next = next_token(); - - u32 syscall_id = 0; - const char *syscall_name = next.start; - if (strleq(syscall_name, "EXIT", next.length)) - syscall_id = SYSCALL_EXIT; - else if (strleq(syscall_name, "OPEN", next.length)) - syscall_id = SYSCALL_DEVICE_OPEN; - else if (strleq(syscall_name, "READ", next.length)) - syscall_id = SYSCALL_DEVICE_READ; - else if (strleq(syscall_name, "WRITE", next.length)) - syscall_id = SYSCALL_DEVICE_WRITE; - else if (strleq(syscall_name, "CLOSE", next.length)) - syscall_id = SYSCALL_DEVICE_CLOSE; - else if (strleq(syscall_name, "IOCTL", next.length)) - syscall_id = SYSCALL_DEVICE_IOCTL; - else if (strleq(syscall_name, "REFRESH", next.length)) - syscall_id = SYSCALL_DEVICE_REFRESH; - - emit_u32(vm, syscall_id); - vm->cp += 4; - - next = next_token(); - while (next.type != TOKEN_SEMICOLON && - next.type != TOKEN_ARROW_RIGHT) { - u8 arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next = next_token(); - } - - if (next.type == TOKEN_ARROW_RIGHT) { - next = next_token(); - u8 arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - } - - } else if (strleq(token.start, "load_immediate", token.length)) { - - emit_op(vm, OP_LOAD_IMM); - vm->cp++; - - Token value = next_token(); - switch (value.type) { - case TOKEN_KEYWORD_TRUE: { - emit_u32(vm, 1); - break; - } - case TOKEN_KEYWORD_FALSE: { - emit_u32(vm, 0); - break; - } - case TOKEN_LITERAL_INT: { - i32 out = atoi(value.start); - emit_u32(vm, out); - break; - } - case TOKEN_LITERAL_NAT: { - char *endptr; - u32 out = (u32)strtoul(value.start, &endptr, 10); - if (endptr == value.start || *endptr != '\0') { - fprintf(stderr, "Invalid 'real' number: '%.*s'\n", token.length, - token.start); - exit(1); - } - emit_u32(vm, out); - break; - } - case TOKEN_LITERAL_REAL: { - r32 out = float_to_real(atof(value.start)); - emit_u32(vm, out); - break; - } - default: { - fprintf(stderr, "Unknown immediate: '%.*s'\n", token.length, - token.start); - exit(1); - } - } - - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_address", token.length)) { - emit_op(vm, OP_LOAD_IMM); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "malloc", token.length)) { - emit_op(vm, OP_MALLOC); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "memset_8", token.length)) { - emit_op(vm, OP_MEMSET_8); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "memset_16", token.length)) { - emit_op(vm, OP_MEMSET_16); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "memset_32", token.length)) { - emit_op(vm, OP_MEMSET_32); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_offset_8", token.length)) { - emit_op(vm, OP_LOAD_OFF_8); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_offset_16", token.length)) { - emit_op(vm, OP_LOAD_OFF_16); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_offset_32", token.length)) { - emit_op(vm, OP_LOAD_OFF_32); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_indirect_8", token.length)) { - emit_op(vm, OP_LOAD_IND_8); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_indirect_16", token.length)) { - emit_op(vm, OP_LOAD_IND_16); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_indirect_32", token.length)) { - emit_op(vm, OP_LOAD_IND_32); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_absolute_8", token.length)) { - emit_op(vm, OP_LOAD_ABS_8); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_absolute_16", token.length)) { - emit_op(vm, OP_LOAD_ABS_16); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "load_absolute_32", token.length)) { - emit_op(vm, OP_LOAD_ABS_32); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_absolute_8", token.length)) { - emit_op(vm, OP_STORE_ABS_8); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_absolute_16", token.length)) { - emit_op(vm, OP_STORE_ABS_16); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_absolute_32", token.length)) { - emit_op(vm, OP_STORE_ABS_32); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_indirect_8", token.length)) { - emit_op(vm, OP_STORE_IND_8); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_indirect_16", token.length)) { - emit_op(vm, OP_STORE_IND_16); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_indirect_32", token.length)) { - emit_op(vm, OP_STORE_IND_32); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_offset_8", token.length)) { - emit_op(vm, OP_STORE_OFF_8); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_offset_16", token.length)) { - emit_op(vm, OP_STORE_OFF_16); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "store_offset_32", token.length)) { - emit_op(vm, OP_STORE_OFF_32); - vm->cp++; - - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_ARROW_RIGHT); - - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "register_move", token.length)) { - emit_op(vm, OP_REG_MOV); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "add_int", token.length)) { - emit_op(vm, OP_ADD_INT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "sub_int", token.length)) { - emit_op(vm, OP_SUB_INT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "mul_int", token.length)) { - emit_op(vm, OP_MUL_INT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "div_int", token.length)) { - emit_op(vm, OP_DIV_INT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "abs_int", token.length)) { - emit_op(vm, OP_ABS_INT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "neg_int", token.length)) { - emit_op(vm, OP_NEG_INT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "add_nat", token.length)) { - emit_op(vm, OP_ADD_NAT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "sub_nat", token.length)) { - emit_op(vm, OP_SUB_NAT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "mul_nat", token.length)) { - emit_op(vm, OP_MUL_NAT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "div_nat", token.length)) { - emit_op(vm, OP_DIV_NAT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "abs_nat", token.length)) { - emit_op(vm, OP_ABS_NAT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "neg_nat", token.length)) { - emit_op(vm, OP_NEG_NAT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "add_real", token.length)) { - emit_op(vm, OP_ADD_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - ; - } else if (strleq(token.start, "sub_real", token.length)) { - emit_op(vm, OP_SUB_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "mul_real", token.length)) { - emit_op(vm, OP_MUL_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "div_real", token.length)) { - emit_op(vm, OP_DIV_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "abs_real", token.length)) { - emit_op(vm, OP_ABS_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "neg_real", token.length)) { - emit_op(vm, OP_NEG_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "int_to_real", token.length)) { - emit_op(vm, OP_INT_TO_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "nat_to_real", token.length)) { - emit_op(vm, OP_NAT_TO_REAL); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "real_to_int", token.length)) { - emit_op(vm, OP_REAL_TO_INT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "real_to_nat", token.length)) { - emit_op(vm, OP_REAL_TO_NAT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "bit_shift_left", token.length)) { - emit_op(vm, OP_BIT_SHIFT_LEFT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "bit_shift_right", token.length)) { - emit_op(vm, OP_BIT_SHIFT_RIGHT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "bit_shift_r_ext", token.length)) { - emit_op(vm, OP_BIT_SHIFT_R_EXT); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "bit_and", token.length)) { - emit_op(vm, OP_BAND); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "bit_or", token.length)) { - emit_op(vm, OP_BOR); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "bit_xor", token.length)) { - emit_op(vm, OP_BXOR); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - Token next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - next = next_token(); - arg = get_reg(next, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump", token.length)) { - emit_op(vm, OP_JMP); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_if_flag", token.length)) { - emit_op(vm, OP_JMPF); - vm->cp++; - - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_eq_int", token.length)) { - emit_op(vm, OP_JEQ_INT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_neq_int", token.length)) { - emit_op(vm, OP_JNEQ_INT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_gt_int", token.length)) { - emit_op(vm, OP_JGT_INT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_lt_int", token.length)) { - emit_op(vm, OP_JLT_INT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_le_int", token.length)) { - emit_op(vm, OP_JLE_INT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_ge_int", token.length)) { - emit_op(vm, OP_JGE_INT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_eq_nat", token.length)) { - emit_op(vm, OP_JEQ_NAT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_neq_nat", token.length)) { - emit_op(vm, OP_JNEQ_NAT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_gt_nat", token.length)) { - emit_op(vm, OP_JGT_NAT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_lt_nat", token.length)) { - emit_op(vm, OP_JLT_NAT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_le_nat", token.length)) { - emit_op(vm, OP_JLE_NAT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_ge_nat", token.length)) { - emit_op(vm, OP_JGE_NAT); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_eq_real", token.length)) { - emit_op(vm, OP_JEQ_REAL); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_neq_real", token.length)) { - emit_op(vm, OP_JNEQ_REAL); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_ge_real", token.length)) { - emit_op(vm, OP_JGE_REAL); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_gt_real", token.length)) { - emit_op(vm, OP_JGT_REAL); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_lt_real", token.length)) { - emit_op(vm, OP_JLT_REAL); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "jump_le_real", token.length)) { - emit_op(vm, OP_JLE_REAL); - vm->cp++; - Token id = next_token(); - u32 ptr = get_ptr(id, st); - emit_u32(vm, ptr); - vm->cp += 4; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "string_length", token.length)) { - emit_op(vm, OP_STRLEN); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "int_to_string", token.length)) { - emit_op(vm, OP_INT_TO_STRING); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "nat_to_string", token.length)) { - emit_op(vm, OP_NAT_TO_STRING); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - } else if (strleq(token.start, "real_to_string", token.length)) { - emit_op(vm, OP_REAL_TO_STRING); - vm->cp++; - Token reg = next_token(); - u8 arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_ARROW_RIGHT); - reg = next_token(); - arg = get_reg(reg, st); - emit_byte(vm, arg); - vm->cp++; - next_token_is(TOKEN_SEMICOLON); - ; - } 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 { /* some other identifier */ printf("Unknown id at line %d: %.*s\n", token.line, token.length, @@ -2336,4 +707,5 @@ bool compile(VM *vm, ScopeTable *st, char *source) { vm->cp = 0; /* actually start emitting code */ st->count = 0; emit_bytecode(vm, source, st); + return true; } diff --git a/src/tools/compiler/compiler.h b/src/tools/compiler/compiler.h index c921029..d28b7be 100644 --- a/src/tools/compiler/compiler.h +++ b/src/tools/compiler/compiler.h @@ -32,20 +32,16 @@ typedef struct plex_tab_s PlexTable; typedef struct scope_s Scope; typedef struct scope_tab_s ScopeTable; +#define MAX_SYMBOL_NAME_LENGTH 64 + struct value_type_s { SymbolType type; - u32 name; + char name[MAX_SYMBOL_NAME_LENGTH]; + u8 name_length; u32 size; u32 table_ref; // if it is a heap object }; -struct plex_def_s { - u32 name; - u32 size; - u32 field_ref_start; - u32 field_count; -}; - struct plex_fields_tab_s { u32 *plex_refs; ValueType *fields; @@ -53,13 +49,20 @@ struct plex_fields_tab_s { u32 capacity; }; +struct plex_def_s { + char name[MAX_SYMBOL_NAME_LENGTH]; + u8 name_length; + u32 size; + u32 field_ref_start; + u32 field_count; +}; + struct plex_tab_s { PlexDef *symbols; u32 count; u32 capacity; }; -#define MAX_SYMBOL_NAME_LENGTH 64 struct symbol_s { char name[MAX_SYMBOL_NAME_LENGTH]; u8 name_length; @@ -80,6 +83,7 @@ struct scope_tab_s { u32 count; u32 capacity; i32 scope_ref; + u32 depth; }; bool compile(VM *vm, ScopeTable *st, char *source); diff --git a/src/tools/compiler/parser.c b/src/tools/compiler/parser.c index 375222c..3bbdf86 100644 --- a/src/tools/compiler/parser.c +++ b/src/tools/compiler/parser.c @@ -7,14 +7,14 @@ typedef struct { const char *start; const char *current; int line; -} Lexer; +} Parser; -Lexer lexer; +Parser parser; -void initLexer(const char *source) { - lexer.start = source; - lexer.current = source; - lexer.line = 1; +void init_parser(const char *source) { + parser.start = source; + parser.current = source; + parser.line = 1; } static bool isAlpha(char c) { @@ -23,36 +23,36 @@ static bool isAlpha(char c) { static bool isDigit(char c) { return c >= '0' && c <= '9'; } -static bool isAtEnd() { return *lexer.current == '\0'; } +static bool isAtEnd() { return *parser.current == '\0'; } static char advance() { - lexer.current++; - return lexer.current[-1]; + parser.current++; + return parser.current[-1]; } -static char peek() { return *lexer.current; } +static char peek() { return *parser.current; } static char peekNext() { if (isAtEnd()) return '\0'; - return lexer.current[1]; + return parser.current[1]; } static bool match(char expected) { if (isAtEnd()) return false; - if (*lexer.current != expected) + if (*parser.current != expected) return false; - lexer.current++; + parser.current++; return true; } static Token makeToken(TokenType type) { Token token; token.type = type; - token.start = lexer.start; - token.length = (int)(lexer.current - lexer.start); - token.line = lexer.line; + token.start = parser.start; + token.length = (int)(parser.current - parser.start); + token.line = parser.line; return token; } @@ -61,7 +61,7 @@ static Token errorToken(const char *message) { token.type = TOKEN_ERROR; token.start = message; token.length = (int)strlen(message); - token.line = lexer.line; + token.line = parser.line; return token; } @@ -75,7 +75,7 @@ static void skipWhitespace() { advance(); break; case '\n': - lexer.line++; + parser.line++; advance(); break; case '/': @@ -90,7 +90,7 @@ static void skipWhitespace() { advance(); while (!isAtEnd()) { if (peek() == '\n') - lexer.line++; + parser.line++; if (peek() == '*' && peekNext() == '/') { advance(); advance(); @@ -110,8 +110,8 @@ static void skipWhitespace() { static TokenType checkKeyword(int start, int length, const char *rest, TokenType type) { - if (lexer.current - lexer.start == start + length && - memcmp(lexer.start + start, rest, length) == 0) { + if (parser.current - parser.start == start + length && + memcmp(parser.start + start, rest, length) == 0) { return type; } @@ -217,8 +217,6 @@ static TokenType identifierType() { switch (lexer.start[2]) { case 'a': return checkKeyword(3, 1, "d", TOKEN_KEYWORD_READ); - case 'f': - return checkKeyword(3, 4, "resh", TOKEN_KEYWORD_REFRESH); case 't': return checkKeyword(3, 3, "urn", TOKEN_KEYWORD_RETURN); } @@ -231,7 +229,14 @@ static TokenType identifierType() { if (lexer.current - lexer.start > 1) { switch (lexer.start[1]) { case 't': - return checkKeyword(2, 1, "r", TOKEN_TYPE_STR); + if (lexer.current - lexer.start > 2) { + switch (lexer.start[2]) { + case 'r': + return checkKeyword(2, 0, "", TOKEN_TYPE_STR); + case 'a': + return checkKeyword(2, 1, "t", TOKEN_KEYWORD_STAT); + } + } } } break; @@ -269,8 +274,6 @@ static TokenType identifierType() { } } break; - case 'g': - return checkKeyword(1, 5, "lobal", TOKEN_KEYWORD_GLOBAL); } return TOKEN_IDENTIFIER; @@ -303,7 +306,7 @@ static Token number() { static Token string() { while (peek() != '"' && !isAtEnd()) { if (peek() == '\n') - lexer.line++; + parser.line++; advance(); } @@ -317,7 +320,7 @@ static Token string() { Token next_token() { skipWhitespace(); - lexer.start = lexer.current; + parser.start = parser.current; if (isAtEnd()) return makeToken(TOKEN_EOF); @@ -440,8 +443,6 @@ const char *token_type_to_string(TokenType type) { return "KEYWORD_TRUE"; case TOKEN_KEYWORD_FALSE: return "KEYWORD_FALSE"; - case TOKEN_KEYWORD_GLOBAL: - return "KEYWORD_GLOBAL"; case TOKEN_OPERATOR_NOT: return "OPERATOR_NOT"; case TOKEN_OPERATOR_AND: diff --git a/src/tools/compiler/parser.h b/src/tools/compiler/parser.h index 714cf38..72713ad 100644 --- a/src/tools/compiler/parser.h +++ b/src/tools/compiler/parser.h @@ -31,7 +31,6 @@ typedef enum { TOKEN_KEYWORD_USE, TOKEN_KEYWORD_INIT, TOKEN_KEYWORD_THIS, - TOKEN_KEYWORD_GLOBAL, TOKEN_KEYWORD_OPEN, TOKEN_KEYWORD_READ, TOKEN_KEYWORD_WRITE, @@ -82,7 +81,7 @@ typedef struct { int line; } Token; -void initLexer(const char *source); +void init_parser(const char *source); Token next_token(); const char* token_type_to_string(TokenType type); diff --git a/src/vm/vm.c b/src/vm/vm.c index 7d3b14c..fbc8e2a 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -137,7 +137,7 @@ bool step_vm(VM *vm) { child->locals[i] = frame->locals[src_reg]; mask = 1 << (src_reg % 32); if (frame->heap_mask[src_reg / 32] & mask) { - child->heap_mask[i / 32] |= 1 << (i % 32); + child->heap_mask[i / 32] |= 1 << (i % 32); } } @@ -174,7 +174,8 @@ bool step_vm(VM *vm) { parent->heap_mask[parent->return_reg / 32] |= (1 << parent->return_reg); } else { parent->locals[parent->return_reg] = value; - parent->heap_mask[parent->return_reg / 32] &= ~(1 << parent->return_reg); + parent->heap_mask[parent->return_reg / 32] &= + ~(1 << parent->return_reg); } } @@ -473,7 +474,7 @@ bool step_vm(VM *vm) { frame->locals[0] = dest; vm->flag = 1; return true; - } + } case OP_MEMSET_16: { u32 i, start, end; u8 value_reg = read_u8(vm, code, vm->pc++); @@ -535,7 +536,7 @@ bool step_vm(VM *vm) { frame->locals[0] = dest; vm->flag = 1; return true; - } + } case OP_REG_MOV: { u8 dest, src1; src1 = read_u8(vm, code, vm->pc);