mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 03:55:24 +00:00
JSSpecCompiler: Add stubs for AST types
This commit is contained in:
parent
da30afa0c3
commit
5846470a5f
Notes:
sideshowbarker
2024-07-17 07:38:17 +09:00
Author: https://github.com/DanShaders Commit: https://github.com/SerenityOS/serenity/commit/5846470a5f Pull-request: https://github.com/SerenityOS/serenity/pull/20632 Reviewed-by: https://github.com/ADKaster ✅
3 changed files with 514 additions and 0 deletions
338
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h
Normal file
338
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h
Normal file
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
#include "Forward.h"
|
||||
|
||||
namespace JSSpecCompiler {
|
||||
|
||||
template<typename T>
|
||||
RefPtr<T> as(NullableTree const& tree)
|
||||
{
|
||||
return dynamic_cast<T*>(tree.ptr());
|
||||
}
|
||||
|
||||
// ===== Generic nodes =====
|
||||
class Node : public RefCounted<Node> {
|
||||
public:
|
||||
virtual ~Node() = default;
|
||||
|
||||
void format_tree(StringBuilder& builder);
|
||||
|
||||
virtual bool is_type() { return false; }
|
||||
|
||||
protected:
|
||||
template<typename... Parameters>
|
||||
void dump_node(StringBuilder& builder, AK::CheckedFormatString<Parameters...>&& fmtstr, Parameters const&... parameters);
|
||||
|
||||
virtual void dump_tree(StringBuilder& builder) = 0;
|
||||
};
|
||||
|
||||
class ErrorNode : public Node {
|
||||
public:
|
||||
ErrorNode() { }
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
inline Tree const error_tree = make_ref_counted<ErrorNode>();
|
||||
|
||||
// ===== Concrete evaluatable nodes =====
|
||||
class MathematicalConstant : public Node {
|
||||
public:
|
||||
MathematicalConstant(i64 number)
|
||||
: m_number(number)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: This should be able to hold arbitrary number
|
||||
i64 m_number;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class StringLiteral : public Node {
|
||||
public:
|
||||
StringLiteral(StringView literal)
|
||||
: m_literal(literal)
|
||||
{
|
||||
}
|
||||
|
||||
StringView m_literal;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
#define ENUMERATE_UNARY_OPERATORS(F) \
|
||||
F(Invalid) \
|
||||
F(Minus) \
|
||||
F(AssertCompletion)
|
||||
|
||||
#define ENUMERATE_BINARY_OPERATORS(F) \
|
||||
F(Invalid) \
|
||||
F(CompareLess) \
|
||||
F(CompareGreater) \
|
||||
F(CompareNotEqual) \
|
||||
F(CompareEqual) \
|
||||
F(Assignment) \
|
||||
F(Declaration) \
|
||||
F(Plus) \
|
||||
F(Minus) \
|
||||
F(Multiplication) \
|
||||
F(Division) \
|
||||
F(Comma) \
|
||||
F(MemberAccess) \
|
||||
F(FunctionCall) \
|
||||
F(ArraySubscript)
|
||||
|
||||
#define NAME(name) name,
|
||||
#define STRINGIFY(name) #name##sv,
|
||||
|
||||
enum class UnaryOperator {
|
||||
ENUMERATE_UNARY_OPERATORS(NAME)
|
||||
};
|
||||
|
||||
inline constexpr StringView unary_operator_names[] = {
|
||||
ENUMERATE_UNARY_OPERATORS(STRINGIFY)
|
||||
};
|
||||
|
||||
enum class BinaryOperator {
|
||||
#define NAME(name) name,
|
||||
ENUMERATE_BINARY_OPERATORS(NAME)
|
||||
};
|
||||
|
||||
inline constexpr StringView binary_operator_names[] = {
|
||||
ENUMERATE_BINARY_OPERATORS(STRINGIFY)
|
||||
};
|
||||
|
||||
#undef NAME
|
||||
#undef STRINGIFY
|
||||
|
||||
class BinaryOperation : public Node {
|
||||
public:
|
||||
BinaryOperation(BinaryOperator operation, Tree left, Tree right)
|
||||
: m_operation(operation)
|
||||
, m_left(left)
|
||||
, m_right(right)
|
||||
{
|
||||
}
|
||||
|
||||
BinaryOperator m_operation;
|
||||
Tree m_left;
|
||||
Tree m_right;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class UnaryOperation : public Node {
|
||||
public:
|
||||
UnaryOperation(UnaryOperator operation, Tree operand)
|
||||
: m_operation(operation)
|
||||
, m_operand(operand)
|
||||
{
|
||||
}
|
||||
|
||||
UnaryOperator m_operation;
|
||||
Tree m_operand;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class IsOneOfOperation : public Node {
|
||||
public:
|
||||
IsOneOfOperation(Tree operand, Vector<Tree>&& compare_values)
|
||||
: m_operand(operand)
|
||||
, m_compare_values(move(compare_values))
|
||||
{
|
||||
}
|
||||
|
||||
Tree m_operand;
|
||||
Vector<Tree> m_compare_values;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class UnresolvedReference : public Node {
|
||||
public:
|
||||
UnresolvedReference(StringView name)
|
||||
: m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
StringView m_name;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class ReturnExpression : public Node {
|
||||
public:
|
||||
ReturnExpression(Tree return_value)
|
||||
: m_return_value(return_value)
|
||||
{
|
||||
}
|
||||
|
||||
Tree m_return_value;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class AssertExpression : public Node {
|
||||
public:
|
||||
AssertExpression(Tree condition)
|
||||
: m_condition(condition)
|
||||
{
|
||||
}
|
||||
|
||||
Tree m_condition;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class IfBranch : public Node {
|
||||
public:
|
||||
IfBranch(Tree condition, Tree branch)
|
||||
: m_condition(condition)
|
||||
, m_branch(branch)
|
||||
{
|
||||
}
|
||||
|
||||
Tree m_condition;
|
||||
Tree m_branch;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class ElseIfBranch : public Node {
|
||||
public:
|
||||
ElseIfBranch(Optional<Tree> condition, Tree branch)
|
||||
: m_condition(condition)
|
||||
, m_branch(branch)
|
||||
{
|
||||
}
|
||||
|
||||
Optional<Tree> m_condition;
|
||||
Tree m_branch;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class TreeList : public Node {
|
||||
public:
|
||||
TreeList(Vector<Tree>&& expressions_)
|
||||
: m_expressions(move(expressions_))
|
||||
{
|
||||
}
|
||||
|
||||
Vector<Tree> m_expressions;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class RecordDirectListInitialization : public Node {
|
||||
public:
|
||||
struct Argument {
|
||||
Tree name;
|
||||
Tree value;
|
||||
};
|
||||
|
||||
RecordDirectListInitialization(Tree type_reference, Vector<Argument>&& arguments)
|
||||
: m_type_reference(type_reference)
|
||||
, m_arguments(move(arguments))
|
||||
{
|
||||
}
|
||||
|
||||
Tree m_type_reference;
|
||||
Vector<Argument> m_arguments;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class FunctionCall : public Node {
|
||||
public:
|
||||
FunctionCall(Tree name, Vector<Tree>&& arguments)
|
||||
: m_name(name)
|
||||
, m_arguments(move(arguments))
|
||||
{
|
||||
}
|
||||
|
||||
Tree m_name;
|
||||
Vector<Tree> m_arguments;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class SlotName : public Node {
|
||||
public:
|
||||
SlotName(StringView member_name)
|
||||
: m_member_name(member_name)
|
||||
{
|
||||
}
|
||||
|
||||
StringView m_member_name;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class Variable : public Node {
|
||||
public:
|
||||
Variable(StringView variable_name)
|
||||
: m_name(variable_name)
|
||||
{
|
||||
}
|
||||
|
||||
StringView m_name;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
class FunctionPointer : public Node {
|
||||
public:
|
||||
FunctionPointer(StringView function_name)
|
||||
: m_function_name(function_name)
|
||||
{
|
||||
}
|
||||
|
||||
StringView m_function_name;
|
||||
|
||||
protected:
|
||||
void dump_tree(StringBuilder& builder) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
|
||||
template<>
|
||||
struct Formatter<JSSpecCompiler::Tree> : Formatter<StringView> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, JSSpecCompiler::Tree const& tree)
|
||||
{
|
||||
tree->format_tree(builder.builder());
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/TemporaryChange.h>
|
||||
|
||||
#include "AST/AST.h"
|
||||
|
||||
namespace JSSpecCompiler {
|
||||
|
||||
void Node::format_tree(StringBuilder& builder)
|
||||
{
|
||||
static int current_depth = -1;
|
||||
TemporaryChange<int> depth_change(current_depth, current_depth + 1);
|
||||
builder.append_repeated(' ', current_depth * 2);
|
||||
dump_tree(builder);
|
||||
}
|
||||
|
||||
template<typename... Parameters>
|
||||
void Node::dump_node(StringBuilder& builder, AK::CheckedFormatString<Parameters...>&& fmtstr, Parameters const&... parameters)
|
||||
{
|
||||
builder.append("<"sv);
|
||||
AK::VariadicFormatParams<AK::AllowDebugOnlyFormatters::No, Parameters...> variadic_format_params { parameters... };
|
||||
MUST(AK::vformat(builder, fmtstr.view(), variadic_format_params));
|
||||
builder.append(">\n"sv);
|
||||
}
|
||||
|
||||
void ErrorNode::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "Error");
|
||||
}
|
||||
|
||||
void MathematicalConstant::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "MathematicalConstant {}", m_number);
|
||||
}
|
||||
|
||||
void StringLiteral::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "StringLiteral {}", m_literal);
|
||||
}
|
||||
|
||||
void BinaryOperation::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "BinaryOperation {}", binary_operator_names[to_underlying(m_operation)]);
|
||||
m_left->format_tree(builder);
|
||||
m_right->format_tree(builder);
|
||||
}
|
||||
|
||||
void UnaryOperation::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "UnaryOperation {}", unary_operator_names[to_underlying(m_operation)]);
|
||||
m_operand->format_tree(builder);
|
||||
}
|
||||
|
||||
void IsOneOfOperation::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "IsOneOf");
|
||||
m_operand->format_tree(builder);
|
||||
for (auto const& compare_value : m_compare_values)
|
||||
compare_value->format_tree(builder);
|
||||
}
|
||||
|
||||
void UnresolvedReference::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "UnresolvedReference {}", m_name);
|
||||
}
|
||||
|
||||
void ReturnExpression::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "ReturnExpression");
|
||||
m_return_value->format_tree(builder);
|
||||
}
|
||||
|
||||
void AssertExpression::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "AssertExpression");
|
||||
m_condition->format_tree(builder);
|
||||
}
|
||||
|
||||
void IfBranch::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "IfBranch");
|
||||
m_condition->format_tree(builder);
|
||||
m_branch->format_tree(builder);
|
||||
}
|
||||
|
||||
void ElseIfBranch::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "ElseIfBranch {}", m_condition.has_value() ? "ElseIf" : "Else");
|
||||
if (m_condition.has_value())
|
||||
(*m_condition)->format_tree(builder);
|
||||
m_branch->format_tree(builder);
|
||||
}
|
||||
|
||||
void TreeList::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "TreeList");
|
||||
for (auto const& expression : m_expressions)
|
||||
expression->format_tree(builder);
|
||||
}
|
||||
|
||||
void RecordDirectListInitialization::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "RecordDirectListInitialization");
|
||||
m_type_reference->format_tree(builder);
|
||||
for (auto const& argument : m_arguments)
|
||||
builder.appendff("{}{}", argument.name, argument.value);
|
||||
}
|
||||
|
||||
void FunctionCall::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "FunctionCall");
|
||||
m_name->format_tree(builder);
|
||||
for (auto const& argument : m_arguments)
|
||||
argument->format_tree(builder);
|
||||
}
|
||||
|
||||
void SlotName::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "Slot {}", m_member_name);
|
||||
}
|
||||
|
||||
void Variable::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "Var {}", m_name);
|
||||
}
|
||||
|
||||
void FunctionPointer::dump_tree(StringBuilder& builder)
|
||||
{
|
||||
dump_node(builder, "Func {}", m_function_name);
|
||||
}
|
||||
|
||||
}
|
39
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h
Normal file
39
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
|
||||
namespace JSSpecCompiler {
|
||||
|
||||
// AST/AST.h
|
||||
class NodeSubtreePointer;
|
||||
|
||||
class Node;
|
||||
using NullableTree = RefPtr<Node>;
|
||||
using Tree = NonnullRefPtr<Node>;
|
||||
class ErrorNode;
|
||||
|
||||
class ScopedBlock;
|
||||
class MathematicalConstant;
|
||||
class StringLiteral;
|
||||
class BinaryOperation;
|
||||
class UnaryOperation;
|
||||
class IsOneOfOperation;
|
||||
class UnresolvedReference;
|
||||
class ReturnExpression;
|
||||
class AssertExpression;
|
||||
class IfBranch;
|
||||
class ElseIfBranch;
|
||||
class TreeList;
|
||||
class RecordDirectListInitialization;
|
||||
class FunctionCall;
|
||||
class SlotName;
|
||||
class Variable;
|
||||
class FunctionPointer;
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue