int main(){ scanner_t scan = scanner_new("test.m"); token_t tok; do { tok = scanner_read(&scan); printf("%s: %.*s\n", token_names[tok.type], (int)tok.length, tok.text); } while(tok.type != T_EOF); scanner_destroy(&scan); }
owl_term owl_load_module(vm_t *vm, uint8_t *bytecode, size_t size) { uint8_t ch; scanner_t *scanner = scanner_new(size, bytecode); owl_term function_list = owl_list_init(); unsigned char *code_ptr = vm->code + vm->code_size; while (scanner_has_next(scanner)) { ch = scanner_next(scanner); switch(ch) { default: printf("Unknown opcode: 0x%02x\n", ch); exit(1); case OP_RETURN: *code_ptr++ = ch; vm->code_size += 1; break; case OP_EXIT: case OP_PRINT: case OP_FILE_PWD: case OP_STORE_TRUE: case OP_STORE_FALSE: case OP_STORE_NIL: case OP_JMP: case OP_GC_COLLECT: *code_ptr++ = ch; *code_ptr++ = scanner_next(scanner); vm->code_size += 2; break; case OP_MOV: case OP_FILE_LS: case OP_NOT: case OP_LIST_COUNT: case OP_STRING_COUNT: case OP_CODE_LOAD: case OP_TEST: case OP_FUNCTION_NAME: case OP_TO_STRING: *code_ptr++ = ch; *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); vm->code_size += 3; break; case OP_TUPLE_NTH: case OP_STORE_INT: case OP_ADD: case OP_SUB: case OP_EQ: case OP_NOT_EQ: case OP_GREATER_THAN: case OP_LIST_NTH: case OP_CONCAT: case OP_STRING_CONTAINS: *code_ptr++ = ch; *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); vm->code_size += 4; break; case OP_LIST_SLICE: case OP_STRING_SLICE: *code_ptr++ = ch; *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); vm->code_size += 5; break; case OP_TUPLE: case OP_LIST: *code_ptr++ = ch; *code_ptr++ = scanner_next(scanner); uint8_t size = scanner_next(scanner); *code_ptr++ = size; vm->code_size += 3; for (int i = 0; i < size; i++) { *code_ptr++ = scanner_next(scanner); vm->code_size += 1; } break; case OP_ANON_FN: *code_ptr++ = ch; *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); *code_ptr++ = scanner_next(scanner); uint8_t n_upvals = scanner_next(scanner); *code_ptr++ = n_upvals; vm->code_size += 5; for (int i = 0; i < n_upvals; i++) { *code_ptr++ = scanner_next(scanner); vm->code_size += 1; } break; case OP_CAPTURE: { *code_ptr++ = OP_CAPTURE; *code_ptr++ = scanner_next(scanner); // ret loc uint8_t name_size = scanner_next(scanner); char name[name_size]; scanner_read(name, name_size, scanner); uint64_t id = strings_intern(vm->function_names, name); *code_ptr++ = (uint8_t) id; vm->code_size += 3; break; } case OP_PUB_FN: { uint8_t name_size = scanner_next(scanner); char name[name_size]; scanner_read(name, name_size, scanner); uint64_t id = strings_intern(vm->function_names, name); assert(id < MAX_FUNCTIONS); uint64_t instruction = (uint64_t) (code_ptr - vm->code); const char *function_name = strings_lookup_id(vm->function_names, id); Function* fun = owl_function_init(function_name, instruction); function_list = owl_list_push(vm, function_list, owl_function_from(fun)); vm->functions[id] = fun; break; } case OP_LOAD_STRING: { *code_ptr++ = OP_LOAD_STRING; *code_ptr++ = scanner_next(scanner); // ret loc uint8_t size = scanner_next(scanner); char str[size]; scanner_read(str, size, scanner); uint64_t id = strings_intern(vm->intern_pool, str); assert(id < UINT8_MAX); *code_ptr++ = (uint8_t) id; // string_id (needs to be bigger than 8 bit int) vm->code_size += 3; break; } case OP_CALL_LOCAL: { *code_ptr++ = OP_CALL_LOCAL; *code_ptr++ = scanner_next(scanner); // ret loc *code_ptr++ = scanner_next(scanner); // function_loc uint8_t func_arity = scanner_next(scanner); *code_ptr++ = func_arity; vm->code_size += 4; for (int i = 0; i < func_arity; i++) { *code_ptr++ = scanner_next(scanner); // arguments vm->code_size += 1; } break; } case OP_CALL: *code_ptr++ = OP_CALL; *code_ptr++ = scanner_next(scanner); // ret loc uint8_t name_size = scanner_next(scanner); char name[name_size]; scanner_read(&name, name_size, scanner); uint64_t id = strings_intern(vm->function_names, name); assert(id < MAX_FUNCTIONS); *code_ptr++ = (uint8_t) id; // function_id (needs to be bigger than 8 bit int) uint8_t arity = scanner_next(scanner); *code_ptr++ = arity; vm->code_size += 4; for (int i = 0; i < arity; i++) { *code_ptr++ = scanner_next(scanner); // arguments vm->code_size += 1; } break; } } free(scanner); return function_list; }