// 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"); }
// 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); }
// 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); }
// 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"); } }
// 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); } }
// 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); }