fix Scope init
This commit is contained in:
parent
3011542376
commit
79422951c7
@ -6,30 +6,24 @@ use full_moon::ast::*;
|
|||||||
use crate::visitor::Visitor;
|
use crate::visitor::Visitor;
|
||||||
|
|
||||||
pub struct ConstantFolder {
|
pub struct ConstantFolder {
|
||||||
locals: Box<Vec<expression_reducer::Variable>>,
|
scope: scope::Scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstantFolder {
|
impl ConstantFolder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ConstantFolder {
|
ConstantFolder {
|
||||||
locals: Box::new(vec![]),
|
scope: scope::Scope::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_local(&mut self, name: String, value: Option<Expression>) {
|
fn register_local(&mut self, name: String, value: Option<Expression>) {
|
||||||
let locals = &*self.locals;
|
let var = expression_reducer::Variable::with_value(name, value, &self.scope);
|
||||||
let var = expression_reducer::Variable::with_value(name, value, locals);
|
self.scope.push_var(var);
|
||||||
self.locals.push(var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign(&mut self, name: String, value: Option<Expression>) {
|
fn assign(&mut self, name: String, value: Option<Expression>) {
|
||||||
let locals = &*self.locals;
|
let var = expression_reducer::Variable::with_value(name, value, &self.scope);
|
||||||
let var = expression_reducer::Variable::with_value(name, value, locals);
|
self.scope.set_var(var);
|
||||||
{
|
|
||||||
let mut iter = self.locals.iter_mut();
|
|
||||||
let it = iter.find(|it| it.name() == var.name());
|
|
||||||
it.map(|old| old.assign_value(var));
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +59,7 @@ impl Visitor for ConstantFolder {
|
|||||||
println!("visit function_call {}", function_call);
|
println!("visit function_call {}", function_call);
|
||||||
let reduced = expression_reducer::reduce_expression_value_function_call(
|
let reduced = expression_reducer::reduce_expression_value_function_call(
|
||||||
function_call.clone(),
|
function_call.clone(),
|
||||||
&*self.locals,
|
&self.scope,
|
||||||
);
|
);
|
||||||
println!("{:?}", reduced);
|
println!("{:?}", reduced);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,8 @@
|
|||||||
|
|
||||||
use full_moon::ast;
|
use full_moon::ast;
|
||||||
|
|
||||||
|
use crate::visitor::constant_folder::scope::Scope;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Variable {
|
pub struct Variable {
|
||||||
n: String,
|
n: String,
|
||||||
@ -65,9 +67,8 @@ pub struct Variable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Variable {
|
impl Variable {
|
||||||
pub fn with_value(name: String, expr: Option<ast::Expression>, locals: &Vec<Variable>) -> Self {
|
pub fn with_value(name: String, expr: Option<ast::Expression>, scope: &Scope) -> Self {
|
||||||
let v = Expression::reduce(expr, locals);
|
let v = Expression::reduce(expr, scope);
|
||||||
println!("variable_with {} = {:?}", name, v);
|
|
||||||
Self { n: name, v: v }
|
Self { n: name, v: v }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ impl Variable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_value(&mut self, var: Self) {
|
pub fn assign_value(&mut self, var: Self) {
|
||||||
println!("variable_assign {} = {:?}", self.n, var.v);
|
// println!("{} = {:?}", self.n, var.v);
|
||||||
self.v = var.v;
|
self.v = var.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,14 +162,14 @@ pub struct Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn reduce(expr: Option<ast::Expression>, locals: &Vec<Variable>) -> Self {
|
pub fn reduce(expr: Option<ast::Expression>, scope: &Scope) -> Self {
|
||||||
if expr.is_none() {
|
if expr.is_none() {
|
||||||
Expression {
|
Expression {
|
||||||
t: ExpressionType::Nil,
|
t: ExpressionType::Nil,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let expr = expr.unwrap();
|
let expr = expr.unwrap();
|
||||||
reduce_expression(expr, locals)
|
reduce_expression(expr, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,30 +195,30 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_expression(expr: ast::Expression, locals: &Vec<Variable>) -> Expression {
|
fn reduce_expression(expr: ast::Expression, scope: &Scope) -> Expression {
|
||||||
match expr {
|
match expr {
|
||||||
ast::Expression::BinaryOperator { lhs, rhs, binop } => {
|
ast::Expression::BinaryOperator { lhs, rhs, binop } => {
|
||||||
let lhs_ = reduce_expression(*lhs, locals);
|
let lhs_ = reduce_expression(*lhs, scope);
|
||||||
let rhs_ = reduce_expression(*rhs, locals);
|
let rhs_ = reduce_expression(*rhs, scope);
|
||||||
apply_binary_operator(lhs_, rhs_, binop)
|
apply_binary_operator(lhs_, rhs_, binop)
|
||||||
}
|
}
|
||||||
ast::Expression::Parentheses { expression, .. } => reduce_expression(*expression, locals),
|
ast::Expression::Parentheses { expression, .. } => reduce_expression(*expression, scope),
|
||||||
ast::Expression::UnaryOperator { unop, expression } => {
|
ast::Expression::UnaryOperator { unop, expression } => {
|
||||||
let expression_ = reduce_expression(*expression, locals);
|
let expression_ = reduce_expression(*expression, scope);
|
||||||
apply_unary_operator(expression_, unop)
|
apply_unary_operator(expression_, unop)
|
||||||
}
|
}
|
||||||
ast::Expression::Value { value } => reduce_expression_value(*value, locals),
|
ast::Expression::Value { value } => reduce_expression_value(*value, scope),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_expression_value(value: ast::Value, locals: &Vec<Variable>) -> Expression {
|
fn reduce_expression_value(value: ast::Value, scope: &Scope) -> Expression {
|
||||||
match value {
|
match value {
|
||||||
ast::Value::Function(_function) => {
|
ast::Value::Function(_function) => {
|
||||||
panic!("reduce Expression::Function is unsupported");
|
panic!("reduce Expression::Function is unsupported");
|
||||||
}
|
}
|
||||||
ast::Value::FunctionCall(function_call) => {
|
ast::Value::FunctionCall(function_call) => {
|
||||||
reduce_expression_value_function_call(function_call, locals)
|
reduce_expression_value_function_call(function_call, scope)
|
||||||
}
|
}
|
||||||
ast::Value::TableConstructor(_table_constructor) => {
|
ast::Value::TableConstructor(_table_constructor) => {
|
||||||
panic!("reduce Expression::TableConstructor is unsupported");
|
panic!("reduce Expression::TableConstructor is unsupported");
|
||||||
@ -229,7 +230,7 @@ fn reduce_expression_value(value: ast::Value, locals: &Vec<Variable>) -> Express
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Value::ParenthesesExpression(parentheses_expression) => {
|
ast::Value::ParenthesesExpression(parentheses_expression) => {
|
||||||
reduce_expression(parentheses_expression, locals)
|
reduce_expression(parentheses_expression, scope)
|
||||||
}
|
}
|
||||||
ast::Value::String(string) => Expression {
|
ast::Value::String(string) => Expression {
|
||||||
t: ExpressionType::String(string.token().to_string()),
|
t: ExpressionType::String(string.token().to_string()),
|
||||||
@ -248,12 +249,12 @@ fn reduce_expression_value(value: ast::Value, locals: &Vec<Variable>) -> Express
|
|||||||
panic!("reduce Expression::Symbol is not true/false");
|
panic!("reduce Expression::Symbol is not true/false");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Value::Var(var) => reduce_expression_value_var(var, locals),
|
ast::Value::Var(var) => reduce_expression_value_var(var, scope),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_expression_value_var(var: ast::Var, locals: &Vec<Variable>) -> Expression {
|
fn reduce_expression_value_var(var: ast::Var, scope: &Scope) -> Expression {
|
||||||
match var {
|
match var {
|
||||||
ast::Var::Expression(expr) => {
|
ast::Var::Expression(expr) => {
|
||||||
let prefix = {
|
let prefix = {
|
||||||
@ -270,8 +271,7 @@ fn reduce_expression_value_var(var: ast::Var, locals: &Vec<Variable>) -> Express
|
|||||||
})
|
})
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let local_var = locals.iter().find(|it| it.name() == prefix);
|
match scope.find_name(&prefix) {
|
||||||
match local_var {
|
|
||||||
None => Expression {
|
None => Expression {
|
||||||
t: ExpressionType::Module(prefix, suffixes),
|
t: ExpressionType::Module(prefix, suffixes),
|
||||||
},
|
},
|
||||||
@ -297,8 +297,7 @@ fn reduce_expression_value_var(var: ast::Var, locals: &Vec<Variable>) -> Express
|
|||||||
t: ExpressionType::Module(name_str, vec![]),
|
t: ExpressionType::Module(name_str, vec![]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let local_var = locals.iter().find(|it| it.name() == name_str);
|
match scope.find_name(&name_str) {
|
||||||
match local_var {
|
|
||||||
None => Expression {
|
None => Expression {
|
||||||
t: ExpressionType::Var(name_str),
|
t: ExpressionType::Var(name_str),
|
||||||
},
|
},
|
||||||
@ -311,7 +310,7 @@ fn reduce_expression_value_var(var: ast::Var, locals: &Vec<Variable>) -> Express
|
|||||||
|
|
||||||
pub fn reduce_expression_value_function_call(
|
pub fn reduce_expression_value_function_call(
|
||||||
function_call: ast::FunctionCall,
|
function_call: ast::FunctionCall,
|
||||||
locals: &Vec<Variable>,
|
scope: &Scope,
|
||||||
) -> Expression {
|
) -> Expression {
|
||||||
let function_name = match function_call.prefix() {
|
let function_name = match function_call.prefix() {
|
||||||
ast::Prefix::Name(name) => name.token().to_string(),
|
ast::Prefix::Name(name) => name.token().to_string(),
|
||||||
@ -325,7 +324,7 @@ pub fn reduce_expression_value_function_call(
|
|||||||
..
|
..
|
||||||
})) => arguments
|
})) => arguments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| reduce_expression(x.clone(), locals))
|
.map(|x| reduce_expression(x.clone(), scope))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
_ => panic!("Index not supported"),
|
_ => panic!("Index not supported"),
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ pub struct Scope {
|
|||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { scope: vec![] }
|
Self { scope: vec![vec![]] }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frame(&self) -> Option<&Local> {
|
fn frame(&self) -> Option<&Local> {
|
||||||
@ -27,9 +27,9 @@ impl Scope {
|
|||||||
self.frame_mut().map(|frame| frame.push(var));
|
self.frame_mut().map(|frame| frame.push(var));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_name(&self, name: String) -> Option<&Variable> {
|
pub fn find_name(&self, name: &String) -> Option<&Variable> {
|
||||||
self.frame()
|
self.frame()
|
||||||
.map_or(None, |frame| frame.iter().find(|var| var.name() == name))
|
.map_or(None, |frame| frame.iter().find(|var| &var.name() == name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_var(&mut self, value: Variable) {
|
pub fn set_var(&mut self, value: Variable) {
|
||||||
|
Loading…
Reference in New Issue
Block a user