Пример #1
0
static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type,
  LLVMValueRef r_value)
{
  switch(ast_id(left))
  {
    case TK_VAR:
    case TK_LET:
    {
      // Generate the locals.
      if(gen_localdecl(c, left) == NULL)
        return NULL;

      return assign_rvalue(c, ast_child(left), r_type, r_value);
    }

    case TK_FVARREF:
    case TK_FLETREF:
    {
      // The result is the previous value of the field.
      LLVMValueRef l_value = gen_fieldptr(c, left);
      return assign_one(c, l_value, r_value, r_type);
    }

    case TK_VARREF:
    {
      // The result is the previous value of the local.
      LLVMValueRef l_value = gen_localptr(c, left);
      return assign_one(c, l_value, r_value, r_type);
    }

    case TK_TUPLE:
    {
      // If the l_value is a tuple, assemble it as the result.
      LLVMValueRef result = gen_expr(c, left);

      if(result == NULL)
        return NULL;

      if(!assign_tuple(c, left, r_type, r_value))
        return NULL;

      // Return the original tuple.
      return result;
    }

    case TK_ID:
    {
      // We may have recursed here from a VAR or LET or arrived directly.
      const char* name = ast_name(left);
      LLVMValueRef l_value = codegen_getlocal(c, name);
      return assign_one(c, l_value, r_value, r_type);
    }

    default: {}
  }

  assert(0);
  return NULL;
}
Пример #2
0
LLVMValueRef gen_localload(compile_t* c, ast_t* ast)
{
  LLVMValueRef local_ptr = gen_localptr(c, ast);

  if(local_ptr == NULL)
    return NULL;

  return LLVMBuildLoad(c->builder, local_ptr, "");
}
Пример #3
0
LLVMValueRef gen_localload(compile_t* c, ast_t* ast)
{
  LLVMValueRef local_ptr = gen_localptr(c, ast);

  if(local_ptr == NULL)
    return NULL;

  ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt);
  reach_type_t* t = reach_type(c->reach, type);
  ast_free_unattached(type);
  compile_type_t* c_t = (compile_type_t*)t->c_type;

  LLVMValueRef value = LLVMBuildLoad(c->builder, local_ptr, "");
  return gen_assign_cast(c, c_t->use_type, value, t->ast_cap);
}
Пример #4
0
LLVMValueRef gen_addressof(compile_t* c, ast_t* ast)
{
  ast_t* expr = ast_child(ast);

  switch(ast_id(expr))
  {
    case TK_VARREF:
    case TK_LETREF:
      return gen_localptr(c, expr);

    case TK_FVARREF:
    case TK_FLETREF:
      return gen_fieldptr(c, expr);

    default: {}
  }

  assert(0);
  return NULL;
}
Пример #5
0
static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type,
  LLVMValueRef r_value)
{
  switch(ast_id(left))
  {
    case TK_SEQ:
      // The actual expression is inside a sequence node.
      while(ast_id(left) == TK_SEQ)
      {
        assert(ast_childcount(left) == 1);
        left = ast_child(left);
      }
      return assign_rvalue(c, left, r_type, r_value);

    case TK_VAR:
    case TK_LET:
    {
      // Generate the locals.
      if(gen_localdecl(c, left) == NULL)
        return NULL;

      return assign_rvalue(c, ast_child(left), r_type, r_value);
    }

    case TK_FVARREF:
    case TK_FLETREF:
    {
      // The result is the previous value of the field.
      LLVMValueRef l_value = gen_fieldptr(c, left);
      return assign_one(c, l_value, r_value, r_type);
    }

    case TK_EMBEDREF:
    {
      // Do nothing. The embed field was already passed as the receiver.
      return GEN_NOVALUE;
    }

    case TK_VARREF:
    {
      // The result is the previous value of the local.
      LLVMValueRef l_value = gen_localptr(c, left);
      return assign_one(c, l_value, r_value, r_type);
    }

    case TK_TUPLE:
    {
      // If the l_value is a tuple, assemble it as the result.
      LLVMValueRef result = gen_expr(c, left);

      if(result == NULL)
        return NULL;

      if(!assign_tuple(c, left, r_type, r_value))
        return NULL;

      // Return the original tuple.
      return result;
    }

    case TK_ID:
    {
      // We may have recursed here from a VAR or LET or arrived directly.
      const char* name = ast_name(left);
      LLVMValueRef l_value = codegen_getlocal(c, name);
      return assign_one(c, l_value, r_value, r_type);
    }

    default: {}
  }

  assert(0);
  return NULL;
}