NODE(sl_node_lambda_t, lambda) { sl_vm_insn_t insn; sl_compile_state_t sub_cs; size_t i; init_compile_state(&sub_cs, cs->vm, cs, node->arg_count + 1); for(i = 0; i < node->arg_count; i++) { st_insert(sub_cs.vars, (st_data_t)node->args[i], (st_data_t)(i + 1)); } sub_cs.section->req_registers = node->arg_count; sub_cs.section->arg_registers = node->arg_count; sub_cs.section->name = sl_make_cstring(cs->vm, "<lambda>"); compile_node(&sub_cs, node->body, 0); insn.opcode = SL_OP_RETURN; emit(&sub_cs, insn); insn.uint = 0; emit(&sub_cs, insn); insn.opcode = SL_OP_LAMBDA; emit(cs, insn); insn.section = sub_cs.section; emit(cs, insn); insn.uint = dest; emit(cs, insn); }
NODE(sl_node_lambda_t, lambda) { sl_compile_state_t sub_cs; size_t i; init_compile_state(&sub_cs, cs->vm, cs, node->arg_count + 1); for(i = 0; i < node->arg_count; i++) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->args[i], (sl_st_data_t)(i + 1)); } sub_cs.section->req_registers = node->arg_count; sub_cs.section->arg_registers = node->arg_count; sub_cs.section->name = sl_intern(cs->vm, "<lambda>"); compile_node(&sub_cs, node->body, 0); op_return(&sub_cs, 0); op_lambda(cs, sub_cs.section, dest); }
NODE(sl_node_def_t, def) { sl_vm_insn_t insn; sl_compile_state_t sub_cs; size_t i, on_reg; init_compile_state(&sub_cs, cs->vm, cs, node->req_arg_count + node->opt_arg_count + 1); for(i = 0; i < node->req_arg_count; i++) { st_insert(sub_cs.vars, (st_data_t)node->req_args[i], (st_data_t)(i + 1)); } for(i = 0; i < node->opt_arg_count; i++) { st_insert(sub_cs.vars, (st_data_t)node->opt_args[i].name, (st_data_t)(node->req_arg_count + i + 1)); } sub_cs.section->name = node->name; sub_cs.section->req_registers = node->req_arg_count; sub_cs.section->arg_registers = node->req_arg_count + node->opt_arg_count; sub_cs.section->opt_skip = sl_alloc(cs->vm->arena, sizeof(size_t) * (node->opt_arg_count + 1)); for(i = 0; i < node->opt_arg_count; i++) { sub_cs.section->opt_skip[i] = sub_cs.section->insns_count; compile_node(&sub_cs, node->opt_args[i].default_value, node->req_arg_count + i + 1); } sub_cs.section->opt_skip[node->opt_arg_count] = sub_cs.section->insns_count; compile_node(&sub_cs, node->body, 0); insn.opcode = SL_OP_RETURN; emit(&sub_cs, insn); insn.uint = 0; emit(&sub_cs, insn); if(node->on) { on_reg = reg_alloc(cs); compile_node(cs, node->on, on_reg); insn.opcode = SL_OP_DEFINE_ON; emit(cs, insn); insn.uint = on_reg; emit(cs, insn); reg_free(cs, on_reg); } else { insn.opcode = SL_OP_DEFINE; emit(cs, insn); } insn.imm = node->name; emit(cs, insn); insn.section = sub_cs.section; emit(cs, insn); insn.uint = dest; emit(cs, insn); }
NODE(sl_node_def_t, def) { sl_compile_state_t sub_cs; size_t i, on_reg; size_t init_regs = 1 + node->req_arg_count + node->opt_arg_count; if(node->rest_arg) { init_regs++; } init_compile_state(&sub_cs, cs->vm, cs, init_regs); for(i = 0; i < node->req_arg_count; i++) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->req_args[i], (sl_st_data_t)(i + 1)); } for(i = 0; i < node->opt_arg_count; i++) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->opt_args[i].name, (sl_st_data_t)(node->req_arg_count + i + 1)); } if(node->rest_arg) { sl_st_insert(sub_cs.vars, (sl_st_data_t)node->rest_arg, (sl_st_data_t)(node->req_arg_count + node->opt_arg_count + 1)); sub_cs.section->has_extra_rest_arg = 1; } sub_cs.section->name = node->name; sub_cs.section->req_registers = node->req_arg_count; sub_cs.section->arg_registers = node->req_arg_count + node->opt_arg_count; sub_cs.section->opt_skip = sl_alloc(cs->vm->arena, sizeof(size_t) * (node->opt_arg_count + 1)); for(i = 0; i < node->opt_arg_count; i++) { sub_cs.section->opt_skip[i] = sub_cs.section->insns_count; compile_node(&sub_cs, node->opt_args[i].default_value, node->req_arg_count + i + 1); } sub_cs.section->opt_skip[node->opt_arg_count] = sub_cs.section->insns_count; compile_node(&sub_cs, node->body, 0); op_return(&sub_cs, 0); if(node->on) { on_reg = reg_alloc(cs); compile_node(cs, node->on, on_reg); op_define_on(cs, on_reg, node->name, node->doc, sub_cs.section, dest); reg_free(cs, on_reg); } else { op_define(cs, node->name, node->doc, sub_cs.section, dest); } }