示例#1
0
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);
}
示例#2
0
文件: owl_code.c 项目: ukutaht/owlang
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;
}