// Parse a variable declaration. // // variable-declaration: // 'var' identifier ':' [template-header] type ';' // 'var' identifier ':' [template-header] type '=' initializer ';' // 'var' identifier ':' '=' initializer ';' // // TODO: Are there other forms of variable declaration? Decl& Parser::variable_declaration() { // Helper functions. Match_any_token_pred end_type(*this, tk::eq_tok, tk::semicolon_tok); Match_token_pred end_init(*this, tk::semicolon_tok); require(tk::var_tok); Name& name = identifier(); match(tk::colon_tok); // Match the ":=" form. // if (match_if(tk::eq_tok)) { // Type& type = cxt.get_auto_type(object_type); // Expr& init = unparsed_expression(end_init); // match(tk::semicolon_tok); // return on_variable_declaration(name, type, init); // } // Match the type. Type& type = unparsed_type(end_type); // Match the "name : type =" form. if (match_if(tk::eq_tok)) { Expr& init = unparsed_expression(end_init); match(tk::semicolon_tok); return on_variable_declaration(name, type, init); } // Otherwise, match the "name : type ;" form. match(tk::semicolon_tok); return on_variable_declaration(name, type); }
// Parse a class definition. // // class-declaration: // 'class' identifier [':'] class-body // 'class' identifier [':' type] class-body // 'class' identifier [':' extension] class-body // // NOTE: The parser currently allows the omission of the ':' because it // looks weird when the kind is not given explicitly omitted. // // TODO: We could use '=' notation in bodies to create new derived types. Decl& Parser::class_declaration() { Match_token_pred end_kind(*this, lbrace_tok); require(class_tok); Name& name = identifier(); // Match the metatype. Type* kind; if (match_if(colon_tok)) { if (match_if(extension_tok)) return extension_declaration(name, &cxt.get_type_type()); if (next_token_is(lbrace_tok)) kind = &cxt.get_type_type(); else kind = &unparsed_type(end_kind); } else { kind = &cxt.get_type_type(); } // Point of declaration. Decl& decl = start_class_declaration(name, *kind); Enter_scope scope(cxt, cxt.saved_scope(decl)); // Match the class body. Def& def = class_body(); return finish_class_definition(decl, def); };
// Parse a base class (super) declaration. // // super-declaration: // super [identifier] : type; Decl& Parser::super_declaration() { Match_token_pred end_type(*this, tk::semicolon_tok); require(tk::super_tok); // Match the optional identifier. Name* name; if (next_token_is(tk::identifier_tok)) name = &identifier(); else name = &build.get_id(); // Match type type. match(tk::colon_tok); Type& type = unparsed_type(end_type); match(tk::semicolon_tok); return on_super_declaration(*name, type); }