void asmgen::variant_push(int pos) { int dataoff = V_DATA_OFF(pos); int typeoff = V_TYPE_OFF(pos); mov_ll_rax((int64_t)&m_fk->ps); mov_rbp_rdx(dataoff); mov_rbp_rdi(typeoff); push_var(); }
node_ptr declare_var(node_ptr tnode, node_ptr vnode, int islocal) { if (vnode->ntype == E_AVAR || vnode->ntype == E_LVAR) { /* Declaring a new variable that will alias an existing one */ vnode = new_ast_var(vnode->name); } if (vnode->ntype != E_VAR) { fprintf(ERRFILE, "Error (declare_var). Expected node of type %s, got one of %s\n", node_type_name(E_VAR), node_type_name(vnode->ntype)); exit(1); } vnode->wsize = tnode->wsize; vnode->dtype = tnode->dtype; vnode->ntype = islocal ? E_LVAR : E_AVAR; vnode->isdefined = zero(); push_var(vnode); return new_node1(S_DECL, IOP_NONE, vnode); }
Node* create_node(int type) { Node* node = malloc(sizeof(Node)); node->type = type; if (type == NOMBRE) node->val = atof(yytext); if (type == VARIABLE) { node->var = search_var(yytext); if (node->var == NULL) { node->var = create_var((char*)_strdup(yytext)); push_var(node->var); } } return node; }
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; }
internal void print_type_(Type *type, u32 prec, TypePtrB1Map *seen, TypePtrU64Map *vars, U8Array *buf) { if (IS_VAR(type)) { type = rep(type); if (type->terms == NULL) { TypePtrU64MapGetResult result = type_ptr_u64_map_get(vars, type); if (!result.found) { result.value = vars->size; type_ptr_u64_map_put_bucket(vars, type, result.value, result.bucket); } push_var(buf, result.value); return; } else if (type->terms->next == type->terms) { type = type->terms; } else { array_push(buf, '{'); Type *term = type->terms; do { // TODO consider printing out the full type if (term == type->terms) { array_push(buf, ','); } if (IS_SEALED(term->symbol)) { u8Array_push_cstring(buf, "sealed \" "); u8Array_push_many(buf, term->seal->data, term->seal->size); array_push(buf, '"'); } else { switch (term->symbol) { case SYMBOL_VOID: array_push(buf, '0'); break; case SYMBOL_UNIT: array_push(buf, '1'); break; case SYMBOL_NUMBER: array_push(buf, 'N'); break; case SYMBOL_PRODUCT: array_push(buf, '*'); break; case SYMBOL_SUM: array_push(buf, '+'); break; case SYMBOL_BLOCK: u8Array_push_cstring(buf, "=>"); break; case SYMBOL_BLOCK | POLYMORPHIC_BIT: u8Array_push_cstring(buf, "->"); break; case SYMBOL_BOOL: array_push(buf, 'B'); break; default: array_push(buf, '?'); break; } } term = term->next; } while (term != type->terms); array_push(buf, '}'); return; } } TypePtrB1MapGetResult seen_result = type_ptr_b1_map_get(seen, type); if (seen_result.found) { TypePtrU64MapGetResult vars_result = type_ptr_u64_map_get(vars, type); if (!vars_result.found) { vars_result.value = vars->size; type_ptr_u64_map_put_bucket(vars, type, vars_result.value, vars_result.bucket); } push_var(buf, vars_result.value); return; } type_ptr_b1_map_put_bucket(seen, type, true, seen_result.bucket); TypePtrU64MapGetResult vars_result = type_ptr_u64_map_get(vars, type); if (vars_result.found) { map_delete_bucket(vars, vars_result.bucket); } usize begin = buf->size; if (IS_SEALED(type->symbol)) { if (prec > 8) { array_push(buf, '('); } u8Array_push_cstring(buf, "sealed \""); u8Array_push_many(buf, type->seal->data, type->seal->size); u8Array_push_cstring(buf, "\" "); print_type_(type->child1, 9, seen, vars, buf); if (prec > 8) { array_push(buf, ')'); } } else { u8 sym = 0; b32 children = true; u32 newprec = 100; b32 block = false; switch (type->symbol) { case SYMBOL_VOID: sym = '0'; children = false; break; case SYMBOL_UNIT: sym = '1'; children = false; break; case SYMBOL_NUMBER: sym = 'N'; children = false; break; case SYMBOL_PRODUCT: sym = '*'; newprec = 7; break; case SYMBOL_SUM: sym = '+'; newprec = 6; break; case SYMBOL_BLOCK: case SYMBOL_BLOCK | POLYMORPHIC_BIT: block = true; break; case SYMBOL_BOOL: sym = 'B'; children = false; break; default: sym = '?'; } if (prec > newprec) { array_push(buf, '('); } else if (block) { array_push(buf, '['); } if (children) { print_type_(type->child1, newprec + 1, seen, vars, buf); } if (type->symbol == SYMBOL_BLOCK) { u8Array_push_cstring(buf, " => "); } else if (type->symbol == (SYMBOL_BLOCK | POLYMORPHIC_BIT)) { u8Array_push_cstring(buf, " -> "); } else { if (children) { array_push(buf, ' '); } array_push(buf, sym); if (children) { array_push(buf, ' '); } } if (children) { print_type_(type->child2, newprec, seen, vars, buf); } if (prec > newprec) { array_push(buf, ')'); } else if (block) { array_push(buf, ']'); } } map_delete_bucket(seen, seen_result.bucket); vars_result = type_ptr_u64_map_get(vars, type); if (vars_result.found) { u32 shift = sizeof("μ. ") - 1 + var_len(vars_result.value); if (prec > 0) { shift++; } array_bump(buf, shift); memmove(buf->data + begin + shift, buf->data + begin, buf->size - begin - shift); u8 *hole = buf->data + begin; if (prec > 0) { *hole++ = '('; } hole = mempcpy(hole, "μ", sizeof("μ") - 1); u32 len = var_len(vars_result.value); write_var(hole, vars_result.value, len); hole += len; hole = mempcpy(hole, ". ", sizeof(". ") - 1); if (prec > 0) { array_push(buf, ')'); } } }
pgsVariable * pgsContext::encoding() { pgsVariable * encoding = pnew pgsString(wxLocale::GetSystemEncodingName()); push_var(encoding); return encoding; }
pgsVariable * pgsContext::seed() { pgsVariable * seed = pnew pgsNumber(wxString() << wxDateTime::GetTimeNow()); push_var(seed); return seed; }
pgsVariable * pgsContext::one() { pgsVariable * one = pnew pgsNumber(wxT("1")); push_var(one); return one; }
pgsVariable * pgsContext::zero() { pgsVariable * zero = pnew pgsNumber(wxT("0")); push_var(zero); return zero; }