JSSpecCompiler: Make nodes inherit from Statement or Expression

The distinction between them will become important during CFG building.
This commit is contained in:
Dan Klishch 2023-08-19 14:05:36 -04:00 committed by Andrew Kaster
parent ed5ef4da6d
commit 326bac19d9
Notes: sideshowbarker 2024-07-17 07:19:27 +09:00
5 changed files with 37 additions and 25 deletions

View file

@ -49,7 +49,7 @@ Vector<NodeSubtreePointer> IsOneOfOperation::subtrees()
return result; return result;
} }
Vector<NodeSubtreePointer> ReturnExpression::subtrees() Vector<NodeSubtreePointer> ReturnNode::subtrees()
{ {
return { { &m_return_value } }; return { { &m_return_value } };
} }

View file

@ -40,7 +40,6 @@ private:
Variant<Tree*, NullableTree*> m_tree_ptr; Variant<Tree*, NullableTree*> m_tree_ptr;
}; };
// ===== Generic nodes =====
class Node : public RefCounted<Node> { class Node : public RefCounted<Node> {
public: public:
virtual ~Node() = default; virtual ~Node() = default;
@ -59,7 +58,20 @@ protected:
virtual void dump_tree(StringBuilder& builder) = 0; 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: public:
ErrorNode(StringView error = ""sv) ErrorNode(StringView error = ""sv)
: m_error(error) : m_error(error)
@ -74,8 +86,7 @@ protected:
inline Tree const error_tree = make_ref_counted<ErrorNode>(); inline Tree const error_tree = make_ref_counted<ErrorNode>();
// ===== Concrete evaluatable nodes ===== class MathematicalConstant : public Expression {
class MathematicalConstant : public Node {
public: public:
MathematicalConstant(i64 number) MathematicalConstant(i64 number)
: m_number(number) : m_number(number)
@ -89,7 +100,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class StringLiteral : public Node { class StringLiteral : public Expression {
public: public:
StringLiteral(StringView literal) StringLiteral(StringView literal)
: m_literal(literal) : m_literal(literal)
@ -147,7 +158,7 @@ inline constexpr StringView binary_operator_names[] = {
#undef NAME #undef NAME
#undef STRINGIFY #undef STRINGIFY
class BinaryOperation : public Node { class BinaryOperation : public Expression {
public: public:
BinaryOperation(BinaryOperator operation, Tree left, Tree right) BinaryOperation(BinaryOperator operation, Tree left, Tree right)
: m_operation(operation) : m_operation(operation)
@ -166,7 +177,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class UnaryOperation : public Node { class UnaryOperation : public Expression {
public: public:
UnaryOperation(UnaryOperator operation, Tree operand) UnaryOperation(UnaryOperator operation, Tree operand)
: m_operation(operation) : m_operation(operation)
@ -183,7 +194,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class IsOneOfOperation : public Node { class IsOneOfOperation : public Expression {
public: public:
IsOneOfOperation(Tree operand, Vector<Tree>&& compare_values) IsOneOfOperation(Tree operand, Vector<Tree>&& compare_values)
: m_operand(move(operand)) : m_operand(move(operand))
@ -200,7 +211,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class UnresolvedReference : public Node { class UnresolvedReference : public Expression {
public: public:
UnresolvedReference(StringView name) UnresolvedReference(StringView name)
: m_name(name) : m_name(name)
@ -213,9 +224,9 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class ReturnExpression : public Node { class ReturnNode : public Node {
public: public:
ReturnExpression(Tree return_value) ReturnNode(Tree return_value)
: m_return_value(move(return_value)) : m_return_value(move(return_value))
{ {
} }
@ -228,7 +239,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class AssertExpression : public Node { class AssertExpression : public Expression {
public: public:
AssertExpression(Tree condition) AssertExpression(Tree condition)
: m_condition(move(condition)) : m_condition(move(condition))
@ -277,7 +288,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class IfElseIfChain : public Node { class IfElseIfChain : public Statement {
public: public:
IfElseIfChain(Vector<Tree>&& conditions, Vector<Tree>&& branches, NullableTree else_branch) IfElseIfChain(Vector<Tree>&& conditions, Vector<Tree>&& branches, NullableTree else_branch)
: m_conditions(move(conditions)) : m_conditions(move(conditions))
@ -300,7 +311,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class TreeList : public Node { class TreeList : public Statement {
public: public:
TreeList(Vector<Tree>&& expressions_) TreeList(Vector<Tree>&& expressions_)
: m_expressions(move(expressions_)) : m_expressions(move(expressions_))
@ -315,7 +326,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class RecordDirectListInitialization : public Node { class RecordDirectListInitialization : public Expression {
public: public:
struct Argument { struct Argument {
Tree name; Tree name;
@ -337,7 +348,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class FunctionCall : public Node { class FunctionCall : public Expression {
public: public:
FunctionCall(Tree name, Vector<Tree>&& arguments) FunctionCall(Tree name, Vector<Tree>&& arguments)
: m_name(move(name)) : m_name(move(name))
@ -354,7 +365,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class SlotName : public Node { class SlotName : public Expression {
public: public:
SlotName(StringView member_name) SlotName(StringView member_name)
: m_member_name(member_name) : m_member_name(member_name)
@ -367,7 +378,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class Variable : public Node { class Variable : public Expression {
public: public:
Variable(StringView variable_name) Variable(StringView variable_name)
: m_name(variable_name) : m_name(variable_name)
@ -380,7 +391,7 @@ protected:
void dump_tree(StringBuilder& builder) override; void dump_tree(StringBuilder& builder) override;
}; };
class FunctionPointer : public Node { class FunctionPointer : public Expression {
public: public:
FunctionPointer(StringView function_name) FunctionPointer(StringView function_name)
: m_function(function_name) : m_function(function_name)

View file

@ -70,9 +70,9 @@ void UnresolvedReference::dump_tree(StringBuilder& builder)
dump_node(builder, "UnresolvedReference {}", m_name); 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); m_return_value->format_tree(builder);
} }

View file

@ -16,16 +16,17 @@ class NodeSubtreePointer;
class Node; class Node;
using NullableTree = RefPtr<Node>; using NullableTree = RefPtr<Node>;
using Tree = NonnullRefPtr<Node>; using Tree = NonnullRefPtr<Node>;
class Statement;
class Expression;
class ErrorNode; class ErrorNode;
class ScopedBlock;
class MathematicalConstant; class MathematicalConstant;
class StringLiteral; class StringLiteral;
class BinaryOperation; class BinaryOperation;
class UnaryOperation; class UnaryOperation;
class IsOneOfOperation; class IsOneOfOperation;
class UnresolvedReference; class UnresolvedReference;
class ReturnExpression; class ReturnNode;
class AssertExpression; class AssertExpression;
class IfBranch; class IfBranch;
class ElseIfBranch; class ElseIfBranch;

View file

@ -306,7 +306,7 @@ ParseErrorOr<Tree> TextParser::parse_return_statement()
auto return_value = TRY(parse_expression()); auto return_value = TRY(parse_expression());
rollback.disarm(); rollback.disarm();
return make_ref_counted<ReturnExpression>(return_value); return make_ref_counted<ReturnNode>(return_value);
} }
// assert: <condition> // assert: <condition>