diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.cpp index 6cd9a5ba08..239070b1a1 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.cpp @@ -49,7 +49,7 @@ Vector IsOneOfOperation::subtrees() return result; } -Vector ReturnExpression::subtrees() +Vector ReturnNode::subtrees() { return { { &m_return_value } }; } diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h index ced4bd7ef9..4a0ed558c4 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h @@ -40,7 +40,6 @@ private: Variant m_tree_ptr; }; -// ===== Generic nodes ===== class Node : public RefCounted { public: virtual ~Node() = default; @@ -59,7 +58,20 @@ protected: virtual void dump_tree(StringBuilder& builder) = 0; }; -class ErrorNode : public Node { +// Although both statements and expressions are allowed to return value, CFG building differentiates +// between them. Expressions are not allowed to change control flow, while statements are. Special +// handling required if a statement turns out to be a descendant of an expression. Roughly speaking, +// from the CFG standpoint, something like `a = ({ b + ({ c }) }) + ({ d })` will look like +// ``` +// auto tmp1 = c; +// auto tmp2 = b + tmp1; +// auto tmp3 = d; +// a = tmp1 + tmp2; +// ```. +class Statement : public Node { }; +class Expression : public Node { }; + +class ErrorNode : public Expression { public: ErrorNode(StringView error = ""sv) : m_error(error) @@ -74,8 +86,7 @@ protected: inline Tree const error_tree = make_ref_counted(); -// ===== Concrete evaluatable nodes ===== -class MathematicalConstant : public Node { +class MathematicalConstant : public Expression { public: MathematicalConstant(i64 number) : m_number(number) @@ -89,7 +100,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class StringLiteral : public Node { +class StringLiteral : public Expression { public: StringLiteral(StringView literal) : m_literal(literal) @@ -147,7 +158,7 @@ inline constexpr StringView binary_operator_names[] = { #undef NAME #undef STRINGIFY -class BinaryOperation : public Node { +class BinaryOperation : public Expression { public: BinaryOperation(BinaryOperator operation, Tree left, Tree right) : m_operation(operation) @@ -166,7 +177,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class UnaryOperation : public Node { +class UnaryOperation : public Expression { public: UnaryOperation(UnaryOperator operation, Tree operand) : m_operation(operation) @@ -183,7 +194,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class IsOneOfOperation : public Node { +class IsOneOfOperation : public Expression { public: IsOneOfOperation(Tree operand, Vector&& compare_values) : m_operand(move(operand)) @@ -200,7 +211,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class UnresolvedReference : public Node { +class UnresolvedReference : public Expression { public: UnresolvedReference(StringView name) : m_name(name) @@ -213,9 +224,9 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class ReturnExpression : public Node { +class ReturnNode : public Node { public: - ReturnExpression(Tree return_value) + ReturnNode(Tree return_value) : m_return_value(move(return_value)) { } @@ -228,7 +239,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class AssertExpression : public Node { +class AssertExpression : public Expression { public: AssertExpression(Tree condition) : m_condition(move(condition)) @@ -277,7 +288,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class IfElseIfChain : public Node { +class IfElseIfChain : public Statement { public: IfElseIfChain(Vector&& conditions, Vector&& branches, NullableTree else_branch) : m_conditions(move(conditions)) @@ -300,7 +311,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class TreeList : public Node { +class TreeList : public Statement { public: TreeList(Vector&& expressions_) : m_expressions(move(expressions_)) @@ -315,7 +326,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class RecordDirectListInitialization : public Node { +class RecordDirectListInitialization : public Expression { public: struct Argument { Tree name; @@ -337,7 +348,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class FunctionCall : public Node { +class FunctionCall : public Expression { public: FunctionCall(Tree name, Vector&& arguments) : m_name(move(name)) @@ -354,7 +365,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class SlotName : public Node { +class SlotName : public Expression { public: SlotName(StringView member_name) : m_member_name(member_name) @@ -367,7 +378,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class Variable : public Node { +class Variable : public Expression { public: Variable(StringView variable_name) : m_name(variable_name) @@ -380,7 +391,7 @@ protected: void dump_tree(StringBuilder& builder) override; }; -class FunctionPointer : public Node { +class FunctionPointer : public Expression { public: FunctionPointer(StringView function_name) : m_function(function_name) diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp index aea5e299ae..fe42a7c294 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp @@ -70,9 +70,9 @@ void UnresolvedReference::dump_tree(StringBuilder& builder) dump_node(builder, "UnresolvedReference {}", m_name); } -void ReturnExpression::dump_tree(StringBuilder& builder) +void ReturnNode::dump_tree(StringBuilder& builder) { - dump_node(builder, "ReturnExpression"); + dump_node(builder, "ReturnNode"); m_return_value->format_tree(builder); } diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h index 7274e6f070..56df2fa3a3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h @@ -16,16 +16,17 @@ class NodeSubtreePointer; class Node; using NullableTree = RefPtr; using Tree = NonnullRefPtr; +class Statement; +class Expression; class ErrorNode; -class ScopedBlock; class MathematicalConstant; class StringLiteral; class BinaryOperation; class UnaryOperation; class IsOneOfOperation; class UnresolvedReference; -class ReturnExpression; +class ReturnNode; class AssertExpression; class IfBranch; class ElseIfBranch; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp index d0dfd2e9e1..afa4a5c601 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp @@ -306,7 +306,7 @@ ParseErrorOr TextParser::parse_return_statement() auto return_value = TRY(parse_expression()); rollback.disarm(); - return make_ref_counted(return_value); + return make_ref_counted(return_value); } // assert: