mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 03:58:12 +00:00
JSSpecCompiler: Parse enumerators in xspec mode
This commit is contained in:
parent
3d365326af
commit
990e30f458
13 changed files with 69 additions and 0 deletions
|
@ -523,6 +523,20 @@ protected:
|
||||||
void dump_tree(StringBuilder& builder) override;
|
void dump_tree(StringBuilder& builder) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Enumerator : public Expression {
|
||||||
|
public:
|
||||||
|
Enumerator(Badge<TranslationUnit>, StringView value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dump_tree(StringBuilder& builder) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StringView m_value;
|
||||||
|
};
|
||||||
|
|
||||||
class FunctionPointer : public Expression {
|
class FunctionPointer : public Expression {
|
||||||
public:
|
public:
|
||||||
FunctionPointer(FunctionDeclarationRef declaration)
|
FunctionPointer(FunctionDeclarationRef declaration)
|
||||||
|
|
|
@ -178,6 +178,11 @@ void Variable::dump_tree(StringBuilder& builder)
|
||||||
dump_node(builder, "Var {}", name());
|
dump_node(builder, "Var {}", name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Enumerator::dump_tree(StringBuilder& builder)
|
||||||
|
{
|
||||||
|
dump_node(builder, "Enumerator {}", m_value);
|
||||||
|
}
|
||||||
|
|
||||||
void FunctionPointer::dump_tree(StringBuilder& builder)
|
void FunctionPointer::dump_tree(StringBuilder& builder)
|
||||||
{
|
{
|
||||||
dump_node(builder, "Func \"{}\"", m_declaration->m_name);
|
dump_node(builder, "Func \"{}\"", m_declaration->m_name);
|
||||||
|
|
|
@ -45,6 +45,8 @@ class TreeList;
|
||||||
class RecordDirectListInitialization;
|
class RecordDirectListInitialization;
|
||||||
class FunctionCall;
|
class FunctionCall;
|
||||||
class SlotName;
|
class SlotName;
|
||||||
|
class Enumerator;
|
||||||
|
using EnumeratorRef = NonnullRefPtr<Enumerator>;
|
||||||
class Variable;
|
class Variable;
|
||||||
using VariableRef = NonnullRefPtr<Variable>;
|
using VariableRef = NonnullRefPtr<Variable>;
|
||||||
class FunctionPointer;
|
class FunctionPointer;
|
||||||
|
|
|
@ -40,6 +40,16 @@ FunctionDeclarationRef TranslationUnit::find_declaration_by_name(StringView name
|
||||||
return it->value;
|
return it->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnumeratorRef TranslationUnit::get_node_for_enumerator_value(StringView value)
|
||||||
|
{
|
||||||
|
if (auto it = m_enumerator_nodes.find(value); it != m_enumerator_nodes.end())
|
||||||
|
return it->value;
|
||||||
|
|
||||||
|
auto enumerator = NonnullRefPtr(NonnullRefPtr<Enumerator>::Adopt, *new Enumerator { {}, value });
|
||||||
|
m_enumerator_nodes.set(value, enumerator);
|
||||||
|
return enumerator;
|
||||||
|
}
|
||||||
|
|
||||||
FunctionDeclaration::FunctionDeclaration(StringView name, Vector<FunctionArgument>&& arguments)
|
FunctionDeclaration::FunctionDeclaration(StringView name, Vector<FunctionArgument>&& arguments)
|
||||||
: m_name(name)
|
: m_name(name)
|
||||||
, m_arguments(arguments)
|
, m_arguments(arguments)
|
||||||
|
|
|
@ -30,12 +30,15 @@ public:
|
||||||
DiagnosticEngine& diag() { return m_diagnostic_engine; }
|
DiagnosticEngine& diag() { return m_diagnostic_engine; }
|
||||||
Vector<FunctionDefinitionRef> functions_to_compile() const { return m_functions_to_compile; }
|
Vector<FunctionDefinitionRef> functions_to_compile() const { return m_functions_to_compile; }
|
||||||
|
|
||||||
|
EnumeratorRef get_node_for_enumerator_value(StringView value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringView m_filename;
|
StringView m_filename;
|
||||||
DiagnosticEngine m_diagnostic_engine;
|
DiagnosticEngine m_diagnostic_engine;
|
||||||
Vector<FunctionDefinitionRef> m_functions_to_compile;
|
Vector<FunctionDefinitionRef> m_functions_to_compile;
|
||||||
Vector<NonnullRefPtr<FunctionDeclaration>> m_declarations_owner;
|
Vector<NonnullRefPtr<FunctionDeclaration>> m_declarations_owner;
|
||||||
HashMap<StringView, FunctionDeclarationRef> m_function_index;
|
HashMap<StringView, FunctionDeclarationRef> m_function_index;
|
||||||
|
HashMap<StringView, EnumeratorRef> m_enumerator_nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionArgument {
|
struct FunctionArgument {
|
||||||
|
|
|
@ -185,6 +185,15 @@ void tokenize_tree(SpecificationParsingContext& ctx, TokenizerState& state, XML:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element.name == tag_emu_const) {
|
||||||
|
auto maybe_contents = get_text_contents(child);
|
||||||
|
if (!maybe_contents.has_value())
|
||||||
|
report_error("malformed <emu-const> subtree, expected single text child node");
|
||||||
|
|
||||||
|
tokens.append({ TokenType::Enumerator, maybe_contents.value_or(""sv), move(child_location) });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (tree_type == TreeType::Header && element.name == tag_span) {
|
if (tree_type == TreeType::Header && element.name == tag_span) {
|
||||||
auto element_class = get_attribute_by_name(child, attribute_class);
|
auto element_class = get_attribute_by_name(child, attribute_class);
|
||||||
if (element_class != class_secnum)
|
if (element_class != class_secnum)
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace JSSpecCompiler {
|
||||||
|
|
||||||
inline constexpr StringView tag_emu_alg = "emu-alg"sv;
|
inline constexpr StringView tag_emu_alg = "emu-alg"sv;
|
||||||
inline constexpr StringView tag_emu_clause = "emu-clause"sv;
|
inline constexpr StringView tag_emu_clause = "emu-clause"sv;
|
||||||
|
inline constexpr StringView tag_emu_const = "emu-const"sv;
|
||||||
inline constexpr StringView tag_emu_import = "emu-import"sv;
|
inline constexpr StringView tag_emu_import = "emu-import"sv;
|
||||||
inline constexpr StringView tag_emu_intro = "emu-intro"sv;
|
inline constexpr StringView tag_emu_intro = "emu-intro"sv;
|
||||||
inline constexpr StringView tag_emu_val = "emu-val"sv;
|
inline constexpr StringView tag_emu_val = "emu-val"sv;
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
|
|
||||||
namespace JSSpecCompiler {
|
namespace JSSpecCompiler {
|
||||||
|
|
||||||
|
TranslationUnitRef SpecificationParsingContext::translation_unit()
|
||||||
|
{
|
||||||
|
return m_translation_unit;
|
||||||
|
}
|
||||||
|
|
||||||
DiagnosticEngine& SpecificationParsingContext::diag()
|
DiagnosticEngine& SpecificationParsingContext::diag()
|
||||||
{
|
{
|
||||||
return m_translation_unit->diag();
|
return m_translation_unit->diag();
|
||||||
|
|
|
@ -26,6 +26,7 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TranslationUnitRef translation_unit();
|
||||||
DiagnosticEngine& diag();
|
DiagnosticEngine& diag();
|
||||||
|
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
|
|
|
@ -316,6 +316,8 @@ TextParseErrorOr<Tree> TextParser::parse_expression()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VERIFY(expression);
|
VERIFY(expression);
|
||||||
|
} else if (token.type == TokenType::Enumerator) {
|
||||||
|
expression = m_ctx.translation_unit()->get_node_for_enumerator_value(token.data);
|
||||||
} else if (token.type == TokenType::Number) {
|
} else if (token.type == TokenType::Number) {
|
||||||
expression = make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(token.data)));
|
expression = make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(token.data)));
|
||||||
} else if (token.type == TokenType::String) {
|
} else if (token.type == TokenType::String) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ constexpr i32 closing_bracket_precedence = 18;
|
||||||
F(Comma, 17, Invalid, Comma, Invalid, "','") \
|
F(Comma, 17, Invalid, Comma, Invalid, "','") \
|
||||||
F(Division, 5, Invalid, Division, Invalid, "division") \
|
F(Division, 5, Invalid, Division, Invalid, "division") \
|
||||||
F(Dot, -1, Invalid, Invalid, Invalid, "punctuation mark '.'") \
|
F(Dot, -1, Invalid, Invalid, Invalid, "punctuation mark '.'") \
|
||||||
|
F(Enumerator, -1, Invalid, Invalid, Invalid, "enumerator") \
|
||||||
F(Equals, 10, Invalid, CompareEqual, Invalid, "equals") \
|
F(Equals, 10, Invalid, CompareEqual, Invalid, "equals") \
|
||||||
F(ExclamationMark, 3, AssertCompletion, Invalid, Invalid, "exclamation mark") \
|
F(ExclamationMark, 3, AssertCompletion, Invalid, Invalid, "exclamation mark") \
|
||||||
F(FunctionCall, 2, Invalid, FunctionCall, Invalid, "function call token") \
|
F(FunctionCall, 2, Invalid, FunctionCall, Invalid, "function call token") \
|
||||||
|
|
|
@ -41,4 +41,12 @@
|
||||||
</ol>
|
</ol>
|
||||||
</emu-alg>
|
</emu-alg>
|
||||||
</emu-clause>
|
</emu-clause>
|
||||||
|
<emu-clause id="4" aoid="Enumerators">
|
||||||
|
<h1><span class="secnum">4</span> Enumerators ( )</h1>
|
||||||
|
<emu-alg>
|
||||||
|
<ol>
|
||||||
|
<li>Return ? <emu-xref><a>WellKnownConstants</a></emu-xref>(<emu-const>enumerator</emu-const>).</li>
|
||||||
|
</ol>
|
||||||
|
</emu-alg>
|
||||||
|
</emu-clause>
|
||||||
</specification>
|
</specification>
|
||||||
|
|
|
@ -54,3 +54,11 @@ TreeList
|
||||||
Func "WellKnownConstants"
|
Func "WellKnownConstants"
|
||||||
Var a
|
Var a
|
||||||
|
|
||||||
|
Enumerators():
|
||||||
|
TreeList
|
||||||
|
ReturnNode
|
||||||
|
UnaryOperation ReturnIfAbrubt
|
||||||
|
FunctionCall
|
||||||
|
Func "WellKnownConstants"
|
||||||
|
Enumerator enumerator
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue