Example #1
0
static void generate_return(code_block *parent, return_statement *ret) {
  function *fn = ret->target;

  bool non_void = !is_void(fn->return_type);
  if (non_void == !ret->value) {
    fprintf(stderr, "return from void function with return or non-void without "
      "return\n");
    abort();
  }

  size_t param_count = 1 + non_void;

  if (non_void) {
    parent = generate_expression(parent, ret->value);
  }

  parent->tail.type = GOTO;
  parent->tail.parameter_count = param_count;
  parent->tail.parameters = xmalloc(sizeof(size_t) * param_count);

  if (non_void) {
    parent->tail.parameters[1] = last_instruction(parent);
  }

  parent->tail.parameters[0] = 0;
  parent->tail.first_block = next_instruction(parent);

  size_t return_index = instruction_type(parent, 0)->struct_index;
  code_struct *return_struct = get_code_struct(parent->system, return_index);
  type *return_block_type = return_struct->fields[0].field_type;

  code_instruction *unwrap = new_instruction(parent, 2);
  unwrap->operation.type = O_GET_FIELD;
  unwrap->type = copy_type(return_block_type);
  unwrap->parameters[0] = 0; // return structs are always the first argument
  unwrap->parameters[1] = 0; // blockref position in all return structs
}
Example #2
0
void run_cpu(cpu* i) {
    i->status = 1;
    i->running = 1;
    
    //printf("\n\t---------------------------------------------------------------------\n");
    while(i->running) {
        // Get the next instruction:
        i->opcode = get_opcode(i);
        // Increment the pointer to the next instruction:
        next_instruction(i, 1);
        // OpCodes:
        switch(i->opcode) {
            //
            // @opcode: SET
            // @args: 2
            //    b: Register Address
            //    a: Set Value
            // @description:
            //      This opcode takes 2 parameters, b and a. It'll set [a] (value of a) to b (the memory address of
            //      the pointer)
            //
            // @todo: Add support for stack memory addresses.
            //
            case SET:
            // Create a new scope so we can create variables, etc...
            {
                // Use b as the index of the register array.
                // Because the registers' addreses range from [0x00-0x07], we can
                // treat them as integers, converting them to [0-7].
                set_register(i, get_arg(i, 0), get_arg(i, 1));
                debug_opcode(i, "SET", 2);
                next_instruction(i, 2); // 2 arguments.
                break;
            }
            case ADD:
            {
                set_register_ex(i, get_register_value(i, get_arg(i, 0), 3) + get_arg(i, 1));
                if (get_register_ex_value(i) > 0xffff)
                {
                    // Overflow:
                    set_register_ex(i, 0x001);
                    i->overflow = 1;
                    set_register(i, get_arg(i, 0), 0x00);
                }
                else
                {
                    set_register(i, get_arg(i, 0), get_register_ex_value(i));
                    set_register_ex(i, 0x000);
                }
                
                debug_opcode(i, "ADD", 2);                
                next_instruction(i, 2); // 2 arguments.
                break;
            }
            case SUB:
            {
                
                set_register_ex(i, get_register_value(i, get_arg(i, 0), 3) - get_arg(i, 1));
                
                if ( get_arg(i, 1) > get_register_value(i, get_arg(i, 0), 3))
                {
                    // Overflow:
                    set_register_ex(i, 0xffff);
                    i->underflow = 1;
                    set_register(i, get_arg(i, 0), 0x00);
                }
                else
                {
                    set_register(i, get_arg(i, 0), get_register_ex_value(i));
                    set_register_ex(i, 0x000);
                }
                
                debug_opcode(i, "SUB", 2);
                next_instruction(i, 2); // 2 arguments.
                break;
            }
            // Store in the stack:
            case MUL:
                set_register_ex(i, get_register_value(i, get_arg(i, 0), 3) * get_arg(i, 1));
                set_register(i, get_arg(i, 0), get_register_ex_value(i));
                set_register_ex(i, get_register_ex_value(i) >> 16);
                debug_opcode(i, "MUL", 2);
                next_instruction(i, 2); // 2 arguments.                
                break;
            case MLI:
            
                break;
            case DIV:
                
                if (get_arg(i, 1) == 0)
                {
                    set_register_ex(i, 0);
                    set_register(i, get_arg(i, 0), 0);
                }
                else
                {
                    set_register_ex(i, get_register_value(i, get_arg(i, 0), 3) / get_arg(i, 1));
                    set_register(i, get_arg(i, 0), get_register_ex_value(i));
                }
                debug_opcode(i, "DIV", 2);
                next_instruction(i, 2); // 2 arguments.
                break;
            case DVI:

                break;
            default:
                printf("\n\n%s\n\n\n\t\tInstruction Fault at: [%s%s%i%s%s] -> 0x%x\n\n\n%s\n",
                       COLORS_BG_RED,
                       COLORS_BG_BLACK,
                       COLORS_LIGHT_BLUE,
                       i->registers->pc,
                       COLORS_RESET,
                       COLORS_BG_RED,
                       i->program->code[i->registers->pc],
                       COLORS_RESET
                );
                i->status = 0;
                dump_registers(i, 0);
                return;
                break;
        }
        
        // Check the size of the instructions left.
        if (i->registers->pc >= i->program->size)
        {
            i->running = 0;
            break;
        }
    }

}