Beispiel #1
0
void
Parser::elaborate_function_declaration(Function_decl& d)
{
  // Reset the list of implicit parameters.
  state.implicit_parms = {};

  // Elaborate the type of each parameter in turn. Note that this does
  // not declare the parameters, it just checks their types.
  Decl_list& parms = d.parameters();
  for (Decl& d : parms)
    elaborate_parameter_declaration(cast<Object_parm>(d));

  // Elaborate the return type.
  //
  // FIXME: If the return type shares a placehoder name with a parameter,
  // then that's not a placeholder. We need to rewrite the type.
  Type& ret = elaborate_type(d.return_type());

  // Rebuild the function type and update the declaration.
  d.type_ = &cxt.get_function_type(parms, ret);

  // If necessary, make the function a template.
  if (state.implicit_parms.size()) {
    Decl& tmp = cxt.make_template(state.implicit_parms, d);

    // FIXME: Actually make this a declaration! We probably need to
    // replace this entity in the declaration list with its new
    // template. We also need to update the overload set with the same.
    (void)tmp;
  }

}
Beispiel #2
0
// The type of the returned expression shall match the declared
// return type of the enclosing function.
//
// TODO: Implement me.
void
Elaborator::elaborate(Return_stmt* s)
{
  Function_decl* fn = stack.function();
  Type const* t = fn->return_type();

  // Check that the return type matches the returned value.
  Expr* c = require_converted(*this, s->first, t);
  if (!c)
    throw std::runtime_error("return type mismatch");
}
Beispiel #3
0
void
Parser::elaborate_function_definition(Function_decl& d)
{
  struct fn
  {
    Parser& p;
    Function_decl& fn;
    void operator()(Def& d)            { lingo_unhandled(d); }
    void operator()(Expression_def& d) { p.elaborate_function_definition(fn, d); }
    void operator()(Function_def& d)   { p.elaborate_function_definition(fn, d); }
  };
  apply(d.definition(), fn{*this, d});
}
Beispiel #4
0
// TODO: Parse default arguments.
//
// TODO: Should we have transformed expression definitions into legitimate
// function bodies at this point?
void
Elaborate_classes::function_declaration(Function_decl& d)
{
  struct fn
  {
    Self& elab;
    void operator()(Def& d)            { lingo_unhandled(d); }
    void operator()(Expression_def& d) { /* Do nothing. */ }
    void operator()(Function_def& d)   { elab.statement(d.statement()); }
  };

  Enter_scope scope(cxt, d);
  apply(d.definition(), fn{*this});
}
Beispiel #5
0
void
Parser::elaborate_function_definition(Function_decl& decl, Function_def& def)
{
  // Declare parameters as local variables prior to elaborating
  // the definition.
  //
  // TODO: Should we be using a specifici kind of scope here?
  Enter_scope scope(cxt);
  for (Decl& d : decl.parameters())
    declare(cxt, d);

  // Elaborate the definition's statement, possibly parsing it.
  Stmt& stmt = elaborate_compound_statement(def.statement());

  // Update the definition with the new statement. We don't need
  // to update the declaration.
  def.stmt_ = &stmt;
}
Beispiel #6
0
void
Parser::elaborate_function_definition(Function_decl& decl, Expression_def& def)
{
  // Declare parameters as local variables prior to elaborating
  // the definition.
  //
  // TODO: Should we be using a specifici kind of scope here?
  Enter_scope scope(cxt);
  for (Decl& d : decl.parameters())
    declare(cxt, d);

  // Elaborate the definition, possibly parsing it.
  Expr& expr = elaborate_expression(def.expression());

  // Transform the returned expression into a normal function
  // definition with a single return statement with that expression.
  Stmt& ret = cxt.make_return_statement(expr);
  Stmt& body = cxt.make_compound_statement({&ret});
  decl.def_ = &cxt.make_function_definition(body);
}