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: for cycle
  • Loading branch information
echosoar committed Feb 10, 2023
commit ca7e41b4b216892db36ed00a7818d8e5dc099268
17 changes: 3 additions & 14 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,25 +226,14 @@ impl AST{
let incrementor = self.parse_expression();
self.check_token_and_next(Token::RightParenthesis);
println!("incrementor: {:?} {:?}", incrementor , self.token);

let block = self.parse_block_statement();
let statement = ForStatement {
initializer: Box::new(initializer),
codition: codition,
incrementor: incrementor,
statement: Box::new(Statement::Unknown),
statement: Box::new(block),
};
// self.check_token_and_next(Token::RightParenthesis);
// // 判断是否是 单行if
// if self.token == Token::LeftBrace {
// statement.then_statement = Box::new(self.parse_block_statement());
// } else {
// statement.then_statement = Box::new(self.parse_statement());
// }

// if self.token == Token::Else {
// self.next();
// statement.else_statement = Box::new(self.parse_statement());
// }
// return Statement::If(statement)
return Statement::For(statement);
}

Expand Down
99 changes: 98 additions & 1 deletion src/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{rc::{Rc, Weak}, cell::RefCell};

use crate::{ast::Program, ast_node::{Statement, Declaration, ObjectLiteral, AssignExpression, CallContext, ArrayLiteral, ClassType}, ast_node::{Expression, CallExpression, Keywords, BinaryExpression}, value::{Value, ValueInfo}, scope::{Scope, get_value_and_scope}, ast_token::Token, builtins::{object::{Object, Property, create_object}, function::{create_function, get_function_this}, global::{new_global_this, get_global_object}, array::create_array}};
use crate::{ast::Program, ast_node::{Statement, Declaration, ObjectLiteral, AssignExpression, CallContext, ArrayLiteral, ClassType, ForStatement, VariableFlag, PostfixUnaryExpression}, ast_node::{Expression, CallExpression, Keywords, BinaryExpression}, value::{Value, ValueInfo}, scope::{Scope, get_value_and_scope}, ast_token::Token, builtins::{object::{Object, Property, create_object}, function::{create_function, get_function_this}, global::{new_global_this, get_global_object}, array::create_array}};

use super::ast::AST;
pub struct Context {
Expand Down Expand Up @@ -63,6 +63,7 @@ impl Context {
fn call_statement(&mut self, statement: &Statement, result_value: &mut Value, last_statement_value: &mut Value) {
match statement {
Statement::Var(var_statement) => {
// var_statement.flag 是 var 还是 let,在上层调用链路中处理
for variable in var_statement.list.iter() {
if let Expression::Var(let_var) = variable {
let name = let_var.name.clone();
Expand Down Expand Up @@ -91,6 +92,7 @@ impl Context {
self.call_statement(&if_statement.else_statement, result_value, last_statement_value);
}
},
Statement::For(for_statment) => self.execute_for(for_statment),
Statement::Block(block) => {
self.switch_scope(Some(Rc::clone(&self.cur_scope)));
self.call_block(&vec![], &block.statements);
Expand All @@ -112,6 +114,9 @@ impl Context {
Expression::Binary(binary) => {
ValueInfo { value: self.execute_binary_expression(binary), name: None, reference: None }
},
Expression::PostfixUnary(expr) => {
ValueInfo { value: self.execute_postfix_unary_expression(expr), name: None, reference: None }
},
Expression::Call(call) => {
ValueInfo { value: self.execute_call_expression(call), name: None, reference: None }
},
Expand Down Expand Up @@ -221,6 +226,7 @@ impl Context {
// 计算数字运算
self.execute_number_operator_expression(&left, &right, &expression.operator)
},
Token::Less | Token::Greater => self.execute_compare_operator_expression(&left, &right, &expression.operator),
_ => Value::Undefined
}

Expand Down Expand Up @@ -250,6 +256,27 @@ impl Context {
}
}

// 执行方法调用表达式
fn execute_compare_operator_expression(&mut self, left: &Value, right: &Value, operator: &Token) -> Value {
let left_number: f64;
let right_number: f64;
if let Some(num) = left.to_number() {
left_number = num;
} else {
return Value::NAN;
}
if let Some(num) = right.to_number() {
right_number = num;
} else {
return Value::NAN;
}
match operator {
Token::Greater => Value::Boolean(left_number > right_number),
Token::Less => Value::Boolean(left_number < right_number),
_=> Value::NAN,
}
}

// 执行方法调用表达式
fn execute_call_expression(&mut self, expression: &CallExpression) -> Value {
let callee = self.execute_expression_info(expression.expression.as_ref());
Expand Down Expand Up @@ -281,6 +308,76 @@ impl Context {
}
}

// 执行 i++ i--
fn execute_postfix_unary_expression(&mut self, expression: &PostfixUnaryExpression) -> Value {
let mut operand_info = self.execute_expression_info(&expression.operand);
let origin_value = operand_info.value.clone();
let mut new_value = origin_value.to_number().unwrap();
match &expression.operator {
Token::Increment => {
new_value = new_value + 1f64;
},
Token::Decrement => {
new_value = new_value - 1f64;
},
_ => {}
}
operand_info.set_value(Value::Number(new_value));
origin_value
}

// 执行循环
fn execute_for(&mut self, for_statment: &ForStatement) {
let mut is_change_scope = false;
let initializer = *for_statment.initializer.clone();
let mut result = Value::Undefined;
let mut last_statment_value = Value::Undefined;
if let Statement::Var(var) = &initializer {
if var.flag == VariableFlag::Var {
self.call_statement(&initializer, &mut result, &mut last_statment_value)
} else if var.flag == VariableFlag::Let {
self.switch_scope(Some(Rc::clone(&self.cur_scope)));
is_change_scope = true;
self.call_statement(&initializer, &mut result, &mut last_statment_value)
}
} else if let Statement::Unknown = &initializer {
// nothing to do
} else {
self.call_statement(&initializer, &mut result, &mut last_statment_value)
}

if !is_change_scope {
self.switch_scope(Some(Rc::clone(&self.cur_scope)));
}

loop {
let condition = &for_statment.codition;
if let Expression::Unknown = condition {
// nothing to do
} else {
let value = self.execute_expression(condition);
if !value.to_boolean() {
break;
}
}

// TODO: expression
if let Statement::Block(block) = for_statment.statement.as_ref() {
// TODO: break, break label, continue, continue label
self.call_block(&vec![], &block.statements);
}

let incrementor = &for_statment.incrementor;
if let Expression::Unknown = condition {
// nothing to do
} else {
self.execute_expression(incrementor);
}
}

self.close_scope();
}

fn new_object(&mut self, expression: &ObjectLiteral) -> Value {
// 获取 object 实例
let object = create_object(&self.global,ClassType::Array, None);
Expand Down