JSSpecCompiler: Parse enumerators in xspec mode

This commit is contained in:
Dan Klishch 2024-01-20 22:10:07 -05:00 committed by Andrew Kaster
parent 3d365326af
commit 990e30f458
Notes: sideshowbarker 2024-07-17 08:25:15 +09:00
13 changed files with 69 additions and 0 deletions

View file

@ -523,6 +523,20 @@ protected:
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 {
public:
FunctionPointer(FunctionDeclarationRef declaration)

View file

@ -178,6 +178,11 @@ void Variable::dump_tree(StringBuilder& builder)
dump_node(builder, "Var {}", name());
}
void Enumerator::dump_tree(StringBuilder& builder)
{
dump_node(builder, "Enumerator {}", m_value);
}
void FunctionPointer::dump_tree(StringBuilder& builder)
{
dump_node(builder, "Func \"{}\"", m_declaration->m_name);

View file

@ -45,6 +45,8 @@ class TreeList;
class RecordDirectListInitialization;
class FunctionCall;
class SlotName;
class Enumerator;
using EnumeratorRef = NonnullRefPtr<Enumerator>;
class Variable;
using VariableRef = NonnullRefPtr<Variable>;
class FunctionPointer;

View file

@ -40,6 +40,16 @@ FunctionDeclarationRef TranslationUnit::find_declaration_by_name(StringView name
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)
: m_name(name)
, m_arguments(arguments)

View file

@ -30,12 +30,15 @@ public:
DiagnosticEngine& diag() { return m_diagnostic_engine; }
Vector<FunctionDefinitionRef> functions_to_compile() const { return m_functions_to_compile; }
EnumeratorRef get_node_for_enumerator_value(StringView value);
private:
StringView m_filename;
DiagnosticEngine m_diagnostic_engine;
Vector<FunctionDefinitionRef> m_functions_to_compile;
Vector<NonnullRefPtr<FunctionDeclaration>> m_declarations_owner;
HashMap<StringView, FunctionDeclarationRef> m_function_index;
HashMap<StringView, EnumeratorRef> m_enumerator_nodes;
};
struct FunctionArgument {

View file

@ -185,6 +185,15 @@ void tokenize_tree(SpecificationParsingContext& ctx, TokenizerState& state, XML:
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) {
auto element_class = get_attribute_by_name(child, attribute_class);
if (element_class != class_secnum)

View file

@ -12,6 +12,7 @@ namespace JSSpecCompiler {
inline constexpr StringView tag_emu_alg = "emu-alg"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_intro = "emu-intro"sv;
inline constexpr StringView tag_emu_val = "emu-val"sv;

View file

@ -16,6 +16,11 @@
namespace JSSpecCompiler {
TranslationUnitRef SpecificationParsingContext::translation_unit()
{
return m_translation_unit;
}
DiagnosticEngine& SpecificationParsingContext::diag()
{
return m_translation_unit->diag();

View file

@ -26,6 +26,7 @@ public:
{
}
TranslationUnitRef translation_unit();
DiagnosticEngine& diag();
template<typename Func>

View file

@ -316,6 +316,8 @@ TextParseErrorOr<Tree> TextParser::parse_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) {
expression = make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(token.data)));
} else if (token.type == TokenType::String) {

View file

@ -30,6 +30,7 @@ constexpr i32 closing_bracket_precedence = 18;
F(Comma, 17, Invalid, Comma, Invalid, "','") \
F(Division, 5, Invalid, Division, Invalid, "division") \
F(Dot, -1, Invalid, Invalid, Invalid, "punctuation mark '.'") \
F(Enumerator, -1, Invalid, Invalid, Invalid, "enumerator") \
F(Equals, 10, Invalid, CompareEqual, Invalid, "equals") \
F(ExclamationMark, 3, AssertCompletion, Invalid, Invalid, "exclamation mark") \
F(FunctionCall, 2, Invalid, FunctionCall, Invalid, "function call token") \

View file

@ -41,4 +41,12 @@
</ol>
</emu-alg>
</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>

View file

@ -54,3 +54,11 @@ TreeList
Func "WellKnownConstants"
Var a
Enumerators():
TreeList
ReturnNode
UnaryOperation ReturnIfAbrubt
FunctionCall
Func "WellKnownConstants"
Enumerator enumerator