From 61173dd9fef6b195fd6457f698e10224d170a9e2 Mon Sep 17 00:00:00 2001 From: asoffer Date: Thu, 28 Dec 2023 21:46:10 -0500 Subject: [PATCH] Parsing for interface literals. --- ir/emit.cc | 8 +++++ ir/ir.cc | 10 ++++++ lexer/token_kind.xmacro.h | 1 + parse/node.xmacro.h | 2 ++ parse/parser.cc | 30 ++++++++++++++++++ parse/parser_test.cc | 64 +++++++++++++++++++++++++++++++++++++++ parse/state.xmacro.h | 2 ++ 7 files changed, 117 insertions(+) diff --git a/ir/emit.cc b/ir/emit.cc index f66b46d1..e45c6555 100644 --- a/ir/emit.cc +++ b/ir/emit.cc @@ -590,6 +590,14 @@ void HandleParseTreeNodeEnumLiteral(ParseNodeIndex, EmitContext&) { NTH_UNIMPLEMENTED(); } +void HandleParseTreeNodeInterfaceLiteralStart(ParseNodeIndex, EmitContext&) { + NTH_UNIMPLEMENTED(); +} + +void HandleParseTreeNodeInterfaceLiteral(ParseNodeIndex, EmitContext&) { + NTH_UNIMPLEMENTED(); +} + void HandleParseTreeNodeWhileLoopStart(ParseNodeIndex index, EmitContext& context) { context.queue.front().branches.push_back( diff --git a/ir/ir.cc b/ir/ir.cc index 42c09b55..0eb0fb4a 100644 --- a/ir/ir.cc +++ b/ir/ir.cc @@ -993,6 +993,16 @@ void HandleParseTreeNodeEnumLiteral(ParseNodeIndex, IrContext&, NTH_UNIMPLEMENTED(); } +void HandleParseTreeNodeInterfaceLiteralStart(ParseNodeIndex, IrContext&, + diag::DiagnosticConsumer&) { + NTH_UNIMPLEMENTED(); +} + +void HandleParseTreeNodeInterfaceLiteral(ParseNodeIndex, IrContext&, + diag::DiagnosticConsumer&) { + NTH_UNIMPLEMENTED(); +} + void HandleParseTreeNodeWhileLoopStart(ParseNodeIndex index, IrContext& context, diag::DiagnosticConsumer& diag) {} diff --git a/lexer/token_kind.xmacro.h b/lexer/token_kind.xmacro.h index 2f084706..2c83b74d 100644 --- a/lexer/token_kind.xmacro.h +++ b/lexer/token_kind.xmacro.h @@ -71,6 +71,7 @@ IC_XMACRO_TOKEN_KIND_KEYWORD(While, "while") IC_XMACRO_TOKEN_KIND_KEYWORD(Scope, "scope") IC_XMACRO_TOKEN_KIND_KEYWORD(Return, "return") IC_XMACRO_TOKEN_KIND_KEYWORD(Enum, "enum") +IC_XMACRO_TOKEN_KIND_KEYWORD(Interface, "interface") IC_XMACRO_TOKEN_KIND_TERMINAL_EXPRESSION(True, "true") IC_XMACRO_TOKEN_KIND_TERMINAL_EXPRESSION(False, "false") diff --git a/parse/node.xmacro.h b/parse/node.xmacro.h index fe508bf4..4a23958c 100644 --- a/parse/node.xmacro.h +++ b/parse/node.xmacro.h @@ -72,6 +72,7 @@ IC_XMACRO_PARSE_NODE(IndexArgumentStart) IC_XMACRO_PARSE_NODE(FunctionTypeParameters) IC_XMACRO_PARSE_NODE(FunctionLiteralSignature) IC_XMACRO_PARSE_NODE(FunctionLiteralStart) +IC_XMACRO_PARSE_NODE(InterfaceLiteralStart) IC_XMACRO_PARSE_NODE(NoReturns) IC_XMACRO_PARSE_NODE(Return) IC_XMACRO_PARSE_NODE_DECLARATION(Declaration) @@ -79,6 +80,7 @@ IC_XMACRO_PARSE_NODE_STATEMENT(Statement) IC_XMACRO_PARSE_NODE_STATEMENT(IfStatement) IC_XMACRO_PARSE_NODE_STATEMENT(WhileLoop) IC_XMACRO_PARSE_NODE_EXPRESSION(ScopeLiteral) +IC_XMACRO_PARSE_NODE_EXPRESSION(InterfaceLiteral) IC_XMACRO_PARSE_NODE_EXPRESSION(Identifier) IC_XMACRO_PARSE_NODE_EXPRESSION(ExpressionPrecedenceGroup) IC_XMACRO_PARSE_NODE_EXPRESSION(MemberExpression) diff --git a/parse/parser.cc b/parse/parser.cc index cd0dcfa2..72c5408e 100644 --- a/parse/parser.cc +++ b/parse/parser.cc @@ -425,6 +425,13 @@ void Parser::HandleResolveEnumLiteral(ParseTree& tree) { tree.append(ParseNode::Kind::EnumLiteral, state.token, state.subtree_start); } +void Parser::HandleResolveInterfaceLiteral(ParseTree& tree) { + PopScope(); + auto state = pop_state(); + tree.append(ParseNode::Kind::InterfaceLiteral, state.token, + state.subtree_start); +} + void Parser::HandleWhileLoopBody(ParseTree& tree) { tree.append_leaf(ParseNode::Kind::WhileLoopBodyStart, *iterator_); tree.back().scope_index = PushScope(); @@ -789,6 +796,29 @@ void Parser::HandleAtom(ParseTree& tree) { }); return; } break; + case Token::Kind::Interface: { + tree.append_leaf(ParseNode::Kind::InterfaceLiteralStart, *iterator_++); + tree.back().scope_index = PushScope(); + if (iterator_->kind() != Token::Kind::LeftBracket) { NTH_UNIMPLEMENTED(); } + ++iterator_; + if (iterator_->kind() != Token::Kind::Identifier) { NTH_UNIMPLEMENTED(); } + ++iterator_; + if (iterator_->kind() != Token::Kind::RightBracket) { NTH_UNIMPLEMENTED(); } + ++iterator_; + if (iterator_->kind() != Token::Kind::LeftBrace) { NTH_UNIMPLEMENTED(); } + ExpandState( + State{ + .kind = State::Kind::BracedStatementSequence, + .ambient_precedence = Precedence::Loosest(), + .subtree_start = tree.size(), + }, + State{ + .kind = State::Kind::ResolveInterfaceLiteral, + .ambient_precedence = Precedence::Loosest(), + .subtree_start = tree.size() - 1, + }); + return; + } break; case Token::Kind::Scope: { tree.append_leaf(ParseNode::Kind::ScopeLiteralStart, *iterator_++); tree.back().scope_index = PushScope(); diff --git a/parse/parser_test.cc b/parse/parser_test.cc index 132536ac..f9e89562 100644 --- a/parse/parser_test.cc +++ b/parse/parser_test.cc @@ -1213,4 +1213,68 @@ NTH_TEST("parser/enum/multiple") { DeclaredIdentifier()))))); } +NTH_TEST("parser/interface/empty") { + diag::NullConsumer d; + TokenBuffer buffer = lex::Lex(R"(interface [T] {})", d); + auto tree = Parse(buffer, d).parse_tree; + NTH_EXPECT( + FromRoot(tree) >>= Module( + ModuleStart(), + StatementSequence( + ScopeStart(), + Statement(StatementStart(), + InterfaceLiteral(InterfaceLiteralStart(), + StatementSequence(ScopeStart())))))); +} + +NTH_TEST("parser/interface/declaration") { + diag::NullConsumer d; + TokenBuffer buffer = lex::Lex(R"(interface [T] { + let x ::= T + })", d); + auto tree = Parse(buffer, d).parse_tree; + NTH_EXPECT( + FromRoot(tree) >>= + Module(ModuleStart(), + StatementSequence( + ScopeStart(), + Statement(StatementStart(), + InterfaceLiteral( + InterfaceLiteralStart(), + StatementSequence( + ScopeStart(), + Statement(StatementStart(), + Declaration(DeclarationStart(), + DeclaredIdentifier(), + Identifier())))))))); +} + +NTH_TEST("parser/interface/multiple-declaration") { + diag::NullConsumer d; + TokenBuffer buffer = lex::Lex(R"(interface [T] { + let x ::= T + let y ::= T + })", + d); + auto tree = Parse(buffer, d).parse_tree; + NTH_EXPECT( + FromRoot(tree) >>= + Module(ModuleStart(), + StatementSequence( + ScopeStart(), + Statement(StatementStart(), + InterfaceLiteral( + InterfaceLiteralStart(), + StatementSequence( + ScopeStart(), + Statement(StatementStart(), + Declaration(DeclarationStart(), + DeclaredIdentifier(), + Identifier())), + Statement(StatementStart(), + Declaration(DeclarationStart(), + DeclaredIdentifier(), + Identifier())))))))); +} + } // namespace ic diff --git a/parse/state.xmacro.h b/parse/state.xmacro.h index 5cb85a1e..ab8d9f6d 100644 --- a/parse/state.xmacro.h +++ b/parse/state.xmacro.h @@ -58,6 +58,8 @@ IC_XMACRO_PARSER_STATE(ResolveWhileLoop) IC_XMACRO_PARSER_STATE(ResolveEnumLiteral) +IC_XMACRO_PARSER_STATE(ResolveInterfaceLiteral) + IC_XMACRO_PARSER_STATE(ResolveReturn) IC_XMACRO_PARSER_STATE(Atom)