diff --git a/include/bolt/CST.hpp b/include/bolt/CST.hpp index 57e3283f7..7df9c3292 100644 --- a/include/bolt/CST.hpp +++ b/include/bolt/CST.hpp @@ -24,7 +24,6 @@ class SourceFile; class Scope; class Pattern; class Expression; -class Statement; class TextLoc { public: @@ -168,10 +167,9 @@ enum class NodeKind { PrefixExpression, RecordExpressionField, RecordExpression, - ExpressionStatement, - ReturnStatement, - IfStatement, - IfStatementPart, + ReturnExpression, + IfExpression, + IfExpressionPart, TypeAssert, Parameter, LetBlockBody, @@ -214,7 +212,7 @@ class Node { unsigned RefCount = 1; - const NodeKind Kind; + const NodeKind K; public: @@ -238,24 +236,13 @@ public: virtual std::size_t getEndColumn() const; inline NodeKind getKind() const noexcept { - return Kind; - } - - template - bool is() const noexcept { - return _is_helper(this); - } - - template - T* as() { - ZEN_ASSERT(is()); - return static_cast(this); + return K; } virtual TextRange getRange() const; inline Node(NodeKind Type): - Kind(Type) {} + K(Type) {} const SourceFile* getSourceFile() const; SourceFile* getSourceFile(); @@ -266,21 +253,6 @@ public: }; -template -bool _is_helper(const Node* N) noexcept { - return N->getKind() == getNodeType(); -} - -template<> -inline bool _is_helper(const Node* N) noexcept { - return N->getKind() == NodeKind::ReferenceExpression - || N->getKind() == NodeKind::LiteralExpression - || N->getKind() == NodeKind::PrefixExpression - || N->getKind() == NodeKind::InfixExpression - || N->getKind() == NodeKind::CallExpression - || N->getKind() == NodeKind::NestedExpression; -} - enum class SymbolKind { Var, Class, @@ -380,9 +352,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Equals; - } + static constexpr NodeKind Kind = NodeKind::Equals; }; @@ -394,9 +364,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::VBar; - } + static constexpr const NodeKind Kind = NodeKind::VBar; }; @@ -408,9 +376,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Colon; - } + static constexpr const NodeKind Kind = NodeKind::Colon; }; @@ -422,9 +388,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Comma; - } + static constexpr const NodeKind Kind = NodeKind::Comma; }; @@ -436,9 +400,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Dot; - } + static constexpr const NodeKind Kind = NodeKind::Dot; }; @@ -450,9 +412,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::DotDot; - } + static constexpr const NodeKind Kind = NodeKind::DotDot; }; @@ -464,9 +424,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Tilde; - } + static constexpr const NodeKind Kind = NodeKind::Tilde; }; @@ -478,9 +436,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::At; - } + static constexpr const NodeKind Kind = NodeKind::At; }; @@ -492,9 +448,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::DoKeyword; - } + static constexpr const NodeKind Kind = NodeKind::DoKeyword; }; @@ -506,9 +460,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::LParen; - } + static constexpr const NodeKind Kind = NodeKind::LParen; }; @@ -520,9 +472,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::RParen; - } + static constexpr const NodeKind Kind = NodeKind::RParen; }; @@ -534,9 +484,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::LBracket; - } + static constexpr const NodeKind Kind = NodeKind::LBracket; }; @@ -548,9 +496,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::RBracket; - } + static constexpr const NodeKind Kind = NodeKind::RBracket; }; @@ -562,9 +508,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::LBrace; - } + static constexpr const NodeKind Kind = NodeKind::LBrace; }; @@ -576,9 +520,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::RBrace; - } + static constexpr const NodeKind Kind = NodeKind::RBrace; }; @@ -590,9 +532,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::RArrow; - } + static constexpr const NodeKind Kind = NodeKind::RArrow; }; @@ -604,9 +544,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::RArrowAlt; - } + static constexpr const NodeKind Kind = NodeKind::RArrowAlt; }; @@ -618,9 +556,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::LetKeyword; - } + static constexpr const NodeKind Kind = NodeKind::LetKeyword; }; @@ -632,9 +568,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::MutKeyword; - } + static constexpr const NodeKind Kind = NodeKind::MutKeyword; }; @@ -646,9 +580,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::PubKeyword; - } + static constexpr const NodeKind Kind = NodeKind::PubKeyword; }; @@ -660,9 +592,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::ForeignKeyword; - } + static constexpr const NodeKind Kind = NodeKind::ForeignKeyword; }; @@ -674,9 +604,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::TypeKeyword; - } + static constexpr const NodeKind Kind = NodeKind::TypeKeyword; }; @@ -688,9 +616,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::ReturnKeyword; - } + static constexpr const NodeKind Kind = NodeKind::ReturnKeyword; }; @@ -702,9 +628,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::ModKeyword; - } + static constexpr const NodeKind Kind = NodeKind::ModKeyword; }; @@ -716,9 +640,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::StructKeyword; - } + static constexpr const NodeKind Kind = NodeKind::StructKeyword; }; @@ -730,9 +652,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::EnumKeyword; - } + static constexpr const NodeKind Kind = NodeKind::EnumKeyword; }; @@ -744,9 +664,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::ClassKeyword; - } + static constexpr const NodeKind Kind = NodeKind::ClassKeyword; }; @@ -758,9 +676,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::InstanceKeyword; - } + static constexpr const NodeKind Kind = NodeKind::InstanceKeyword; }; @@ -772,9 +688,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::ElifKeyword; - } + static constexpr const NodeKind Kind = NodeKind::ElifKeyword; }; @@ -786,9 +700,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::IfKeyword; - } + static constexpr const NodeKind Kind = NodeKind::IfKeyword; }; @@ -800,9 +712,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::ElseKeyword; - } + static constexpr const NodeKind Kind = NodeKind::ElseKeyword; }; @@ -814,9 +724,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::MatchKeyword; - } + static constexpr const NodeKind Kind = NodeKind::MatchKeyword; }; @@ -828,9 +736,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Invalid; - } + static constexpr const NodeKind Kind = NodeKind::Invalid; }; @@ -842,9 +748,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::EndOfFile; - } + static constexpr const NodeKind Kind = NodeKind::EndOfFile; }; @@ -856,9 +760,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::BlockStart; - } + static constexpr const NodeKind Kind = NodeKind::BlockStart; }; @@ -870,9 +772,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::BlockEnd; - } + static constexpr const NodeKind Kind = NodeKind::BlockEnd; }; @@ -884,9 +784,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::LineFoldEnd; - } + static constexpr const NodeKind Kind = NodeKind::LineFoldEnd; }; @@ -902,9 +800,7 @@ public: std::string getCanonicalText() const; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::CustomOperator; - } + static constexpr const NodeKind Kind = NodeKind::CustomOperator; }; @@ -918,9 +814,7 @@ public: std::string getText() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Assignment; - } + static constexpr const NodeKind Kind = NodeKind::Assignment; }; @@ -938,9 +832,7 @@ public: bool isTypeVar() const; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Identifier; - } + static constexpr const NodeKind Kind = NodeKind::Identifier; }; @@ -956,9 +848,7 @@ public: ByteString getCanonicalText() const; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::IdentifierAlt; - } + static constexpr const NodeKind Kind = NodeKind::IdentifierAlt; }; @@ -991,9 +881,7 @@ public: LiteralValue getValue() override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::StringLiteral; - } + static constexpr const NodeKind Kind = NodeKind::StringLiteral; }; @@ -1018,9 +906,7 @@ public: LiteralValue getValue() override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::IntegerLiteral; - } + static constexpr const NodeKind Kind = NodeKind::IntegerLiteral; }; @@ -1082,7 +968,7 @@ public: Token* getFirstToken() const; Token* getLastToken() const; - inline static bool classof(const Node* N) { + static bool classof(const Node* N) { return N->getKind() == NodeKind::VBar || N->getKind() == NodeKind::CustomOperator; } @@ -1115,9 +1001,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::WrappedOperator; - } + static constexpr const NodeKind Kind = NodeKind::WrappedOperator; }; @@ -1241,6 +1125,8 @@ public: return Expression; } + static constexpr const NodeKind Kind = NodeKind::ExpressionAnnotation; + }; class TypeExpression; @@ -1268,6 +1154,8 @@ public: return TE; } + static constexpr const NodeKind Kind = NodeKind::TypeAssertAnnotation; + }; class TypedNode : public Node { @@ -1289,7 +1177,7 @@ public: return Ty; } - static bool classof(Node* N); + static bool classof(const Node* N); }; @@ -1301,7 +1189,7 @@ protected: public: - static bool classof(Node* N) { + static bool classof(const Node* N) { return N->getKind() == NodeKind::ReferenceTypeExpression || N->getKind() == NodeKind::AppTypeExpression || N->getKind() == NodeKind::NestedTypeExpression @@ -1341,6 +1229,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordTypeExpressionField; + }; class RecordTypeExpression : public TypeExpression { @@ -1368,6 +1258,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordTypeExpression; + }; class VarTypeExpression; @@ -1388,9 +1280,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::TypeclassConstraintExpression; - } + static constexpr const NodeKind Kind = NodeKind::TypeclassConstraintExpression; }; @@ -1413,9 +1303,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::EqualityConstraintExpression; - } + static constexpr const NodeKind Kind = NodeKind::EqualityConstraintExpression; }; @@ -1438,9 +1326,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::QualifiedTypeExpression; - } + static constexpr const NodeKind Kind = NodeKind::QualifiedTypeExpression; }; @@ -1462,6 +1348,8 @@ public: SymbolPath getSymbolPath() const; + static constexpr const NodeKind Kind = NodeKind::ReferenceTypeExpression; + }; class ArrowTypeExpression : public TypeExpression { @@ -1480,6 +1368,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::ArrowTypeExpression; + }; class AppTypeExpression : public TypeExpression { @@ -1498,6 +1388,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::AppTypeExpression; + }; class VarTypeExpression : public TypeExpression { @@ -1511,6 +1403,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::VarTypeExpression; + }; class NestedTypeExpression : public TypeExpression { @@ -1532,6 +1426,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::NestedTypeExpression; + }; class TupleTypeExpression : public TypeExpression { @@ -1553,6 +1449,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::TupleTypeExpression; + }; @@ -1562,6 +1460,17 @@ protected: inline Pattern(NodeKind Type): Node(Type) {} + static bool classof(const Node* N) { + return N->getKind() == NodeKind::BindPattern + || N->getKind() == NodeKind::ListPattern + || N->getKind() == NodeKind::LiteralPattern + || N->getKind() == NodeKind::NamedRecordPattern + || N->getKind() == NodeKind::NamedTuplePattern + || N->getKind() == NodeKind::NestedPattern + || N->getKind() == NodeKind::RecordPattern + || N->getKind() == NodeKind::TuplePattern; + } + }; class BindPattern : public Pattern { @@ -1577,9 +1486,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::BindPattern; - } + static constexpr const NodeKind Kind = NodeKind::BindPattern; }; @@ -1595,9 +1502,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::LiteralPattern; - } + static constexpr const NodeKind Kind = NodeKind::LiteralPattern; }; @@ -1642,6 +1547,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordPatternField; + }; class RecordPattern : public Pattern { @@ -1663,6 +1570,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordPattern; + }; class NamedRecordPattern : public Pattern { @@ -1690,6 +1599,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::NamedRecordPattern; + }; class NamedTuplePattern : public Pattern { @@ -1708,6 +1619,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::NamedTuplePattern; + }; class TuplePattern : public Pattern { @@ -1729,6 +1642,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::TuplePattern; + }; class NestedPattern : public Pattern { @@ -1750,6 +1665,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::NestedPattern; + }; class ListPattern : public Pattern { @@ -1771,6 +1688,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::ListPattern; + }; class Expression : public TypedNode, public AnnotationContainer { @@ -1781,7 +1700,7 @@ protected: public: - static bool classof(Node* N) { + static bool classof(const Node* N) { return N->getKind() == NodeKind::ReferenceExpression || N->getKind() == NodeKind::NestedExpression || N->getKind() == NodeKind::CallExpression @@ -1792,6 +1711,9 @@ public: || N->getKind() == NodeKind::BlockExpression || N->getKind() == NodeKind::MemberExpression || N->getKind() == NodeKind::LiteralExpression + || N->getKind() == NodeKind::BlockExpression + || N->getKind() == NodeKind::IfExpression + || N->getKind() == NodeKind::ReturnExpression || N->getKind() == NodeKind::PrefixExpression; } @@ -1803,13 +1725,6 @@ public: std::vector> ModulePath; Symbol Name; - inline ReferenceExpression( - std::vector> ModulePath, - Symbol Name - ): Expression(NodeKind::ReferenceExpression), - ModulePath(ModulePath), - Name(Name) {} - inline ReferenceExpression( std::vector Annotations, std::vector> ModulePath, @@ -1818,6 +1733,11 @@ public: ModulePath(ModulePath), Name(Name) {} + inline ReferenceExpression( + std::vector> ModulePath, + Symbol Name + ): ReferenceExpression({}, ModulePath, Name) {} + inline ByteString getNameAsString() const noexcept { return Name.getCanonicalText(); } @@ -1827,6 +1747,8 @@ public: SymbolPath getSymbolPath() const; + static constexpr const NodeKind Kind = NodeKind::ReferenceExpression; + }; class MatchCase : public Node { @@ -1858,6 +1780,7 @@ public: return TheScope; } + static constexpr const NodeKind Kind = NodeKind::MatchCase; }; @@ -1868,18 +1791,7 @@ public: Expression* Value; class BlockStart* BlockStart; std::vector Cases; - - inline MatchExpression( - class MatchKeyword* MatchKeyword, - Expression* Value, - class BlockStart* BlockStart, - std::vector Cases - ): Expression(NodeKind::MatchExpression), - MatchKeyword(MatchKeyword), - Value(Value), - BlockStart(BlockStart), - Cases(Cases) {} - + inline MatchExpression( std::vector Annotations, class MatchKeyword* MatchKeyword, @@ -1892,9 +1804,18 @@ public: BlockStart(BlockStart), Cases(Cases) {} + inline MatchExpression( + class MatchKeyword* MatchKeyword, + Expression* Value, + class BlockStart* BlockStart, + std::vector Cases + ): MatchExpression({}, MatchKeyword, Value, BlockStart, Cases) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::MatchExpression; + }; class BlockExpression : public Expression { @@ -1904,15 +1825,6 @@ public: class BlockStart* BlockStart; std::vector Elements; - inline BlockExpression( - class DoKeyword* DoKeyword, - class BlockStart* BlockStart, - std::vector Elements - ): Expression(NodeKind::BlockExpression), - DoKeyword(DoKeyword), - BlockStart(BlockStart), - Elements(Elements) {} - inline BlockExpression( std::vector Annotations, class DoKeyword* DoKeyword, @@ -1923,9 +1835,17 @@ public: BlockStart(BlockStart), Elements(Elements) {} + inline BlockExpression( + class DoKeyword* DoKeyword, + class BlockStart* BlockStart, + std::vector Elements + ): BlockExpression({}, DoKeyword, BlockStart, Elements) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::BlockExpression; + }; class MemberExpression : public Expression { @@ -1935,15 +1855,6 @@ public: class Dot* Dot; Token* Name; - inline MemberExpression( - Expression* E, - class Dot* Dot, - Token* Name - ): Expression(NodeKind::MemberExpression), - E(E), - Dot(Dot), - Name(Name) {} - inline MemberExpression( std::vector Annotations, class Expression* E, @@ -1954,6 +1865,12 @@ public: Dot(Dot), Name(Name) {} + inline MemberExpression( + Expression* E, + class Dot* Dot, + Token* Name + ): MemberExpression({}, E, Dot, Name) {} + Token* getFirstToken() const override; Token* getLastToken() const override; @@ -1961,6 +1878,8 @@ public: return E; } + static constexpr const NodeKind Kind = NodeKind::MemberExpression; + }; class TupleExpression : public Expression { @@ -1970,15 +1889,6 @@ public: std::vector> Elements; class RParen* RParen; - inline TupleExpression( - class LParen* LParen, - std::vector> Elements, - class RParen* RParen - ): Expression(NodeKind::TupleExpression), - LParen(LParen), - Elements(Elements), - RParen(RParen) {} - inline TupleExpression( std::vector Annotations, class LParen* LParen, @@ -1989,9 +1899,17 @@ public: Elements(Elements), RParen(RParen) {} + inline TupleExpression( + class LParen* LParen, + std::vector> Elements, + class RParen* RParen + ): TupleExpression({}, LParen, Elements, RParen) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::TupleExpression; + }; class NestedExpression : public Expression { @@ -2001,15 +1919,6 @@ public: Expression* Inner; class RParen* RParen; - inline NestedExpression( - class LParen* LParen, - Expression* Inner, - class RParen* RParen - ): Expression(NodeKind::NestedExpression), - LParen(LParen), - Inner(Inner), - RParen(RParen) {} - inline NestedExpression( std::vector Annotations, class LParen* LParen, @@ -2020,9 +1929,18 @@ public: Inner(Inner), RParen(RParen) {} + + inline NestedExpression( + class LParen* LParen, + Expression* Inner, + class RParen* RParen + ): NestedExpression({}, LParen, Inner, RParen) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::NestedExpression; + }; class LiteralExpression : public Expression { @@ -2030,17 +1948,15 @@ public: Literal* Token; - LiteralExpression( - Literal* Token - ): Expression(NodeKind::LiteralExpression), - Token(Token) {} - - LiteralExpression( + inline LiteralExpression( std::vector Annotations, Literal* Token ): Expression(NodeKind::LiteralExpression, Annotations), Token(Token) {} + inline LiteralExpression(Literal* Token): + LiteralExpression({}, Token) {} + inline ByteString getAsText() { ZEN_ASSERT(Token->getKind() == NodeKind::StringLiteral); return static_cast(Token)->Text; @@ -2054,6 +1970,8 @@ public: class Token* getFirstToken() const override; class Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::LiteralExpression; + }; class CallExpression : public Expression { @@ -2062,13 +1980,6 @@ public: Expression* Function; std::vector Args; - inline CallExpression( - Expression* Function, - std::vector Args - ): Expression(NodeKind::CallExpression), - Function(Function), - Args(Args) {} - inline CallExpression( std::vector Annotations, Expression* Function, @@ -2077,9 +1988,16 @@ public: Function(Function), Args(Args) {} + inline CallExpression( + Expression* Function, + std::vector Args + ): CallExpression({}, Function, Args) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::CallExpression; + }; class InfixExpression : public Expression { @@ -2089,15 +2007,6 @@ public: Operator Operator; Expression* Right; - inline InfixExpression( - Expression* Left, - class Operator Operator, - Expression* Right - ): Expression(NodeKind::InfixExpression), - Left(Left), - Operator(Operator), - Right(Right) {} - inline InfixExpression( std::vector Annotations, Expression* Left, @@ -2108,9 +2017,17 @@ public: Operator(Operator), Right(Right) {} + inline InfixExpression( + Expression* Left, + class Operator Operator, + Expression* Right + ): InfixExpression({}, Left, Operator, Right) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::InfixExpression; + }; class PrefixExpression : public Expression { @@ -2119,14 +2036,7 @@ public: Token* Operator; Expression* Argument; - PrefixExpression( - Token* Operator, - Expression* Argument - ): Expression(NodeKind::PrefixExpression), - Operator(Operator), - Argument(Argument) {} - - PrefixExpression( + inline PrefixExpression( std::vector Annotations, Token* Operator, Expression* Argument @@ -2134,9 +2044,16 @@ public: Operator(Operator), Argument(Argument) {} + inline PrefixExpression( + Token* Operator, + Expression* Argument + ): PrefixExpression({}, Operator, Argument) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::PrefixExpression; + }; class RecordExpressionField : public Node { @@ -2158,10 +2075,17 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + bool hasExpression() const { + return E; + } + inline Expression* getExpression() const { + ZEN_ASSERT(E != nullptr); return E; } + static constexpr const NodeKind Kind = NodeKind::RecordExpressionField; + }; class RecordExpression : public Expression { @@ -2171,15 +2095,6 @@ public: std::vector> Fields; class RBrace* RBrace; - inline RecordExpression( - class LBrace* LBrace, - std::vector> Fields, - class RBrace* RBrace - ): Expression(NodeKind::RecordExpression), - LBrace(LBrace), - Fields(Fields), - RBrace(RBrace) {} - inline RecordExpression( std::vector Annotations, class LBrace* LBrace, @@ -2190,47 +2105,20 @@ public: Fields(Fields), RBrace(RBrace) {} - Token* getFirstToken() const override; - Token* getLastToken() const override; - -}; - -class Statement : public Node, public AnnotationContainer { -protected: - - inline Statement(NodeKind Type, std::vector Annotations = {}): - Node(Type), AnnotationContainer(Annotations) {} - -public: - - static bool classof(Node* N) { - return N->getKind() == NodeKind::ExpressionStatement - || N->getKind() == NodeKind::ReturnStatement - || N->getKind() == NodeKind::IfStatement; - } - -}; - -class ExpressionStatement : public Statement { -public: - - class Expression* Expression; - - ExpressionStatement(class Expression* Expression): - Statement(NodeKind::ExpressionStatement), Expression(Expression) {} - - ExpressionStatement( - std::vector Annotations, - class Expression* Expression - ): Statement(NodeKind::ExpressionStatement, Annotations), - Expression(Expression) {} + inline RecordExpression( + class LBrace* LBrace, + std::vector> Fields, + class RBrace* RBrace + ): RecordExpression({}, LBrace, Fields, RBrace) {} Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordExpression; + }; -class IfStatementPart : public Node, public AnnotationContainer { +class IfExpressionPart : public Node, public AnnotationContainer { public: Token* Keyword; @@ -2238,68 +2126,73 @@ public: class BlockStart* BlockStart; std::vector Elements; - inline IfStatementPart( - Token* Keyword, - Expression* Test, - class BlockStart* BlockStart, - std::vector Elements - ): Node(NodeKind::IfStatementPart), - Keyword(Keyword), - Test(Test), - BlockStart(BlockStart), - Elements(Elements) {} - - inline IfStatementPart( + inline IfExpressionPart( std::vector Annotations, Token* Keyword, Expression* Test, class BlockStart* BlockStart, std::vector Elements - ): Node(NodeKind::IfStatementPart), + ): Node(NodeKind::IfExpressionPart), AnnotationContainer(Annotations), Keyword(Keyword), Test(Test), BlockStart(BlockStart), Elements(Elements) {} + inline IfExpressionPart( + Token* Keyword, + Expression* Test, + class BlockStart* BlockStart, + std::vector Elements + ): IfExpressionPart({}, Keyword, Test, BlockStart, Elements) {} + Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::IfExpressionPart; + }; -class IfStatement : public Statement { +class IfExpression : public Expression { public: - std::vector Parts; + std::vector Parts; - inline IfStatement(std::vector Parts): - Statement(NodeKind::IfStatement), Parts(Parts) {} + inline IfExpression( + std::vector Annotations, + std::vector Parts + ): Expression(NodeKind::IfExpression, Annotations), + Parts(Parts) {} + + + inline IfExpression(std::vector Parts): + IfExpression({}, Parts) {} Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::IfExpression; + }; -class ReturnStatement : public Statement { +class ReturnExpression : public Expression { public: class ReturnKeyword* ReturnKeyword; Expression* E; - ReturnStatement( - class ReturnKeyword* ReturnKeyword, - class Expression* Expression - ): Statement(NodeKind::ReturnStatement), - ReturnKeyword(ReturnKeyword), - E(Expression) {} - - ReturnStatement( + inline ReturnExpression( std::vector Annotations, class ReturnKeyword* ReturnKeyword, - class Expression* Expression - ): Statement(NodeKind::ReturnStatement, Annotations), + Expression* E + ): Expression(NodeKind::ReturnExpression, Annotations), ReturnKeyword(ReturnKeyword), - E(Expression) {} + E(E) {} + + inline ReturnExpression( + class ReturnKeyword* ReturnKeyword, + class Expression* Expression + ): ReturnExpression({}, ReturnKeyword, Expression) {} Token* getFirstToken() const override; Token* getLastToken() const override; @@ -2312,6 +2205,8 @@ public: return E; } + static constexpr const NodeKind Kind = NodeKind::ReturnExpression; + }; class TypeAssert : public Node { @@ -2330,6 +2225,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::TypeAssert; + }; class Parameter : public Node { @@ -2348,9 +2245,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::Parameter; - } + static constexpr const NodeKind Kind = NodeKind::Parameter; }; @@ -2377,6 +2272,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::LetBlockBody; + }; class LetExprBody : public LetBody { @@ -2395,6 +2292,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::LetExprBody; + }; class Declaration : public TypedNode, public AnnotationContainer { @@ -2546,9 +2445,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::PrefixFunctionDeclaration; - } + static constexpr const NodeKind Kind = NodeKind::PrefixFunctionDeclaration; }; @@ -2608,9 +2505,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::SuffixFunctionDeclaration; - } + static constexpr const NodeKind Kind = NodeKind::SuffixFunctionDeclaration; }; @@ -2673,9 +2568,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::InfixFunctionDeclaration; - } + static constexpr const NodeKind Kind = NodeKind::InfixFunctionDeclaration; }; @@ -2734,9 +2627,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::NamedFunctionDeclaration; - } + static constexpr const NodeKind Kind = NodeKind::NamedFunctionDeclaration; }; @@ -2782,10 +2673,6 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::VariableDeclaration; - } - bool hasExpression() const { return Body; } @@ -2795,6 +2682,8 @@ public: return static_cast(Body)->Expression; } + static constexpr const NodeKind Kind = NodeKind::VariableDeclaration; + }; class InstanceDeclaration : public Node { @@ -2822,9 +2711,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::InstanceDeclaration; - } + static constexpr const NodeKind Kind = NodeKind::InstanceDeclaration; }; @@ -2856,9 +2743,7 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; - static bool classof(const Node* N) { - return N->getKind() == NodeKind::ClassDeclaration; - } + static constexpr const NodeKind Kind = NodeKind::ClassDeclaration; }; @@ -2881,6 +2766,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordDeclarationField; + }; class RecordDeclaration : public Declaration { @@ -2911,6 +2798,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordDeclaration; + }; class VariantDeclarationMember : public Node { @@ -2937,6 +2826,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::TupleVariantDeclarationMember; + }; class RecordVariantDeclarationMember : public VariantDeclarationMember { @@ -2958,6 +2849,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::RecordVariantDeclarationMember; + }; class VariantDeclaration : public Declaration { @@ -2988,6 +2881,8 @@ public: Token* getFirstToken() const override; Token* getLastToken() const override; + static constexpr const NodeKind Kind = NodeKind::VariantDeclaration; + }; class SourceFile : public Node { @@ -3021,79 +2916,78 @@ public: return TheScope; } - static bool classof(const Node* N) { - return N->getKind() == NodeKind::SourceFile; - } + static constexpr const NodeKind Kind = NodeKind::SourceFile; }; -template<> inline NodeKind getNodeType() { return NodeKind::Equals; } -template<> inline NodeKind getNodeType() { return NodeKind::Colon; } -template<> inline NodeKind getNodeType() { return NodeKind::Dot; } -template<> inline NodeKind getNodeType() { return NodeKind::DotDot; } -template<> inline NodeKind getNodeType() { return NodeKind::Tilde; } -template<> inline NodeKind getNodeType() { return NodeKind::LParen; } -template<> inline NodeKind getNodeType() { return NodeKind::RParen; } -template<> inline NodeKind getNodeType() { return NodeKind::LBracket; } -template<> inline NodeKind getNodeType() { return NodeKind::RBracket; } -template<> inline NodeKind getNodeType() { return NodeKind::LBrace; } -template<> inline NodeKind getNodeType() { return NodeKind::RBrace; } -template<> inline NodeKind getNodeType() { return NodeKind::RArrow; } -template<> inline NodeKind getNodeType() { return NodeKind::RArrowAlt; } -template<> inline NodeKind getNodeType() { return NodeKind::LetKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::ForeignKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::MutKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::PubKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::TypeKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::ReturnKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::ModKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::StructKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::EnumKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::ClassKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::InstanceKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::ElifKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::IfKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::MatchKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::ElseKeyword; } -template<> inline NodeKind getNodeType() { return NodeKind::Invalid; } -template<> inline NodeKind getNodeType() { return NodeKind::EndOfFile; } -template<> inline NodeKind getNodeType() { return NodeKind::BlockStart; } -template<> inline NodeKind getNodeType() { return NodeKind::BlockEnd; } -template<> inline NodeKind getNodeType() { return NodeKind::LineFoldEnd; } -template<> inline NodeKind getNodeType() { return NodeKind::CustomOperator; } -template<> inline NodeKind getNodeType() { return NodeKind::Assignment; } -template<> inline NodeKind getNodeType() { return NodeKind::Identifier; } -template<> inline NodeKind getNodeType() { return NodeKind::IdentifierAlt; } -template<> inline NodeKind getNodeType() { return NodeKind::StringLiteral; } -template<> inline NodeKind getNodeType() { return NodeKind::IntegerLiteral; } -template<> inline NodeKind getNodeType() { return NodeKind::QualifiedTypeExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::ReferenceTypeExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::ArrowTypeExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::BindPattern; } -template<> inline NodeKind getNodeType() { return NodeKind::ReferenceExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::NestedExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::LiteralExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::CallExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::InfixExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::PrefixExpression; } -template<> inline NodeKind getNodeType() { return NodeKind::ExpressionStatement; } -template<> inline NodeKind getNodeType() { return NodeKind::ReturnStatement; } -template<> inline NodeKind getNodeType() { return NodeKind::IfStatement; } -template<> inline NodeKind getNodeType() { return NodeKind::IfStatementPart; } -template<> inline NodeKind getNodeType() { return NodeKind::TypeAssert; } -template<> inline NodeKind getNodeType() { return NodeKind::Parameter; } -template<> inline NodeKind getNodeType() { return NodeKind::LetBlockBody; } -template<> inline NodeKind getNodeType() { return NodeKind::LetExprBody; } -template<> inline NodeKind getNodeType() { return NodeKind::PrefixFunctionDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::InfixFunctionDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::SuffixFunctionDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::NamedFunctionDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::VariableDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::RecordDeclarationField; } -template<> inline NodeKind getNodeType() { return NodeKind::RecordDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::ClassDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::InstanceDeclaration; } -template<> inline NodeKind getNodeType() { return NodeKind::SourceFile; } +// template<> inline NodeKind getNodeType() { return NodeKind::Equals; } +// template<> inline NodeKind getNodeType() { return NodeKind::Colon; } +// template<> inline NodeKind getNodeType() { return NodeKind::Dot; } +// template<> inline NodeKind getNodeType() { return NodeKind::DotDot; } +// template<> inline NodeKind getNodeType() { return NodeKind::Tilde; } +// template<> inline NodeKind getNodeType() { return NodeKind::LParen; } +// template<> inline NodeKind getNodeType() { return NodeKind::RParen; } +// template<> inline NodeKind getNodeType() { return NodeKind::LBracket; } +// template<> inline NodeKind getNodeType() { return NodeKind::RBracket; } +// template<> inline NodeKind getNodeType() { return NodeKind::LBrace; } +// template<> inline NodeKind getNodeType() { return NodeKind::RBrace; } +// template<> inline NodeKind getNodeType() { return NodeKind::RArrow; } +// template<> inline NodeKind getNodeType() { return NodeKind::RArrowAlt; } +// template<> inline NodeKind getNodeType() { return NodeKind::LetKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::ForeignKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::MutKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::PubKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::TypeKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::ReturnKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::ModKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::StructKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::EnumKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::ClassKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::InstanceKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::ElifKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::IfKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::MatchKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::ElseKeyword; } +// template<> inline NodeKind getNodeType() { return NodeKind::Invalid; } +// template<> inline NodeKind getNodeType() { return NodeKind::EndOfFile; } +// template<> inline NodeKind getNodeType() { return NodeKind::BlockStart; } +// template<> inline NodeKind getNodeType() { return NodeKind::BlockEnd; } +// template<> inline NodeKind getNodeType() { return NodeKind::LineFoldEnd; } +// template<> inline NodeKind getNodeType() { return NodeKind::CustomOperator; } +// template<> inline NodeKind getNodeType() { return NodeKind::Assignment; } +// template<> inline NodeKind getNodeType() { return NodeKind::Identifier; } +// template<> inline NodeKind getNodeType() { return NodeKind::IdentifierAlt; } +// template<> inline NodeKind getNodeType() { return NodeKind::StringLiteral; } +// template<> inline NodeKind getNodeType() { return NodeKind::IntegerLiteral; } +// template<> inline NodeKind getNodeType() { return NodeKind::QualifiedTypeExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::ReferenceTypeExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::ArrowTypeExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::BindPattern; } +// template<> inline NodeKind getNodeType() { return NodeKind::ReferenceExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::NestedExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::MatchExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::BlockExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::LiteralExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::CallExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::InfixExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::PrefixExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::ReturnExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::IfExpression; } +// template<> inline NodeKind getNodeType() { return NodeKind::IfExpressionPart; } +// template<> inline NodeKind getNodeType() { return NodeKind::TypeAssert; } +// template<> inline NodeKind getNodeType() { return NodeKind::Parameter; } +// template<> inline NodeKind getNodeType() { return NodeKind::LetBlockBody; } +// template<> inline NodeKind getNodeType() { return NodeKind::LetExprBody; } +// template<> inline NodeKind getNodeType() { return NodeKind::PrefixFunctionDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::InfixFunctionDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::SuffixFunctionDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::NamedFunctionDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::VariableDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::RecordDeclarationField; } +// template<> inline NodeKind getNodeType() { return NodeKind::RecordDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::ClassDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::InstanceDeclaration; } +// template<> inline NodeKind getNodeType() { return NodeKind::SourceFile; } } diff --git a/include/bolt/CSTVisitor.hpp b/include/bolt/CSTVisitor.hpp index f7c16bbea..8fcfe9bc5 100644 --- a/include/bolt/CSTVisitor.hpp +++ b/include/bolt/CSTVisitor.hpp @@ -99,10 +99,9 @@ public: BOLT_GEN_CASE(PrefixExpression) BOLT_GEN_CASE(RecordExpressionField) BOLT_GEN_CASE(RecordExpression) - BOLT_GEN_CASE(ExpressionStatement) - BOLT_GEN_CASE(ReturnStatement) - BOLT_GEN_CASE(IfStatement) - BOLT_GEN_CASE(IfStatementPart) + BOLT_GEN_CASE(ReturnExpression) + BOLT_GEN_CASE(IfExpression) + BOLT_GEN_CASE(IfExpressionPart) BOLT_GEN_CASE(TypeAssert) BOLT_GEN_CASE(Parameter) BOLT_GEN_CASE(LetBlockBody) @@ -498,23 +497,15 @@ protected: static_cast(this)->visitExpression(N); } - void visitStatement(Statement* N) { - static_cast(this)->visitNode(N); + void visitReturnExpression(ReturnExpression* N) { + static_cast(this)->visitExpression(N); } - void visitExpressionStatement(ExpressionStatement* N) { - static_cast(this)->visitStatement(N); + void visitIfExpression(IfExpression* N) { + static_cast(this)->visitExpression(N); } - void visitReturnStatement(ReturnStatement* N) { - static_cast(this)->visitStatement(N); - } - - void visitIfStatement(IfStatement* N) { - static_cast(this)->visitStatement(N); - } - - void visitIfStatementPart(IfStatementPart* N) { + void visitIfExpressionPart(IfExpressionPart* N) { static_cast(this)->visitNode(N); } @@ -687,10 +678,9 @@ public: BOLT_GEN_CHILD_CASE(PrefixExpression) BOLT_GEN_CHILD_CASE(RecordExpressionField) BOLT_GEN_CHILD_CASE(RecordExpression) - BOLT_GEN_CHILD_CASE(ExpressionStatement) - BOLT_GEN_CHILD_CASE(ReturnStatement) - BOLT_GEN_CHILD_CASE(IfStatement) - BOLT_GEN_CHILD_CASE(IfStatementPart) + BOLT_GEN_CHILD_CASE(ReturnExpression) + BOLT_GEN_CHILD_CASE(IfExpression) + BOLT_GEN_CHILD_CASE(IfExpressionPart) BOLT_GEN_CHILD_CASE(TypeAssert) BOLT_GEN_CHILD_CASE(Parameter) BOLT_GEN_CHILD_CASE(LetBlockBody) @@ -1163,14 +1153,7 @@ public: BOLT_VISIT(N->RBrace); } - void visitEachChild(ExpressionStatement* N) { - for (auto A: N->Annotations) { - BOLT_VISIT(A); - } - BOLT_VISIT(N->Expression); - } - - void visitEachChild(ReturnStatement* N) { + void visitEachChild(ReturnExpression* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } @@ -1178,13 +1161,13 @@ public: BOLT_VISIT(N->E); } - void visitEachChild(IfStatement* N) { + void visitEachChild(IfExpression* N) { for (auto Part: N->Parts) { BOLT_VISIT(Part); } } - void visitEachChild(IfStatementPart* N) { + void visitEachChild(IfExpressionPart* N) { for (auto A: N->Annotations) { BOLT_VISIT(A); } diff --git a/include/bolt/Checker.hpp b/include/bolt/Checker.hpp index dc5a3913f..d2a73e403 100644 --- a/include/bolt/Checker.hpp +++ b/include/bolt/Checker.hpp @@ -89,15 +89,11 @@ class Checker { Type* IntType; Type* BoolType; Type* StringType; + Type* UnitType; public: - Checker(DiagnosticEngine& DE): - DE(DE) { - IntType = new TCon("Int"); - BoolType = new TCon("Bool"); - StringType = new TCon("String"); - } + Checker(DiagnosticEngine& DE); Type* getIntType() const { return IntType; @@ -111,6 +107,10 @@ public: return StringType; } + Type* getUnitType() const { + return UnitType; + } + TVar* createTVar() { return new TVar(); } diff --git a/include/bolt/Common.hpp b/include/bolt/Common.hpp index bee22a018..8e8cbf2a3 100644 --- a/include/bolt/Common.hpp +++ b/include/bolt/Common.hpp @@ -1,6 +1,7 @@ #pragma once +#include #include #include "zen/config.hpp" @@ -36,17 +37,10 @@ public: }; -template -D* cast(B* base) { - ZEN_ASSERT(D::classof(base)); - return static_cast(base); -} - -template -const D* cast(const B* base) { - ZEN_ASSERT(D::classof(base)); - return static_cast(base); -} +template +concept HoldsKind = requires (T a) { + { a.getKind() } -> std::convertible_to; +}; template bool isa(const T* value) { @@ -54,4 +48,22 @@ bool isa(const T* value) { return D::classof(value); } +template +bool isa(const T* value) { + ZEN_ASSERT(value != nullptr); + return D::Kind == value->getKind(); +} + +template +D* cast(B* base) { + ZEN_ASSERT(isa(base)); + return static_cast(base); +} + +template +const D* cast(const B* base) { + ZEN_ASSERT(isa(base)); + return static_cast(base); +} + } diff --git a/include/bolt/Parser.hpp b/include/bolt/Parser.hpp index 9ddbf3d07..5adc3791d 100644 --- a/include/bolt/Parser.hpp +++ b/include/bolt/Parser.hpp @@ -75,9 +75,7 @@ class Parser { std::optional>> parseRecordPatternFields(); template - T* expectToken() { - return static_cast(expectToken(getNodeType())); - } + T* expectToken(); Expression* parseInfixOperatorAfterExpression(Expression* LHS, int MinPrecedence); @@ -115,18 +113,15 @@ public: Parameter* parseParam(); ReferenceExpression* parseReferenceExpression(); - Expression* parseUnaryExpression(); - Expression* parseExpression(); - + BlockExpression* parseBlockExpression(std::vector Annotations = {}); Expression* parseCallExpression(); + IfExpression* parseIfExpression(); - IfStatement* parseIfStatement(); + ReturnExpression* parseReturnExpression(); - ReturnStatement* parseReturnStatement(); - - ExpressionStatement* parseExpressionStatement(); + Expression* parseExpressionStatement(); Node* parseLetBodyElement(); diff --git a/src/CST.cc b/src/CST.cc index 15df7b619..f8fc9db60 100644 --- a/src/CST.cc +++ b/src/CST.cc @@ -7,7 +7,7 @@ namespace bolt { TextFile::TextFile(ByteString Path, ByteString Text): Path(Path), Text(Text) { LineOffsets.push_back(0); - for (size_t I = 0; I < Text.size(); I++) { + for (std::size_t I = 0; I < Text.size(); I++) { auto Chr = Text[I]; if (Chr == '\n') { LineOffsets.push_back(I+1); @@ -16,16 +16,16 @@ TextFile::TextFile(ByteString Path, ByteString Text): LineOffsets.push_back(Text.size()); } -size_t TextFile::getLineCount() const { +std::size_t TextFile::getLineCount() const { return LineOffsets.size()-1; } -size_t TextFile::getStartOffsetOfLine(size_t Line) const { +std::size_t TextFile::getStartOffsetOfLine(std::size_t Line) const { ZEN_ASSERT(Line-1 < LineOffsets.size()); return LineOffsets[Line-1]; } -size_t TextFile::getEndOffsetOfLine(size_t Line) const { +std::size_t TextFile::getEndOffsetOfLine(std::size_t Line) const { ZEN_ASSERT(Line <= LineOffsets.size()); if (Line == LineOffsets.size()) { return Text.size(); @@ -33,9 +33,9 @@ size_t TextFile::getEndOffsetOfLine(size_t Line) const { return LineOffsets[Line]; } -size_t TextFile::getLine(size_t Offset) const { +std::size_t TextFile::getLine(std::size_t Offset) const { ZEN_ASSERT(Offset < Text.size()); - for (size_t I = 0; I < LineOffsets.size(); ++I) { + for (std::size_t I = 0; I < LineOffsets.size(); ++I) { if (LineOffsets[I] > Offset) { return I; } @@ -43,7 +43,7 @@ size_t TextFile::getLine(size_t Offset) const { ZEN_UNREACHABLE } -size_t TextFile::getColumn(size_t Offset) const { +std::size_t TextFile::getColumn(std::size_t Offset) const { auto Line = getLine(Offset); auto StartOffset = getStartOffsetOfLine(Line); return Offset - StartOffset + 1 ; @@ -60,7 +60,7 @@ ByteString TextFile::getText() const { const SourceFile* Node::getSourceFile() const { const Node* CurrNode = this; for (;;) { - if (CurrNode->Kind == NodeKind::SourceFile) { + if (CurrNode->K == NodeKind::SourceFile) { return static_cast(CurrNode); } CurrNode = CurrNode->Parent; @@ -70,7 +70,7 @@ const SourceFile* Node::getSourceFile() const { SourceFile* Node::getSourceFile() { Node* CurrNode = this; for (;;) { - if (CurrNode->Kind == NodeKind::SourceFile) { + if (CurrNode->K == NodeKind::SourceFile) { return static_cast(CurrNode); } CurrNode = CurrNode->Parent; @@ -508,42 +508,34 @@ Token* PrefixExpression::getLastToken() const { return Argument->getLastToken(); } -Token* ExpressionStatement::getFirstToken() const { - return Expression->getFirstToken(); -} - -Token* ExpressionStatement::getLastToken() const { - return Expression->getLastToken(); -} - -Token* ReturnStatement::getFirstToken() const { +Token* ReturnExpression::getFirstToken() const { return ReturnKeyword; } -Token* ReturnStatement::getLastToken() const { +Token* ReturnExpression::getLastToken() const { if (E) { return E->getLastToken(); } return ReturnKeyword; } -Token* IfStatementPart::getFirstToken() const { +Token* IfExpressionPart::getFirstToken() const { return Keyword; } -Token* IfStatementPart::getLastToken() const { +Token* IfExpressionPart::getLastToken() const { if (Elements.size()) { return Elements.back()->getLastToken(); } return BlockStart; } -Token* IfStatement::getFirstToken() const { +Token* IfExpression::getFirstToken() const { ZEN_ASSERT(Parts.size()); return Parts.front()->getFirstToken(); } -Token* IfStatement::getLastToken() const { +Token* IfExpression::getLastToken() const { ZEN_ASSERT(Parts.size()); return Parts.back()->getLastToken(); } @@ -1049,7 +1041,7 @@ SymbolPath ReferenceExpression::getSymbolPath() const { return SymbolPath { ModuleNames, Name.getCanonicalText() }; } -bool TypedNode::classof(Node* N) { +bool TypedNode::classof(const Node* N) { return Expression::classof(N) || TypeExpression::classof(N) || FunctionDeclaration::classof(N) diff --git a/src/Checker.cc b/src/Checker.cc index 3da4d287b..28298060e 100644 --- a/src/Checker.cc +++ b/src/Checker.cc @@ -78,7 +78,13 @@ Type* substituteType(Type* Ty, const TVSub& Sub) { } } - +Checker::Checker(DiagnosticEngine& DE): + DE(DE) { + IntType = new TCon("Int"); + BoolType = new TCon("Bool"); + StringType = new TCon("String"); + UnitType = new TCon("()"); + } Type* Checker::instantiate(TypeScheme* Scm) { TVSub Sub; @@ -103,6 +109,23 @@ std::tuple Checker::inferExpr(TypeEnv& Env, Expression* Ex switch (Expr->getKind()) { + case NodeKind::BlockExpression: + { + auto E = static_cast(Expr); + auto N = E->Elements.size(); + for (std::size_t I = 0; I+1 < N; ++I) { + auto Element = E->Elements[I]; + + auto CC = inferElement(Env, Element, RetTy); + mergeTo(Out, CC); + } + auto Last = E->Elements[N-1]; + auto [CC, ResTy] = inferExpr(Env, cast(Last), RetTy); + mergeTo(Out, CC); + Ty = ResTy; + break; + } + case NodeKind::ReferenceExpression: { auto E = static_cast(Expr); @@ -169,6 +192,21 @@ std::tuple Checker::inferExpr(TypeEnv& Env, Expression* Ex break; } + case NodeKind::ReturnExpression: + { + auto E = static_cast(Expr); + if (E->hasExpression()) { + auto [ValOut, ValTy] = inferExpr(Env, E->getExpression(), RetTy); + mergeTo(Out, ValOut); + // Since evaluation stops at the return expression, it can be matched with any type. + Out.push_back(new CTypesEqual { ValTy, RetTy, E }); + } else { + Out.push_back(new CTypesEqual { getUnitType(), RetTy, E }); + } + Ty = createTVar(); + break; + } + // TODO LambdaExpression default: @@ -255,7 +293,7 @@ ConstraintSet Checker::inferFunctionDeclaration(TypeEnv& Env, FunctionDeclaratio if (Body != nullptr) { // TODO elminate BlockBody and replace with BlockExpr ZEN_ASSERT(Body->getKind() == NodeKind::LetExprBody); - auto [BodyOut, BodyTy] = inferExpr(NewEnv, static_cast(Body)->Expression, RetTy); + auto [BodyOut, BodyTy] = inferExpr(NewEnv, cast(Body)->Expression, RetTy); mergeTo(Out, BodyOut); Out.push_back(new CTypesEqual(RetTy, BodyTy, Body)); } @@ -351,7 +389,7 @@ ConstraintSet Checker::inferMany(TypeEnv& Env, std::vector& Elements, Typ V.visit(N); }; - std::vector Stmts; + std::vector Stmts; for (auto Element: Elements) { if (isa(Element)) { @@ -367,7 +405,7 @@ ConstraintSet Checker::inferMany(TypeEnv& Env, std::vector& Elements, Typ populate(M, M->getExpression()); } } else { - Stmts.push_back(cast(Element)); + Stmts.push_back(Element); } } @@ -407,6 +445,11 @@ ConstraintSet Checker::inferMany(TypeEnv& Env, std::vector& Elements, Typ ConstraintSet Checker::inferElement(TypeEnv& Env, Node* N, Type* RetTy) { + if (isa(N)) { + auto [Out, Ty] = inferExpr(Env, cast(N), RetTy); + return Out; + } + switch (N->getKind()) { case NodeKind::PrefixFunctionDeclaration: @@ -415,16 +458,9 @@ ConstraintSet Checker::inferElement(TypeEnv& Env, Node* N, Type* RetTy) { case NodeKind::NamedFunctionDeclaration: return inferFunctionDeclaration(Env, static_cast(N)); - case NodeKind::ExpressionStatement: + case NodeKind::ReturnExpression: { - auto M = static_cast(N); - auto [Out, _] = inferExpr(Env, M->Expression, RetTy); - return Out; - } - - case NodeKind::ReturnStatement: - { - auto M = static_cast(N); + auto M = static_cast(N); if (!M->hasExpression()) { return {}; } diff --git a/src/ConsolePrinter.cc b/src/ConsolePrinter.cc index 3b5ae378a..c8305e61a 100644 --- a/src/ConsolePrinter.cc +++ b/src/ConsolePrinter.cc @@ -172,9 +172,9 @@ static std::string describe(NodeKind Type) { return "a literal expression"; case NodeKind::MemberExpression: return "an accessor of a member"; - case NodeKind::IfStatement: + case NodeKind::IfExpression: return "an if-statement"; - case NodeKind::IfStatementPart: + case NodeKind::IfExpressionPart: return "a branch of an if-statement"; case NodeKind::VariantDeclaration: return "a variant"; diff --git a/src/Evaluator.cc b/src/Evaluator.cc index 04a18c85c..66b29edf2 100644 --- a/src/Evaluator.cc +++ b/src/Evaluator.cc @@ -60,11 +60,11 @@ Value Evaluator::apply(Value Op, std::vector Args) { { auto Fn = Op.getDeclaration(); Env NewEnv; - auto Params= Fn->getParams(); + auto Params = Fn->getParams(); auto ParamIter = Params.begin(); auto ParamsEnd = Params.end(); auto ArgIter = Args.begin(); - auto ArgsEnd= Args.end(); + auto ArgsEnd = Args.end(); for (;;) { if (ParamIter == ParamsEnd && ArgIter == ArgsEnd) { break; @@ -97,6 +97,10 @@ Value Evaluator::apply(Value Op, std::vector Args) { } void Evaluator::evaluate(Node* N, Env& E) { + if (isa(N)) { + evaluateExpression(cast(N), E); + return; + } switch (N->getKind()) { case NodeKind::SourceFile: { @@ -106,12 +110,6 @@ void Evaluator::evaluate(Node* N, Env& E) { } break; } - case NodeKind::ExpressionStatement: - { - auto ES = static_cast(N); - evaluateExpression(ES->Expression, E); - break; - } case NodeKind::PrefixFunctionDeclaration: case NodeKind::InfixFunctionDeclaration: case NodeKind::SuffixFunctionDeclaration: diff --git a/src/Parser.cc b/src/Parser.cc index 776075aa2..83e8ceb71 100644 --- a/src/Parser.cc +++ b/src/Parser.cc @@ -85,6 +85,18 @@ Parser::Parser(TextFile& File, Stream& S, DiagnosticEngine& DE): ExprOperators.add("$", OperatorFlags_InfixR, 0); } + +template +T* Parser::expectToken() { + auto Tok = Tokens.peek(); + if (Tok->getKind() != T::Kind) { + DE.add(File, Tok, std::vector { T::Kind }); + return nullptr; + } + Tokens.get(); + return static_cast(Tok); +} + Token* Parser::peekFirstTokenAfterAnnotationsAndModifiers() { std::size_t I = 0; for (;;) { @@ -107,16 +119,6 @@ Token* Parser::peekFirstTokenAfterAnnotationsAndModifiers() { } } -Token* Parser::expectToken(NodeKind Kind) { - auto T = Tokens.peek(); - if (T->getKind() != Kind) { - DE.add(File, T, std::vector { Kind }); - return nullptr; - } - Tokens.get(); - return T; -} - ListPattern* Parser::parseListPattern() { auto LBracket = expectToken(); if (!LBracket) { @@ -818,7 +820,7 @@ Expression* Parser::parsePrimitiveExpression() { ModulePath.push_back(std::make_tuple(static_cast(T1), static_cast(T2))); } auto T3 = Tokens.get(); - if (!T3->is() && !T3->is()) { + if (!isa(T3) && !isa(T3)) { for (auto [Name, Dot]: ModulePath) { Name->unref(); Dot->unref(); @@ -886,37 +888,11 @@ after_tuple_elements: case NodeKind::MatchKeyword: return parseMatchExpression(); case NodeKind::DoKeyword: - { - Tokens.get(); - auto T1 = expectToken(NodeKind::BlockStart); - if (!T1) { - BOLT_EACH_UNREF(Annotations); - T0->unref(); - return nullptr; - } - std::vector Elements; - for (;;) { - auto T2 = Tokens.peek(); - if (T2->getKind() == NodeKind::BlockEnd) { - Tokens.get()->unref(); - break; - } - auto Element = parseLetBodyElement(); - if (Element == nullptr) { - BOLT_EACH_UNREF(Annotations); - T0->unref(); - T1->unref(); - BOLT_EACH_UNREF(Elements); - return nullptr; - } - Elements.push_back(Element); - } - return new BlockExpression { - static_cast(T0), - static_cast(T1), - Elements - }; - } + return parseBlockExpression(); + case NodeKind::IfKeyword: + return parseIfExpression(); + case NodeKind::ReturnKeyword: + return parseReturnExpression(); case NodeKind::IntegerLiteral: case NodeKind::StringLiteral: Tokens.get(); @@ -938,6 +914,42 @@ after_tuple_elements: } } +BlockExpression* Parser::parseBlockExpression(std::vector Annotations) { + auto DoKeyword = expectToken(); + if (!DoKeyword) { + BOLT_EACH_UNREF(Annotations); + return nullptr; + } + auto BlockStart = expectToken(); + if (!BlockStart) { + BOLT_EACH_UNREF(Annotations); + DoKeyword->unref(); + return nullptr; + } + std::vector Elements; + for (;;) { + auto T2 = Tokens.peek(); + if (T2->getKind() == NodeKind::BlockEnd) { + Tokens.get()->unref(); + break; + } + auto Element = parseLetBodyElement(); + if (Element == nullptr) { + BOLT_EACH_UNREF(Annotations); + DoKeyword->unref(); + BlockStart->unref(); + BOLT_EACH_UNREF(Elements); + return nullptr; + } + Elements.push_back(Element); + } + return new BlockExpression { + DoKeyword, + BlockStart, + Elements + }; +} + Expression* Parser::parseMemberExpression() { auto E = parsePrimitiveExpression(); if (!E) { @@ -1068,17 +1080,17 @@ Expression* Parser::parseExpression() { return parseInfixOperatorAfterExpression(Left, 0); } -ExpressionStatement* Parser::parseExpressionStatement() { +Expression* Parser::parseExpressionStatement() { auto E = parseExpression(); if (!E) { skipPastLineFoldEnd(); return nullptr; } checkLineFoldEnd(); - return new ExpressionStatement(E); + return E; } -ReturnStatement* Parser::parseReturnStatement() { +ReturnExpression* Parser::parseReturnExpression() { auto Annotations = parseAnnotations(); auto ReturnKeyword = expectToken(); if (!ReturnKeyword) { @@ -1094,16 +1106,14 @@ ReturnStatement* Parser::parseReturnStatement() { Expression = parseExpression(); if (!Expression) { ReturnKeyword->unref(); - skipPastLineFoldEnd(); return nullptr; } - checkLineFoldEnd(); } - return new ReturnStatement(Annotations, ReturnKeyword, Expression); + return new ReturnExpression(Annotations, ReturnKeyword, Expression); } -IfStatement* Parser::parseIfStatement() { - std::vector Parts; +IfExpression* Parser::parseIfExpression() { + std::vector Parts; auto Annotations = parseAnnotations(); auto IfKeyword = expectToken(); if (!IfKeyword) { @@ -1136,7 +1146,7 @@ IfStatement* Parser::parseIfStatement() { } } Tokens.get()->unref(); // Always a LineFoldEnd - Parts.push_back(new IfStatementPart(Annotations, IfKeyword, Test, T1, Then)); + Parts.push_back(new IfExpressionPart(Annotations, IfKeyword, Test, T1, Then)); for (;;) { auto T3 = peekFirstTokenAfterAnnotationsAndModifiers(); if (T3->getKind() != NodeKind::ElseKeyword && T3->getKind() != NodeKind::ElifKeyword) { @@ -1168,12 +1178,12 @@ IfStatement* Parser::parseIfStatement() { } } Tokens.get()->unref(); // Always a LineFoldEnd - Parts.push_back(new IfStatementPart(Annotations, T3, Test, T4, Alt)); + Parts.push_back(new IfExpressionPart(Annotations, T3, Test, T4, Alt)); if (T3->getKind() == NodeKind::ElseKeyword) { break; } } - return new IfStatement(Parts); + return new IfExpression(Parts); } enum class LetMode { @@ -1435,7 +1445,7 @@ finish: Pub, Foreign, Let, - Name->as()->Name, + cast(Name)->Name, Params, TA, Body @@ -1448,10 +1458,6 @@ Node* Parser::parseLetBodyElement() { switch (T0->getKind()) { case NodeKind::LetKeyword: return parseLetDeclaration(); - case NodeKind::ReturnKeyword: - return parseReturnStatement(); - case NodeKind::IfKeyword: - return parseIfStatement(); default: return parseExpressionStatement(); } @@ -1550,7 +1556,7 @@ InstanceDeclaration* Parser::parseInstanceDeclaration() { std::vector TypeExps; for (;;) { auto T1 = Tokens.peek(); - if (T1->is()) { + if (isa(T1)) { break; } auto TE = parseTypeExpression(); @@ -1578,7 +1584,7 @@ InstanceDeclaration* Parser::parseInstanceDeclaration() { std::vector Elements; for (;;) { auto T2 = Tokens.peek(); - if (T2->is()) { + if (isa(T2)) { Tokens.get()->unref(); break; } @@ -1656,7 +1662,7 @@ ClassDeclaration* Parser::parseClassDeclaration() { std::vector Elements; for (;;) { auto T2 = Tokens.peek(); - if (T2->is()) { + if (isa(T2)) { Tokens.get()->unref(); break; } @@ -1867,8 +1873,6 @@ Node* Parser::parseSourceElement() { switch (T0->getKind()) { case NodeKind::LetKeyword: return parseLetDeclaration(); - case NodeKind::IfKeyword: - return parseIfStatement(); case NodeKind::ClassKeyword: return parseClassDeclaration(); case NodeKind::InstanceKeyword: @@ -1886,7 +1890,7 @@ SourceFile* Parser::parseSourceFile() { std::vector Elements; for (;;) { auto T0 = Tokens.peek(); - if (T0->is()) { + if (isa(T0)) { break; } auto Element = parseSourceElement(); diff --git a/src/Scope.cc b/src/Scope.cc index 0a2ce065a..48f57e74d 100644 --- a/src/Scope.cc +++ b/src/Scope.cc @@ -49,11 +49,11 @@ void Scope::scan(Node* X) { } void Scope::scanChild(Node* X) { + if (isa(X)) { + return; + } switch (X->getKind()) { case NodeKind::LetExprBody: - case NodeKind::ExpressionStatement: - case NodeKind::IfStatement: - case NodeKind::ReturnStatement: break; case NodeKind::LetBlockBody: { diff --git a/src/main.cc b/src/main.cc index 2020a1cfe..25ba1bd64 100644 --- a/src/main.cc +++ b/src/main.cc @@ -135,12 +135,12 @@ int main(int Argc, const char* Argv[]) { std::multimap Expected; void visitExpressionAnnotation(ExpressionAnnotation* N) { - if (N->getExpression()->is()) { + if (isa(N->getExpression())) { auto CE = static_cast(N->getExpression()); - if (CE->Function->is()) { + if (isa(CE->Function)) { auto RE = static_cast(CE->Function); if (RE->getNameAsString() == "expect_diagnostic") { - ZEN_ASSERT(CE->Args.size() == 1 && CE->Args[0]->is()); + ZEN_ASSERT(CE->Args.size() == 1 && isa(CE->Args[0])); Expected.emplace(N->Parent->getStartLine(), static_cast(CE->Args[0])->getAsInt()); } }