示例#1
0
// Parse a function declaration.
//
//    function-decl -> 'def' identifier parameter-clause return-type ';'
//                   | 'def' identifier parameter-clause return-type function-definition
//    parameter-clause -> '(' [parameter-list] ')'
//
//    parameter-list -> parameter-decl | parameter-decl ',' parameter-list
//
//    return-type -> '->' type
//
//    function-definition -> block-stmt
//
// A function declaration may not have a definition.
Decl*
Parser::function_decl(Specifier spec)
{
  require(def_kw);
  Token n = match(identifier_tok);

  // parameter-clause
  Decl_seq parms;
  match(lparen_tok);
  while (lookahead() != rparen_tok) {
    Decl* p = parameter_decl();
    parms.push_back(p);

    if (match_if(comma_tok))
      continue;
    else
      break;
  }
  match(rparen_tok);

  // return-type
  match(arrow_tok);
  Type const* t = type();

  // function declaration
  if (match_if(semicolon_tok))
    return on_function(spec, n, parms, t);

  // function-definition.
  Stmt* s = block_stmt();

  return on_function(spec, n, parms, t, s);
}
示例#2
0
// Parse a method declaration.
//
//
//    method-decl -> 'def' identifier parameter-clause return-type function-definition
//
// Note that methods must be declared inside
// the class.
//
// TODO: Support out-of-class definitions?
//
// TODO: Support specifiers to modify the "this"
// parameter. Maybe before the return type? Maybe
// as part of the specifiers?
//
// TODO:
//
//    struct R {
//      const def f() -> void { }   // Why not...
Decl*
Parser::method_decl(Specifier spec)
{
  require(def_kw);
  Token n = match(identifier_tok);

  //check for a this_kw
  //do stuff
  //return on_ctor <- reference on_method

  // parameter-clause
  Decl_seq parms;
  match(lparen_tok);
  while (lookahead() != rparen_tok) {
    Decl* p = parameter_decl();
    parms.push_back(p);

    if (match_if(comma_tok))
      continue;
    else
      break;
  }
  match(rparen_tok);

  // return-type
  match(arrow_tok);
  Type const* t = type();

  // function-definition.
  Stmt* s = block_stmt();

  return on_method(spec, n, parms, t, s);
}
示例#3
0
// NOTE ADD LAMDBA PARSER HERE
Expr*
Parser::lambda_expr()
{
  require(bslash_tok);

  //Match the identifier inserted earlier
  Token n = match(identifier_tok);
  // parameter-clause
  Decl_seq parms;
  match(lparen_tok);
  while (lookahead() != rparen_tok)
  {

    Decl* p = parameter_decl();

    parms.push_back(p);
    if (match_if(comma_tok))
    {
      continue;
    }
    else
      break;
  }
  match(rparen_tok);

  // return-type
  match(arrow_tok);
  Type const* t = type();
  // must be function-definition
  Stmt* s = block_stmt();

  //return a lambda expression
  return on_lambda(n, parms, t, s);
}
示例#4
0
// Parse a module.
//
//    module -> decl-seq | <empty>
//
//    decl-seq -> decl | decl-seq
//
// TODO: Return an empty module.
Decl*
Parser::module()
{
  Decl_seq decls;
  while (!ts_.eof()) {
    try {
      Decl* d = decl();
      decls.push_back(d);
    } catch (Translation_error& err) {
      diagnose(err);
      consume_thru(term_);
    }
  }
  return on_module(decls);
}
示例#5
0
// Parse a record declaration.
//
//    record-decl -> 'struct' identifier record-body
//
//    record-body -> '{' field-seq '}'
//
//    field-seq -> field-seq | field-seq field-seq
Decl*
Parser::record_decl(Specifier spec)
{
  require(struct_kw);
  Token n = match(identifier_tok);

  // record-body and field-seq
  require(lbrace_tok);
  Decl_seq fs;
  while (lookahead() != rbrace_tok) {
    Decl* f = field_decl();
    fs.push_back(f);
  }
  match(rbrace_tok);
  return on_record(spec, n, fs);
}
示例#6
0
文件: offset.cpp 项目: thehexia/steve
// Returns an expression which computes the byte offsetof a
// member within a record.
// 'e' is an offsetof expression.
//
// The byte offset of a member within a record type
// is the sum of the length of all fields preceding
// it within the record.
Expr*
get_offset(Decl const* layout, Decl const* mem)
{
  assert(is<Layout_decl>(layout));
  // keep track of all member declarations coming before mem
  Decl_seq pred;

  Expr* offsetof = zero();

  for (auto decl : as<Layout_decl>(layout)->fields()) {
    if (decl == mem) {
      break;
    }

    pred.push_back(decl);
  }

  for (auto decl : pred) {
    offsetof = add(offsetof, get_length(decl->type()));
  }

  return offsetof;
}