static int value_of(lua_State * L) { auto it = value_of(to_token_table(L, 1)); if (it) { push_boolean(L, it->is_command()); push_name(L, it->value()); push_integer(L, it->expr_precedence()); return 3; } else { push_nil(L); return 1; } }
static int find(lua_State * L) { list<pair<action, parse_table>> it = to_parse_table(L, 1).find(to_name_ext(L, 2)); if (it) { // TODO(Leo): support multiple actions auto p = head(it); push_notation_action(L, p.first); push_parse_table(L, p.second); return 2; } else { return push_nil(L); } }
static void test(struct hash *h) { push_number(h, "a" , 1.0); push_string(h, "b" , "hello world"); push_nil(h, "c"); int i; char buffer[10]; for (i=0;i<100;i++) { sprintf(buffer,"%d",i*2); push_number(h,buffer,i); } debug_table(h); hash_genpool(h); }
static int find(lua_State * L) { char k; if (lua_isnumber(L, 2)) { k = lua_tonumber(L, 2); } else { char const * str = lua_tostring(L, 2); if (strlen(str) != 1) throw exception("arg #2 must be a string of length 1"); k = str[0]; } auto it = to_token_table(L, 1).find(k); if (it) return push_token_table(L, *it); else return push_nil(L); }
bool run(struct context *context, struct byte_array *program, struct map *env, bool in_context) { null_check(context); null_check(program); program = byte_array_copy(program); program->current = program->data; struct program_state *state = NULL; enum Opcode inst = VM_NIL; if (context->runtime) { if (in_context) { if (!state) state = (struct program_state*)stack_peek(context->program_stack, 0); env = state->named_variables; // use the caller's variable set in the new state } else state = program_state_new(context, env); } while (program->current < program->data + program->length) { inst = (enum Opcode)*program->current; bool really = inst & VM_RLY; inst &= ~VM_RLY; #ifdef DEBUG display_program_counter(context, program); #endif program->current++; // increment past the instruction int32_t pc_offset = 0; switch (inst) { case VM_COM: case VM_ITR: if (iterate(context, inst, state, program)) goto done; break; case VM_RET: if (ret(context, program)) goto done; break; case VM_TRO: if (tro(context)) goto done; break; case VM_TRY: if (vm_trycatch(context, program)) goto done; break; case VM_EQU: case VM_MUL: case VM_DIV: case VM_ADD: case VM_SUB: case VM_NEQ: case VM_GTN: case VM_LTN: case VM_GRQ: case VM_LEQ: case VM_BND: case VM_BOR: case VM_MOD: case VM_XOR: case VM_INV: case VM_RSF: case VM_LSF: binary_op(context, inst); break; case VM_ORR: case VM_AND: pc_offset = boolean_op(context, program, inst); break; case VM_NEG: case VM_NOT: unary_op(context, inst); break; case VM_SRC: src(context, inst, program); break; case VM_DST: dst(context, really); break; case VM_STX: case VM_SET: set(context, inst, state, program); break; case VM_JMP: pc_offset = jump(context, program); break; case VM_IFF: pc_offset = iff(context, program); break; case VM_CAL: func_call(context, inst, program, NULL); break; case VM_LST: push_list(context, program); break; case VM_MAP: push_map(context, program); break; case VM_NIL: push_nil(context); break; case VM_INT: push_int(context, program); break; case VM_FLT: push_float(context, program); break; case VM_BUL: push_bool(context, program); break; case VM_STR: push_str(context, program); break; case VM_VAR: push_var(context, program); break; case VM_FNC: push_fnc(context, program); break; case VM_GET: list_get(context, really); break; case VM_PTX: case VM_PUT: list_put(context, inst, really); break; case VM_MET: method(context, program, really); break; default: vm_exit_message(context, ERROR_OPCODE); return false; } program->current += pc_offset; } if (!context->runtime) return false; done: if (!in_context) stack_pop(context->program_stack); return inst == VM_RET; }