srctree

Robin Linden parent 1f2bd5ab 023febe9
js: Add support for IfStatements

inlinesplit
js/ast.h added: 46, removed: 4, total 42
@@ -23,6 +23,7 @@ struct CallExpression;
struct ExpressionStatement;
struct FunctionDeclaration;
struct Identifier;
struct IfStatement;
struct NumericLiteral;
struct Program;
struct StringLiteral;
@@ -32,7 +33,7 @@ struct VariableDeclarator;
using Declaration = std::variant<FunctionDeclaration, VariableDeclaration>;
using Literal = std::variant<NumericLiteral, StringLiteral>;
using Pattern = std::variant<Identifier>;
using Statement = std::variant<Declaration, ExpressionStatement, BlockStatement, ReturnStatement>;
using Statement = std::variant<Declaration, ExpressionStatement, BlockStatement, ReturnStatement, IfStatement>;
using Expression = std::variant<Identifier, Literal, CallExpression, BinaryExpression>;
using Node = std::variant<Expression, Statement, Pattern, Program, Function, VariableDeclarator>;
 
@@ -147,6 +148,12 @@ struct ReturnStatement {
std::optional<Expression> argument;
};
 
struct IfStatement {
Expression test;
std::shared_ptr<Statement> if_branch;
std::optional<std::shared_ptr<Statement>> else_branch;
};
 
} // namespace ast
} // namespace js
 
 
js/ast_executor.h added: 46, removed: 4, total 42
@@ -107,6 +107,14 @@ public:
return Value{};
}
 
Value operator()(IfStatement const &v) {
if (execute(v.test).as_bool()) {
return execute(*v.if_branch);
}
 
return v.else_branch ? execute(**v.else_branch) : Value{};
}
 
std::map<std::string, Value, std::less<>> variables;
std::optional<Value> returning;
};
 
js/ast_executor_test.cpp added: 46, removed: 4, total 42
@@ -133,5 +133,32 @@ int main() {
expect_eq(e.execute(ExpressionStatement{NumericLiteral{1213}}), Value{1213});
});
 
etest::test("if", [] {
auto if_stmt = IfStatement{
.test = NumericLiteral{1},
.if_branch = std::make_shared<Statement>(ExpressionStatement{StringLiteral{"true!"}}),
};
 
AstExecutor e;
expect_eq(e.execute(if_stmt), Value{"true!"});
 
if_stmt.test = NumericLiteral{0};
expect_eq(e.execute(if_stmt), Value{});
});
 
etest::test("if-else", [] {
auto if_stmt = IfStatement{
.test = NumericLiteral{1},
.if_branch = std::make_shared<Statement>(ExpressionStatement{StringLiteral{"true!"}}),
.else_branch = std::make_shared<Statement>(ExpressionStatement{StringLiteral{"false!"}}),
};
 
AstExecutor e;
expect_eq(e.execute(if_stmt), Value{"true!"});
 
if_stmt.test = NumericLiteral{0};
expect_eq(e.execute(if_stmt), Value{"false!"});
});
 
return etest::run_all_tests();
}