예제 #1
0
파일: genoperator.c 프로젝트: jonas-l/ponyc
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
파일: genoperator.c 프로젝트: jonas-l/ponyc
LLVMValueRef gen_assign_value(compile_t* c, ast_t* left, LLVMValueRef right,
  ast_t* right_type)
{
  // Must generate the right hand side before the left hand side.
  if(right == NULL)
    return NULL;

  // This is from pattern matching and we should not generate the alloca again.
  return assign_rvalue(c, ast_child(left), right_type, right);
}
예제 #3
0
파일: genoperator.c 프로젝트: jonas-l/ponyc
static bool assign_tuple(compile_t* c, ast_t* left, ast_t* r_type,
  LLVMValueRef r_value)
{
  // Handle assignment for each component.
  ast_t* child = ast_child(left);
  ast_t* rtype_child = ast_child(r_type);
  int i = 0;

  while(child != NULL)
  {
    ast_t* expr = NULL;

    switch(ast_id(child))
    {
      case TK_SEQ:
        // The actual tuple expression is inside a sequence node.
        expr = ast_child(child);
        break;

      case TK_LET:
      case TK_VAR:
      case TK_TUPLE:
        expr = child;
        break;

      case TK_DONTCARE:
        // Ignore this element.
        break;

      default:
        assert(0);
    }

    if(expr != NULL)
    {
      // Extract the tuple value.
      LLVMValueRef rvalue_child = LLVMBuildExtractValue(c->builder, r_value, i,
        "");

      // Recurse, assigning pairwise.
      if(assign_rvalue(c, expr, rtype_child, rvalue_child) == NULL)
        return false;
    }

    i++;
    child = ast_sibling(child);
    rtype_child = ast_sibling(rtype_child);
  }

  assert(rtype_child == NULL);
  return true;
}
예제 #4
0
파일: genoperator.c 프로젝트: jonas-l/ponyc
LLVMValueRef gen_assign(compile_t* c, ast_t* ast)
{
  // Must generate the right hand side before the left hand side. Left and
  // right are swapped for type checking, so we fetch them in reverse order.
  AST_GET_CHILDREN(ast, right, left);
  LLVMValueRef r_value = gen_expr(c, right);

  // Emit debug location of assignment expression
  dwarf_location(&c->dwarf, ast);

  if(r_value == NULL)
    return NULL;

  return assign_rvalue(c, left, ast_type(right), r_value);
}
예제 #5
0
파일: genoperator.c 프로젝트: enigma/ponyc
LLVMValueRef gen_assign(compile_t* c, ast_t* ast)
{
  // Must generate the right hand side before the left hand side. Left and
  // right are swapped for type checking, so we fetch them in reverse order.
  AST_GET_CHILDREN(ast, right, left);
  LLVMValueRef r_value = gen_expr(c, right);

  if(r_value == NULL)
    return NULL;

  codegen_debugloc(c, ast);
  LLVMValueRef result = assign_rvalue(c, left, ast_type(right), r_value);
  codegen_debugloc(c, NULL);
  return result;
}
예제 #6
0
파일: genoperator.c 프로젝트: DevL/ponyc
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;
}