Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: condition #6

Merged
merged 14 commits into from
Feb 20, 2023
Prev Previous commit
Next Next commit
feat: complete if condition
  • Loading branch information
echosoar committed Feb 8, 2023
commit 238107f7c0a8adc424103d315f49da2ef8149cef
4 changes: 4 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ impl AST{
// class (ES2015)
Statement::Class(self.parse_class())
},
Token::LeftBrace => {
// block
self.parse_block_statement()
},
_ => {
let expression = self.parse_expression();
match expression {
Expand Down
65 changes: 41 additions & 24 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,34 +55,51 @@ impl Context {
let mut result_value = Value::Undefined;
let mut last_statement_value = Value::Undefined;
for statement in body.iter() {
match statement {
Statement::Var(var_statement) => {
for variable in var_statement.list.iter() {
if let Expression::Var(let_var) = variable {
let name = let_var.name.clone();
let mut value = self.execute_expression(&let_var.initializer);
value.bind_name(name.clone());
last_statement_value = value.clone();
(*self.cur_scope).borrow_mut().set_value(name, value);
}
self.call_statement(statement, &mut result_value, &mut last_statement_value);
}
(result_value, last_statement_value)
}

fn call_statement(&mut self, statement: &Statement, result_value: &mut Value, last_statement_value: &mut Value) {
match statement {
Statement::Var(var_statement) => {
for variable in var_statement.list.iter() {
if let Expression::Var(let_var) = variable {
let name = let_var.name.clone();
let mut value = self.execute_expression(&let_var.initializer);
value.bind_name(name.clone());
(*last_statement_value) = value.clone();
(*self.cur_scope).borrow_mut().set_value(name, value);
}
},
Statement::Expression(expression) => {
last_statement_value = self.execute_expression(&expression.expression);
},
Statement::Return(return_statement) => {
result_value = self.execute_expression(&return_statement.expression);
last_statement_value = result_value.clone()
},
Statement::Function(_) => {
// skip, 因为函数声明前置了
},
_ => {
println!("unknown statement {:?}", statement);
}
},
Statement::Expression(expression) => {
(*last_statement_value) = self.execute_expression(&expression.expression);
},
Statement::Return(return_statement) => {
(*result_value) = self.execute_expression(&return_statement.expression);
(*last_statement_value) = result_value.clone()
},
Statement::Function(_) => {
// skip, 因为函数声明前置了
},
Statement::If(if_statement) => {
let condition = self.execute_expression(&if_statement.condition);
if condition.to_boolean() {
self.call_statement(&if_statement.then_statement, result_value, last_statement_value);
} else {
self.call_statement(&if_statement.else_statement, result_value, last_statement_value);
}
},
Statement::Block(block) => {
self.switch_scope(Some(Rc::clone(&self.cur_scope)));
self.call_block(&vec![], &block.statements);
self.close_scope();
},
_ => {
println!("unknown statement {:?}", statement);
}
}
(result_value, last_statement_value)
}

fn execute_expression(&mut self, expression: &Expression) -> Value {
Expand Down
5 changes: 3 additions & 2 deletions tests/function_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ fn run_function_name_and_length() {
function abc(a, b, c) { } ;\n
let foo = function(x, y) {};\n
let obj = { x: function() {}};\n
{\n
let res = {\n
abc: { name: abc.name, length: abc.length},\n
foo: { name: foo.name, length: foo.length},\n
obj: { name: obj.x.name, length: obj.x.length},\n
};"));
};\n
res"));
let global_tmp = Rc::new(RefCell::new(Object::new(ClassType::Object,None)));
match value {
Value::Object(obj) => {
Expand Down
28 changes: 20 additions & 8 deletions tests/object_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ use jsi::{JSI, ast_node::{Expression, Statement, ObjectLiteral, ExpressionStatem
#[test]
fn ast_base() {
let mut jsi = JSI::new();
let program = jsi.parse(String::from("{a: 123, b: '123', [1 + 'a']: false}"));
let program = jsi.parse(String::from("let a = {a: 123, b: '123', [1 + 'a']: false}"));
let expr = match &program.body[0] {
Statement::Expression(expr_statement) => {
expr_statement.expression.clone()
Statement::Var(expr_statement) => {
if let Expression::Var(v) = &expr_statement.list[0] {
*v.initializer.clone()
} else {
Expression::Unknown
}
},
_ => Expression::Unknown,
};
Expand Down Expand Up @@ -37,9 +41,18 @@ fn ast_base() {
#[test]
fn ast_with_child_object() {
let mut jsi = JSI::new();
let program = jsi.parse(String::from("{obj: { x: false}}"));
assert_eq!(program.body, vec![Statement::Expression(ExpressionStatement {
expression: Expression::Object(ObjectLiteral {
let program = jsi.parse(String::from("let a = {obj: { x: false}}"));
let expr = match &program.body[0] {
Statement::Var(expr_statement) => {
if let Expression::Var(v) = &expr_statement.list[0] {
*v.initializer.clone()
} else {
Expression::Unknown
}
},
_ => Expression::Unknown,
};
assert_eq!(expr, Expression::Object(ObjectLiteral {
properties: vec![
PropertyAssignment{
name: Box::new(Expression::String(StringLiteral { literal: String::from("obj"), value: String::from("obj")})),
Expand All @@ -53,8 +66,7 @@ fn ast_with_child_object() {
})),
},
]
})
})]);
}));
}

#[test]
Expand Down