Exemplo n.º 1
0
// Parse a declaration.
//
//    declaration:
//      [specifier-seq] basic-declaration
//
//    basic-declaration:
//      variable-declaration
//      function-declaration
//      type-declaration
//      concept-declaration
Decl&
Parser::declaration()
{
  // Parse and cache the specifier sequences.
  specifier_seq();

  switch (lookahead()) {
    case tk::var_tok:
      return variable_declaration();

    case tk::def_tok:
      return function_declaration();

    case tk::class_tok:
      return class_declaration();

    case tk::concept_tok:
      lingo_unreachable();
    case tk::super_tok:
      return super_declaration();
    default:
      break;
  }
  throw Syntax_error("invalid declaration");
}
Exemplo n.º 2
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);
  const Type* t = nullptr;
  // Determine if it is inheriting from a base class
  if(match_if(colon_tok)){
    // We have a base class
    t = type();
  }

  // record-body and field-seq
  require(lbrace_tok);
  Decl_seq fs, ms;
  while (lookahead() != rbrace_tok) {
    Specifier spec = specifier_seq();
    if (lookahead() == def_kw) {
      Decl* m = method_decl(spec);
      ms.push_back(m);
    } else if(lookahead() == identifier_tok) {
      Decl* f = field_decl(spec);
      fs.push_back(f);
    } else {
      throw Syntax_error(ts_.location(), "invalid member declaration");
    }
  }
  match(rbrace_tok);

  // Need to replace nullptr with base record
  return on_record(spec, n, fs, ms, t);
}
Exemplo n.º 3
0
// Parse a field declaration.
//
//    field-decl -> [specifier-seq] identifier object-type
Decl*
Parser::field_decl()
{
  // specifier-seq
  Specifier spec = specifier_seq();

  // actual declaration
  Token n = match(identifier_tok);
  match(colon_tok);
  Type const* t = type();
  match(semicolon_tok);
  return on_field(spec, n, t);
}
Exemplo n.º 4
0
// Parse a declaration.
//
//    decl -> [specifier-seq] entity-decl
//
//    entity-decl -> variable-decl
//                 | function-decl
Decl*
Parser::decl()
{
  // optional specifier-seq
  Specifier spec = specifier_seq();

  // entity-decl
  switch (lookahead()) {
    case var_kw:
      return variable_decl(spec);
    case def_kw:
      return function_decl(spec);
    case struct_kw:
      return record_decl(spec);
    default:
      // TODO: Is this a recoverable error?
      error("invalid declaration");
  }
}
Exemplo n.º 5
0
// Parse a parameter declaration.
//
//    parameter-decl ::= identifier ':' type
//                     | type
Decl*
Parser::parameter_decl()
{
  // specifier-seq
  Specifier spec = specifier_seq();

  // If we have <token> :, then interpret
  // this as a named parameter.
  if (lookahead(1) == colon_tok) {
    Token n = match(identifier_tok);
    match(colon_tok);
    Type const* t = type();
    return on_parameter(spec, n, t);
  }

  // Otherwise, we probably just have a type.
  else {
    Type const* t = type();
    return on_parameter(spec, t);
  }
}
Exemplo n.º 6
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, ms;
  while (lookahead() != rbrace_tok) {
    Specifier spec = specifier_seq();
    if (lookahead() == def_kw) {
      Decl* m = method_decl(spec);
      ms.push_back(m);
    } else if(lookahead() == identifier_tok) {
      Decl* f = field_decl(spec);
      fs.push_back(f);
    } else {
      throw Syntax_error(ts_.location(), "invalid member declaration");
    }
  }
  match(rbrace_tok);
  return on_record(spec, n, fs, ms);
}