format code
This commit is contained in:
parent
236c3aeb68
commit
3011542376
@ -1,16 +1,16 @@
|
|||||||
mod visitor;
|
mod visitor;
|
||||||
|
|
||||||
use std::fs;
|
|
||||||
use full_moon::parse;
|
use full_moon::parse;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
use visitor::Visitor;
|
|
||||||
use visitor::ConstantFolder;
|
use visitor::ConstantFolder;
|
||||||
|
use visitor::Visitor;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// let contents = fs::read_to_string("main_android_org.lua")
|
// let contents = fs::read_to_string("main_android_org.lua")
|
||||||
// let contents = fs::read_to_string("small.lua")
|
// let contents = fs::read_to_string("small.lua")
|
||||||
let contents = fs::read_to_string("very_small.lua")
|
let contents =
|
||||||
.expect("Something went wrong reading the file");
|
fs::read_to_string("very_small.lua").expect("Something went wrong reading the file");
|
||||||
|
|
||||||
let tree = parse(&contents).expect("Parsing lua gone wrong");
|
let tree = parse(&contents).expect("Parsing lua gone wrong");
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
mod visitor;
|
|
||||||
mod constant_folder;
|
mod constant_folder;
|
||||||
|
mod visitor;
|
||||||
|
|
||||||
pub use visitor::*;
|
|
||||||
pub use constant_folder::*;
|
pub use constant_folder::*;
|
||||||
|
pub use visitor::*;
|
||||||
|
@ -5,31 +5,26 @@ use full_moon::ast::*;
|
|||||||
|
|
||||||
use crate::visitor::Visitor;
|
use crate::visitor::Visitor;
|
||||||
|
|
||||||
|
|
||||||
pub struct ConstantFolder {
|
pub struct ConstantFolder {
|
||||||
locals: Box<Vec<expression_reducer::Variable>>
|
locals: Box<Vec<expression_reducer::Variable>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstantFolder {
|
impl ConstantFolder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ConstantFolder{
|
ConstantFolder {
|
||||||
locals: Box::new(vec![])
|
locals: Box::new(vec![]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 locals = &*self.locals;
|
||||||
let var = expression_reducer::Variable::with_value(
|
let var = expression_reducer::Variable::with_value(name, value, locals);
|
||||||
name, value, locals
|
|
||||||
);
|
|
||||||
self.locals.push(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 locals = &*self.locals;
|
||||||
let var = expression_reducer::Variable::with_value(
|
let var = expression_reducer::Variable::with_value(name, value, locals);
|
||||||
name, value, locals
|
|
||||||
);
|
|
||||||
{
|
{
|
||||||
let mut iter = self.locals.iter_mut();
|
let mut iter = self.locals.iter_mut();
|
||||||
let it = iter.find(|it| it.name() == var.name());
|
let it = iter.find(|it| it.name() == var.name());
|
||||||
@ -48,7 +43,7 @@ impl Visitor for ConstantFolder {
|
|||||||
panic!("assignment Var::Expression is not supported")
|
panic!("assignment Var::Expression is not supported")
|
||||||
}
|
}
|
||||||
Var::Name(n) => n.token().to_string(),
|
Var::Name(n) => n.token().to_string(),
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
});
|
});
|
||||||
let expr = expressions.next().map(|x| x.clone() /* reduced */);
|
let expr = expressions.next().map(|x| x.clone() /* reduced */);
|
||||||
match name {
|
match name {
|
||||||
@ -68,7 +63,10 @@ impl Visitor for ConstantFolder {
|
|||||||
|
|
||||||
fn visit_function_call<'a>(&mut self, function_call: &FunctionCall<'a>) {
|
fn visit_function_call<'a>(&mut self, function_call: &FunctionCall<'a>) {
|
||||||
println!("visit function_call {}", function_call);
|
println!("visit function_call {}", function_call);
|
||||||
let reduced = expression_reducer::reduce_expression_value_function_call(function_call.clone(), &*self.locals);
|
let reduced = expression_reducer::reduce_expression_value_function_call(
|
||||||
|
function_call.clone(),
|
||||||
|
&*self.locals,
|
||||||
|
);
|
||||||
println!("{:?}", reduced);
|
println!("{:?}", reduced);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,5 +122,4 @@ impl Visitor for ConstantFolder {
|
|||||||
fn visit_label<'a>(&mut self, label: &lua52::Label<'a>) {
|
fn visit_label<'a>(&mut self, label: &lua52::Label<'a>) {
|
||||||
println!("visit label {}", label);
|
println!("visit label {}", label);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,17 +61,14 @@ use full_moon::ast;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Variable {
|
pub struct Variable {
|
||||||
n: String,
|
n: String,
|
||||||
v: Expression
|
v: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
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>, locals: &Vec<Variable>) -> Self {
|
||||||
let v = Expression::reduce(expr, locals);
|
let v = Expression::reduce(expr, locals);
|
||||||
println!("variable_with {} = {:?}", name, v);
|
println!("variable_with {} = {:?}", name, v);
|
||||||
Self {
|
Self { n: name, v: v }
|
||||||
n: name,
|
|
||||||
v: v,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> String {
|
pub fn name(&self) -> String {
|
||||||
@ -121,7 +118,7 @@ impl BinOp {
|
|||||||
ast::BinOp::TildeEqual(_) => BinOp::TildeEqual,
|
ast::BinOp::TildeEqual(_) => BinOp::TildeEqual,
|
||||||
ast::BinOp::TwoDots(_) => BinOp::TwoDots,
|
ast::BinOp::TwoDots(_) => BinOp::TwoDots,
|
||||||
ast::BinOp::TwoEqual(_) => BinOp::TwoEqual,
|
ast::BinOp::TwoEqual(_) => BinOp::TwoEqual,
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +136,7 @@ impl UnOp {
|
|||||||
ast::UnOp::Minus(_) => UnOp::Minus,
|
ast::UnOp::Minus(_) => UnOp::Minus,
|
||||||
ast::UnOp::Not(_) => UnOp::Not,
|
ast::UnOp::Not(_) => UnOp::Not,
|
||||||
ast::UnOp::Hash(_) => UnOp::Hash,
|
ast::UnOp::Hash(_) => UnOp::Hash,
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,7 +163,7 @@ 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>, locals: &Vec<Variable>) -> Self {
|
||||||
if expr.is_none() {
|
if expr.is_none() {
|
||||||
Expression{
|
Expression {
|
||||||
t: ExpressionType::Nil,
|
t: ExpressionType::Nil,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -199,34 +196,18 @@ impl Expression {
|
|||||||
|
|
||||||
fn reduce_expression(expr: ast::Expression, locals: &Vec<Variable>) -> Expression {
|
fn reduce_expression(expr: ast::Expression, locals: &Vec<Variable>) -> Expression {
|
||||||
match expr {
|
match expr {
|
||||||
ast::Expression::BinaryOperator {
|
ast::Expression::BinaryOperator { lhs, rhs, binop } => {
|
||||||
lhs,
|
|
||||||
rhs,
|
|
||||||
binop
|
|
||||||
} => {
|
|
||||||
let lhs_ = reduce_expression(*lhs, locals);
|
let lhs_ = reduce_expression(*lhs, locals);
|
||||||
let rhs_ = reduce_expression(*rhs, locals);
|
let rhs_ = reduce_expression(*rhs, locals);
|
||||||
apply_binary_operator(lhs_, rhs_, binop)
|
apply_binary_operator(lhs_, rhs_, binop)
|
||||||
}
|
}
|
||||||
ast::Expression::Parentheses {
|
ast::Expression::Parentheses { expression, .. } => reduce_expression(*expression, locals),
|
||||||
expression,
|
ast::Expression::UnaryOperator { unop, expression } => {
|
||||||
..
|
|
||||||
} => {
|
|
||||||
reduce_expression(*expression, locals)
|
|
||||||
}
|
|
||||||
ast::Expression::UnaryOperator {
|
|
||||||
unop,
|
|
||||||
expression,
|
|
||||||
} => {
|
|
||||||
let expression_ = reduce_expression(*expression, locals);
|
let expression_ = reduce_expression(*expression, locals);
|
||||||
apply_unary_operator(expression_, unop)
|
apply_unary_operator(expression_, unop)
|
||||||
}
|
}
|
||||||
ast::Expression::Value {
|
ast::Expression::Value { value } => reduce_expression_value(*value, locals),
|
||||||
value
|
_ => unreachable!(),
|
||||||
} => {
|
|
||||||
reduce_expression_value(*value, locals)
|
|
||||||
}
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,36 +224,32 @@ fn reduce_expression_value(value: ast::Value, locals: &Vec<Variable>) -> Express
|
|||||||
}
|
}
|
||||||
ast::Value::Number(number) => {
|
ast::Value::Number(number) => {
|
||||||
let num = number.token().to_string();
|
let num = number.token().to_string();
|
||||||
Expression{
|
Expression {
|
||||||
t: ExpressionType::Number(num.parse::<f64>().unwrap()),
|
t: ExpressionType::Number(num.parse::<f64>().unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Value::ParenthesesExpression(parentheses_expression) => {
|
ast::Value::ParenthesesExpression(parentheses_expression) => {
|
||||||
reduce_expression(parentheses_expression, locals)
|
reduce_expression(parentheses_expression, locals)
|
||||||
}
|
}
|
||||||
ast::Value::String(string) => {
|
ast::Value::String(string) => Expression {
|
||||||
Expression{
|
|
||||||
t: ExpressionType::String(string.token().to_string()),
|
t: ExpressionType::String(string.token().to_string()),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
ast::Value::Symbol(symbol) => {
|
ast::Value::Symbol(symbol) => {
|
||||||
let s = symbol.token().to_string();
|
let s = symbol.token().to_string();
|
||||||
if s == "true" {
|
if s == "true" {
|
||||||
Expression{
|
Expression {
|
||||||
t: ExpressionType::Boolean(true),
|
t: ExpressionType::Boolean(true),
|
||||||
}
|
}
|
||||||
} else if s == "false" {
|
} else if s == "false" {
|
||||||
Expression{
|
Expression {
|
||||||
t: ExpressionType::Boolean(false),
|
t: ExpressionType::Boolean(false),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("reduce Expression::Symbol is not true/false");
|
panic!("reduce Expression::Symbol is not true/false");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Value::Var(var) => {
|
ast::Value::Var(var) => reduce_expression_value_var(var, locals),
|
||||||
reduce_expression_value_var(var, locals)
|
_ => unreachable!(),
|
||||||
}
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,105 +259,90 @@ fn reduce_expression_value_var(var: ast::Var, locals: &Vec<Variable>) -> Express
|
|||||||
let prefix = {
|
let prefix = {
|
||||||
match expr.prefix() {
|
match expr.prefix() {
|
||||||
ast::Prefix::Name(name) => name.token().to_string(),
|
ast::Prefix::Name(name) => name.token().to_string(),
|
||||||
_ => panic!("Var::Expression prefix expression is unsupported")
|
_ => panic!("Var::Expression prefix expression is unsupported"),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let suffixes = expr.suffixes().map(|suf| {
|
let suffixes = expr
|
||||||
match suf {
|
.suffixes()
|
||||||
ast::Suffix::Index(ast::Index::Dot{
|
.map(|suf| match suf {
|
||||||
name,
|
ast::Suffix::Index(ast::Index::Dot { name, .. }) => name.token().to_string(),
|
||||||
..
|
_ => panic!("Var::Expression Call not supported"),
|
||||||
}) => {
|
})
|
||||||
name.token().to_string()
|
.collect::<Vec<String>>();
|
||||||
}
|
|
||||||
_ => panic!("Var::Expression Call not supported")
|
|
||||||
}
|
|
||||||
}).collect::<Vec<String>>();
|
|
||||||
|
|
||||||
let local_var = locals.iter().find(|it| it.name() == prefix);
|
let local_var = locals.iter().find(|it| it.name() == prefix);
|
||||||
match local_var {
|
match local_var {
|
||||||
None => {
|
None => Expression {
|
||||||
Expression {
|
t: ExpressionType::Module(prefix, suffixes),
|
||||||
t: ExpressionType::Module(prefix, suffixes)
|
},
|
||||||
}
|
Some(var) => match var.v.clone().t {
|
||||||
}
|
ExpressionType::Module(n, _) => Expression {
|
||||||
Some(var) => {
|
t: ExpressionType::Module(n, suffixes),
|
||||||
match var.v.clone().t {
|
},
|
||||||
ExpressionType::Module(n, _) => {
|
_ => Expression {
|
||||||
Expression {
|
t: ExpressionType::Module(var.name(), suffixes),
|
||||||
t: ExpressionType::Module(n, suffixes)
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Expression {
|
|
||||||
t: ExpressionType::Module(var.name(), suffixes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Var::Name(name) => {
|
ast::Var::Name(name) => {
|
||||||
fn is_standard_library(name: &String) -> bool {
|
fn is_standard_library(name: &String) -> bool {
|
||||||
let standard_library_names: Vec<&str> = vec![
|
let standard_library_names: Vec<&str> = vec!["math", "string", "table", "bit"];
|
||||||
"math", "string", "table", "bit"
|
|
||||||
];
|
|
||||||
standard_library_names.contains(&name.as_str())
|
standard_library_names.contains(&name.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
let name_str = name.token().to_string();
|
let name_str = name.token().to_string();
|
||||||
if is_standard_library(&name_str) {
|
if is_standard_library(&name_str) {
|
||||||
return Expression {
|
return Expression {
|
||||||
t: ExpressionType::Module(name_str, vec![])
|
t: ExpressionType::Module(name_str, vec![]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let local_var = locals.iter().find(|it| it.name() == name_str);
|
let local_var = locals.iter().find(|it| it.name() == name_str);
|
||||||
match local_var {
|
match local_var {
|
||||||
None => {
|
None => Expression {
|
||||||
Expression {
|
t: ExpressionType::Var(name_str),
|
||||||
t: ExpressionType::Var(name_str)
|
},
|
||||||
|
Some(v) => v.v.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(v) => {
|
_ => unreachable!(),
|
||||||
v.v.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce_expression_value_function_call(function_call: ast::FunctionCall, locals: &Vec<Variable>) -> Expression {
|
pub fn reduce_expression_value_function_call(
|
||||||
|
function_call: ast::FunctionCall,
|
||||||
|
locals: &Vec<Variable>,
|
||||||
|
) -> 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(),
|
||||||
_ => panic!("Function name as expression is unsupported")
|
_ => panic!("Function name as expression is unsupported"),
|
||||||
};
|
};
|
||||||
let args = {
|
let args = {
|
||||||
let suf = function_call.suffixes().next().unwrap();
|
let suf = function_call.suffixes().next().unwrap();
|
||||||
match suf {
|
match suf {
|
||||||
ast::Suffix::Call(ast::Call::AnonymousCall(ast::FunctionArgs::Parentheses{
|
ast::Suffix::Call(ast::Call::AnonymousCall(ast::FunctionArgs::Parentheses {
|
||||||
arguments,
|
arguments,
|
||||||
..
|
..
|
||||||
})) => {
|
})) => arguments
|
||||||
arguments.iter().map(|x| reduce_expression(x.clone(), locals)).collect::<Vec<_>>()
|
.iter()
|
||||||
}
|
.map(|x| reduce_expression(x.clone(), locals))
|
||||||
_ => panic!("Index not supported")
|
.collect::<Vec<_>>(),
|
||||||
|
_ => panic!("Index not supported"),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Expression {
|
Expression {
|
||||||
t: ExpressionType::FunctionCall(function_name, args)
|
t: ExpressionType::FunctionCall(function_name, args),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_binary_operator(lhs: Expression, rhs: Expression, binop: ast::BinOp) -> Expression {
|
fn apply_binary_operator(lhs: Expression, rhs: Expression, binop: ast::BinOp) -> Expression {
|
||||||
match (&lhs.t, &rhs.t) {
|
match (&lhs.t, &rhs.t) {
|
||||||
(&ExpressionType::Number(lhs_), &ExpressionType::Number(rhs_)) => {
|
(&ExpressionType::Number(lhs_), &ExpressionType::Number(rhs_)) => match binop {
|
||||||
match binop {
|
|
||||||
ast::BinOp::GreaterThan(_) => {
|
ast::BinOp::GreaterThan(_) => {
|
||||||
return Expression {
|
return Expression {
|
||||||
t: ExpressionType::Boolean(lhs_ > rhs_),
|
t: ExpressionType::Boolean(lhs_ > rhs_),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
ast::BinOp::GreaterThanEqual(_) => {
|
ast::BinOp::GreaterThanEqual(_) => {
|
||||||
return Expression {
|
return Expression {
|
||||||
t: ExpressionType::Boolean(lhs_ >= rhs_),
|
t: ExpressionType::Boolean(lhs_ >= rhs_),
|
||||||
@ -437,14 +399,12 @@ fn apply_binary_operator(lhs: Expression, rhs: Expression, binop: ast::BinOp) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
match (&lhs.t, &rhs.t) {
|
match (&lhs.t, &rhs.t) {
|
||||||
(&ExpressionType::Boolean(lhs_), &ExpressionType::Boolean(rhs_)) => {
|
(&ExpressionType::Boolean(lhs_), &ExpressionType::Boolean(rhs_)) => match binop {
|
||||||
match binop {
|
|
||||||
ast::BinOp::And(_) => {
|
ast::BinOp::And(_) => {
|
||||||
return Expression {
|
return Expression {
|
||||||
t: ExpressionType::Boolean(lhs_ & rhs_),
|
t: ExpressionType::Boolean(lhs_ & rhs_),
|
||||||
@ -456,22 +416,19 @@ fn apply_binary_operator(lhs: Expression, rhs: Expression, binop: ast::BinOp) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match (&lhs.t, &rhs.t) {
|
match (&lhs.t, &rhs.t) {
|
||||||
(&ExpressionType::String(ref lhs_), &ExpressionType::String(ref rhs_)) => {
|
(&ExpressionType::String(ref lhs_), &ExpressionType::String(ref rhs_)) => match binop {
|
||||||
match binop {
|
|
||||||
ast::BinOp::TwoDots(_) => {
|
ast::BinOp::TwoDots(_) => {
|
||||||
return Expression {
|
return Expression {
|
||||||
t: ExpressionType::String(lhs_.clone() + &rhs_),
|
t: ExpressionType::String(lhs_.clone() + &rhs_),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,20 +443,20 @@ fn apply_unary_operator(expr: Expression, unop: ast::UnOp) -> Expression {
|
|||||||
if let ExpressionType::Boolean(e) = expr.t {
|
if let ExpressionType::Boolean(e) = expr.t {
|
||||||
return Expression {
|
return Expression {
|
||||||
t: ExpressionType::Boolean(!e),
|
t: ExpressionType::Boolean(!e),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::UnOp::Minus(_) => {
|
ast::UnOp::Minus(_) => {
|
||||||
if let ExpressionType::Number(e) = expr.t {
|
if let ExpressionType::Number(e) = expr.t {
|
||||||
return Expression {
|
return Expression {
|
||||||
t: ExpressionType::Number(-e),
|
t: ExpressionType::Number(-e),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::UnOp::Hash(_) => {
|
ast::UnOp::Hash(_) => {
|
||||||
panic!("Unary Hash unimplemented")
|
panic!("Unary Hash unimplemented")
|
||||||
}
|
}
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression {
|
Expression {
|
||||||
|
@ -8,9 +8,7 @@ pub struct Scope {
|
|||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self { scope: vec![] }
|
||||||
scope: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frame(&self) -> Option<&Local> {
|
fn frame(&self) -> Option<&Local> {
|
||||||
@ -30,11 +28,8 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_name(&self, name: String) -> Option<&Variable> {
|
pub fn find_name(&self, name: String) -> Option<&Variable> {
|
||||||
self.frame().map_or(None, |frame| {
|
self.frame()
|
||||||
frame
|
.map_or(None, |frame| frame.iter().find(|var| var.name() == name))
|
||||||
.iter()
|
|
||||||
.find(|var| var.name() == name)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_var(&mut self, value: Variable) {
|
pub fn set_var(&mut self, value: Variable) {
|
||||||
|
@ -10,39 +10,21 @@ pub trait Visitor {
|
|||||||
|
|
||||||
fn visit_statement<'a>(&mut self, stmt: &Stmt<'a>) {
|
fn visit_statement<'a>(&mut self, stmt: &Stmt<'a>) {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Assignment(assignment) => {
|
Stmt::Assignment(assignment) => self.visit_assignment(assignment),
|
||||||
self.visit_assignment(assignment)
|
Stmt::Do(do_) => self.visit_do(do_),
|
||||||
}
|
Stmt::FunctionCall(function_call) => self.visit_function_call(function_call),
|
||||||
Stmt::Do(do_) => {
|
|
||||||
self.visit_do(do_)
|
|
||||||
}
|
|
||||||
Stmt::FunctionCall(function_call) => {
|
|
||||||
self.visit_function_call(function_call)
|
|
||||||
}
|
|
||||||
Stmt::FunctionDeclaration(function_declaration) => {
|
Stmt::FunctionDeclaration(function_declaration) => {
|
||||||
self.visit_function_declaration(function_declaration)
|
self.visit_function_declaration(function_declaration)
|
||||||
}
|
}
|
||||||
Stmt::GenericFor(generic_for) => {
|
Stmt::GenericFor(generic_for) => self.visit_generic_for(generic_for),
|
||||||
self.visit_generic_for(generic_for)
|
Stmt::If(if_) => self.visit_if(if_),
|
||||||
}
|
|
||||||
Stmt::If(if_) => {
|
|
||||||
self.visit_if(if_)
|
|
||||||
}
|
|
||||||
Stmt::LocalAssignment(local_assignment) => {
|
Stmt::LocalAssignment(local_assignment) => {
|
||||||
self.visit_local_assignment(local_assignment)
|
self.visit_local_assignment(local_assignment)
|
||||||
}
|
}
|
||||||
Stmt::LocalFunction(local_function) => {
|
Stmt::LocalFunction(local_function) => self.visit_local_function(local_function),
|
||||||
self.visit_local_function(local_function)
|
Stmt::NumericFor(numeric_for) => self.visit_numeric_for(numeric_for),
|
||||||
}
|
Stmt::Repeat(repeat) => self.visit_repeat(repeat),
|
||||||
Stmt::NumericFor(numeric_for) => {
|
Stmt::While(while_) => self.visit_while(while_),
|
||||||
self.visit_numeric_for(numeric_for)
|
|
||||||
}
|
|
||||||
Stmt::Repeat(repeat) => {
|
|
||||||
self.visit_repeat(repeat)
|
|
||||||
}
|
|
||||||
Stmt::While(while_) => {
|
|
||||||
self.visit_while(while_)
|
|
||||||
}
|
|
||||||
// Stmt::CompoundAssignment(compound_assignment) => {
|
// Stmt::CompoundAssignment(compound_assignment) => {
|
||||||
// self.visit_compound_assignment(compound_assignment)
|
// self.visit_compound_assignment(compound_assignment)
|
||||||
// }
|
// }
|
||||||
@ -52,12 +34,8 @@ pub trait Visitor {
|
|||||||
// Stmt::TypeDeclaration(type_declaration) => {
|
// Stmt::TypeDeclaration(type_declaration) => {
|
||||||
// self.visit_type_declaration(type_declaration)
|
// self.visit_type_declaration(type_declaration)
|
||||||
// }
|
// }
|
||||||
Stmt::Goto(goto) => {
|
Stmt::Goto(goto) => self.visit_goto(goto),
|
||||||
self.visit_goto(goto)
|
Stmt::Label(label) => self.visit_label(label),
|
||||||
}
|
|
||||||
Stmt::Label(label) => {
|
|
||||||
self.visit_label(label)
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user