mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 19:37:35 +00:00
LibJS: Defer Value construction until a Literal is executed
Remove the need to construct a full Value during parsing. This means we don't have to worry about plumbing the heap into the parser. The Literal ASTNode now has a bunch of subclasses that synthesize a Value on demand.
This commit is contained in:
parent
4d942cc1d0
commit
425fd3ce51
3 changed files with 73 additions and 8 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <LibJS/AST.h>
|
#include <LibJS/AST.h>
|
||||||
#include <LibJS/Function.h>
|
#include <LibJS/Function.h>
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
|
#include <LibJS/PrimitiveString.h>
|
||||||
#include <LibJS/Value.h>
|
#include <LibJS/Value.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -262,10 +263,22 @@ void CallExpression::dump(int indent) const
|
||||||
printf("%s '%s'\n", class_name(), name().characters());
|
printf("%s '%s'\n", class_name(), name().characters());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Literal::dump(int indent) const
|
void StringLiteral::dump(int indent) const
|
||||||
{
|
{
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
printf("Literal _%s_\n", m_value.to_string().characters());
|
printf("StringLiteral \"%s\"\n", m_value.characters());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NumericLiteral::dump(int indent) const
|
||||||
|
{
|
||||||
|
print_indent(indent);
|
||||||
|
printf("NumberLiteral %g\n", m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BooleanLiteral::dump(int indent) const
|
||||||
|
{
|
||||||
|
print_indent(indent);
|
||||||
|
printf("BooleanLiteral %s\n", m_value ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionDeclaration::dump(int indent) const
|
void FunctionDeclaration::dump(int indent) const
|
||||||
|
@ -415,4 +428,19 @@ Value MemberExpression::execute(Interpreter& interpreter) const
|
||||||
return object_result.as_object()->get(property_name);
|
return object_result.as_object()->get(property_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value StringLiteral::execute(Interpreter& interpreter) const
|
||||||
|
{
|
||||||
|
return Value(js_string(interpreter.heap(), m_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Value NumericLiteral::execute(Interpreter&) const
|
||||||
|
{
|
||||||
|
return Value(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value BooleanLiteral::execute(Interpreter&) const
|
||||||
|
{
|
||||||
|
return Value(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,19 +290,56 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class Literal : public Expression {
|
class Literal : public Expression {
|
||||||
|
protected:
|
||||||
|
explicit Literal() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BooleanLiteral final : public Literal {
|
||||||
public:
|
public:
|
||||||
explicit Literal(Value value)
|
explicit BooleanLiteral(bool value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Value execute(Interpreter&) const override;
|
||||||
|
virtual void dump(int indent) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual const char* class_name() const override { return "BooleanLiteral"; }
|
||||||
|
|
||||||
|
bool m_value { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
class NumericLiteral final : public Literal {
|
||||||
|
public:
|
||||||
|
explicit NumericLiteral(double value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Value execute(Interpreter&) const override;
|
||||||
|
virtual void dump(int indent) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual const char* class_name() const override { return "NumericLiteral"; }
|
||||||
|
|
||||||
|
double m_value { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
class StringLiteral final : public Literal {
|
||||||
|
public:
|
||||||
|
explicit StringLiteral(String value)
|
||||||
: m_value(move(value))
|
: m_value(move(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Value execute(Interpreter&) const override { return m_value; }
|
virtual Value execute(Interpreter&) const override;
|
||||||
virtual void dump(int indent) const override;
|
virtual void dump(int indent) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual const char* class_name() const override { return "Literal"; }
|
virtual const char* class_name() const override { return "StringLiteral"; }
|
||||||
|
|
||||||
Value m_value;
|
String m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Identifier final : public Expression {
|
class Identifier final : public Expression {
|
||||||
|
|
|
@ -86,9 +86,9 @@ NonnullOwnPtr<Expression> Parser::parse_primary_expression()
|
||||||
case TokenType::Identifier:
|
case TokenType::Identifier:
|
||||||
return make<Identifier>(consume().value());
|
return make<Identifier>(consume().value());
|
||||||
case TokenType::NumericLiteral:
|
case TokenType::NumericLiteral:
|
||||||
return make<Literal>(Value(consume().double_value()));
|
return make<NumericLiteral>(consume().double_value());
|
||||||
case TokenType::BoolLiteral:
|
case TokenType::BoolLiteral:
|
||||||
return make<Literal>(Value(consume().bool_value()));
|
return make<BooleanLiteral>(consume().bool_value());
|
||||||
case TokenType::CurlyOpen:
|
case TokenType::CurlyOpen:
|
||||||
return parse_object_expression();
|
return parse_object_expression();
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue