JSSpecCompiler: Parse true, false, this, undefined, and null

This commit is contained in:
Dan Klishch 2024-01-20 21:41:38 -05:00 committed by Andrew Kaster
parent 86d54a8684
commit b800276347
Notes: sideshowbarker 2024-07-16 21:45:42 +09:00
7 changed files with 70 additions and 3 deletions

View file

@ -134,6 +134,11 @@ protected:
class WellKnownNode : public Expression {
public:
enum Type {
False,
Null,
This,
True,
Undefined,
ZeroArgumentFunctionCall,
// Update WellKnownNode::dump_tree after adding an entry here
};

View file

@ -38,6 +38,11 @@ void ErrorNode::dump_tree(StringBuilder& builder)
void WellKnownNode::dump_tree(StringBuilder& builder)
{
static constexpr StringView type_to_name[] = {
"False"sv,
"Null"sv,
"This"sv,
"True"sv,
"Undefined"sv,
"ZeroArgumentFunctionCall"sv,
};
dump_node(builder, "WellKnownNode {}", type_to_name[m_type]);

View file

@ -158,8 +158,8 @@ void tokenize_tree(SpecificationParsingContext& ctx, TokenizerState& state, XML:
if (contents.length() >= 2 && contents.starts_with('"') && contents.ends_with('"'))
tokens.append({ TokenType::String, contents.substring_view(1, contents.length() - 2), move(child_location) });
else if (contents == "undefined")
tokens.append({ TokenType::Undefined, contents, move(child_location) });
else if (contents.is_one_of("undefined", "null", "this", "true", "false"))
tokens.append({ TokenType::WellKnownValue, contents, move(child_location) });
else
tokens.append({ TokenType::Identifier, contents, move(child_location) });
return;

View file

@ -298,6 +298,24 @@ TextParseErrorOr<Tree> TextParser::parse_expression()
NullableTree expression;
if (token.type == TokenType::Identifier) {
expression = make_ref_counted<UnresolvedReference>(token.data);
} else if (token.type == TokenType::WellKnownValue) {
static constexpr struct {
StringView name;
WellKnownNode::Type type;
} translations[] = {
{ "false"sv, WellKnownNode::Type::False },
{ "null"sv, WellKnownNode::Type::Null },
{ "this"sv, WellKnownNode::Type::This },
{ "true"sv, WellKnownNode::Type::True },
{ "undefined"sv, WellKnownNode::Type::Undefined },
};
for (auto [name, type] : translations) {
if (token.data == name) {
expression = make_ref_counted<WellKnownNode>(type);
break;
}
}
VERIFY(expression);
} 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

@ -48,7 +48,7 @@ constexpr i32 closing_bracket_precedence = 18;
F(String, -1, Invalid, Invalid, Invalid, "string literal") \
F(Superscript, 4, Invalid, Power, Invalid, "subscript") \
F(UnaryMinus, 3, Minus, Invalid, Invalid, "unary minus") \
F(Undefined, -1, Invalid, Invalid, Invalid, "constant") \
F(WellKnownValue, -1, Invalid, Invalid, Invalid, "constant") \
F(Word, -1, Invalid, Invalid, Invalid, "word")
enum class TokenType {

View file

@ -13,4 +13,24 @@
</ol>
</emu-alg>
</emu-clause>
<emu-clause id="2" aoid="WellKnownConstants">
<h1><span class="secnum">2</span> WellKnownConstants ( <var>a</var> )</h1>
<emu-alg>
<ol>
<li>
If <var>a</var> is <emu-val>undefined</emu-val>, then
<ol>
<li>Let <var>b</var> be <emu-val>null</emu-val>.</li>
<li>Return <emu-val>true</emu-val>.</li>
</ol>
</li>
<li>Else,
<ol>
<li>Let <var>c</var> be <emu-val>this</emu-val>.</li>
<li>Return <emu-val>false</emu-val>.</li>
</ol>
</li>
</ol>
</emu-alg>
</emu-clause>
</specification>

View file

@ -27,3 +27,22 @@ TreeList
Var d
Var e
WellKnownConstants(a):
TreeList
IfElseIfChain
IsOneOf
Var a
WellKnownNode Undefined
TreeList
BinaryOperation Assignment
Var b
WellKnownNode Null
ReturnNode
WellKnownNode True
TreeList
BinaryOperation Assignment
Var c
WellKnownNode This
ReturnNode
WellKnownNode False