From 236c3aeb688494b385e8ad9e9cc6850c6300dfbe Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Wed, 19 May 2021 17:26:21 +0700 Subject: [PATCH] add Scope --- src/visitor/constant_folder.rs | 2 +- src/visitor/constant_folder/scope.rs | 48 ++++++++ src/visitor/constant_folder/variable_.rs | 144 ----------------------- very_small.lua | 34 +++--- 4 files changed, 64 insertions(+), 164 deletions(-) create mode 100644 src/visitor/constant_folder/scope.rs delete mode 100644 src/visitor/constant_folder/variable_.rs diff --git a/src/visitor/constant_folder.rs b/src/visitor/constant_folder.rs index 07fba18..6d55d3f 100644 --- a/src/visitor/constant_folder.rs +++ b/src/visitor/constant_folder.rs @@ -1,4 +1,5 @@ mod expression_reducer; +mod scope; use full_moon::ast::*; @@ -86,7 +87,6 @@ impl Visitor for ConstantFolder { fn visit_local_assignment<'a>(&mut self, local_assignment: &LocalAssignment<'a>) { let mut names = local_assignment.names().iter(); let mut expressions = local_assignment.expressions().iter(); - loop { let name = names.next().map(|x| x.token().to_string()); let expr = expressions.next().map(|x| x.clone() /* reduced */); diff --git a/src/visitor/constant_folder/scope.rs b/src/visitor/constant_folder/scope.rs new file mode 100644 index 0000000..5ad95b7 --- /dev/null +++ b/src/visitor/constant_folder/scope.rs @@ -0,0 +1,48 @@ +use crate::visitor::constant_folder::expression_reducer::Variable; + +type Local = Vec; + +pub struct Scope { + scope: Vec, +} + +impl Scope { + pub fn new() -> Self { + Self { + scope: vec![], + } + } + + fn frame(&self) -> Option<&Local> { + self.scope.last() + } + + fn frame_mut(&mut self) -> Option<&mut Local> { + self.scope.last_mut() + } + + pub fn new_frame(&mut self) { + self.scope.push(vec![]) + } + + pub fn push_var(&mut self, var: Variable) { + self.frame_mut().map(|frame| frame.push(var)); + } + + pub fn find_name(&self, name: String) -> Option<&Variable> { + self.frame().map_or(None, |frame| { + frame + .iter() + .find(|var| var.name() == name) + }) + } + + pub fn set_var(&mut self, value: Variable) { + self.frame_mut().map(|frame| { + frame + .iter_mut() + .find(|var| var.name() == value.name()) + .map(|var| var.assign_value(value)) + }); + } +} diff --git a/src/visitor/constant_folder/variable_.rs b/src/visitor/constant_folder/variable_.rs deleted file mode 100644 index 96ff59e..0000000 --- a/src/visitor/constant_folder/variable_.rs +++ /dev/null @@ -1,144 +0,0 @@ -/// A compile-time expression folder (constant propagation) -/// -/// To do constant folding, we must be able to reduce expression at -/// the compile-time. We give each Variable an Expression and reduce it. -/// If there is some expression, the variable value is the expression reduced. -/// Else the variable has undefined value at compile-time. -/// -/// We try to reduce -/// ```lua -/// L41_1 = L37_1 -/// L42_1 = 20 -/// L43_1 = 76 -/// L44_1 = 201 -/// L45_1 = 132 -/// L46_1 = 98 -/// L47_1 = 93 -/// L41_1 = (L41_1(L42_1, L43_1, L44_1, L45_1, L46_1, L47_1)) -/// ``` -/// into -/// ```lua -/// L41_1 = L37_1 -/// L42_1 = 20 -/// L43_1 = 76 -/// L44_1 = 201 -/// L45_1 = 132 -/// L46_1 = 98 -/// L47_1 = 93 -/// L41_1 = L37_1(20, 76, 201, 132, 98, 93) -/// ``` -/// -/// We reduce expression with a list of local variables. -/// -/// There are many cases where reduction fail to complete, these expression -/// won't reduced and kept the same. -/// -/// - Undefined or parameter -/// - Nil initialized -/// - Set {} -/// - For counter -/// -/// Every expression containing these won't be reduced furthur. Thus: -/// ```lua -/// L1 = 0 -/// L2 = nil -/// L3 = L1 + L2 -/// ``` -/// reduces into -/// ```lua -/// L1 = 0 -/// L2 = nil -/// L3 = 0 + L2 -/// ``` -/// -/// Keep in mind that we do expression folding only, dead code elimination -/// is done through another pass -use std::ops; - -enum BinOp { - Plus, - Minus, - Modulus, - Times, - Dividend, - Concat, -} - -enum CompareOp { - Lt, - Eq, - Gt, - Lte, - Gte, - Ne, -} - -/// Types of expression -enum Expression { - /// a number (int) - Literal(i64), - /// a string literal - String(String), - /// special name of library module.function (math.min) - Module(String, Vec), - /// variable referencing - Var(Variable), - /// Binary operation between expression - BinOp(Box, Box, BinOp), - /// Index into array - Index(Box, Box), - /// Comparision expression (1 < 2) - Comparision(Box, Box, CompareOp), - /// Function call - FunctionCall(), -} - -/// Variable has a name and the expression attached to it -pub struct Variable { - name: String, - value: Option>, -} - -impl Expression { -} - -impl ops::Add for Expression { - type Output = Self; - fn add(self, other: Self) -> Self { - - } -} -impl ops::Sub for Expression {} -impl ops::Mul for Expression {} -impl ops::Div for Expression {} -impl ops::Rem for Expression {} - -pub fn reduce_expression(expr: Expression, locals: Vec) -> Expression { - match expr { - Expression::BinOp(lhs_, rhs_, op) => { - let lhs = reduce_expression(*lhs_, locals); - let rhs = reduce_expression(*rhs_, locals); - match op { - Plus => { - lhs + rhs - } - Minus => { - lhs - rhs - } - Modulus => { - lhs % rhs - } - Times => { - lhs * rhs - } - Dividend => { - lhs / rhs - } - Concat => { - lhs.concat(rhs) - } - } - } - _ => expr - } -} diff --git a/very_small.lua b/very_small.lua index fa5a59d..c0c92c5 100644 --- a/very_small.lua +++ b/very_small.lua @@ -1,22 +1,3 @@ --- local L1_1, L1_2, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L37_1 --- L1_2 = 2 --- L1_1 = 1 + L1_2 --- L1_1 = true --- L1_2 = false --- L1_1 = L1_1 and L1_2 - --- L41_1 = L37_1 --- L42_1 = 20 --- L43_1 = 76 --- L44_1 = 201 --- L45_1 = 132 --- L46_1 = 98 --- L47_1 = 93 --- L41_1 = (L41_1(L42_1, L43_1, L44_1, L45_1, L46_1, L47_1)) - --- L1_1 = math --- L1_1 = math.min - local L0_1, L1_1, L2_1, L3_1, L4_1, L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1, L54_1, L55_1, L56_1, L57_1, L58_1, L59_1, L60_1, L61_1, L62_1, L63_1, L64_1, L65_1, L66_1, L67_1, L68_1, L69_1, L70_1, L71_1, L72_1, L73_1, L74_1, L75_1, L76_1, L77_1, L78_1, L79_1, L80_1, L81_1, L82_1, L83_1, L84_1, L85_1, L86_1, L87_1, L88_1, L89_1, L90_1, L91_1, L92_1, L93_1, L94_1, L95_1, L96_1, L97_1, L98_1, L99_1, L100_1, L101_1, L102_1, L103_1, L104_1, L105_1, L106_1, L107_1, L108_1, L109_1, L110_1, L111_1, L112_1, L113_1, L114_1, L115_1, L116_1, L117_1, L118_1, L119_1, L120_1, L121_1, L122_1, L123_1, L124_1, L125_1, L126_1, L127_1, L128_1, L129_1, L130_1, L131_1, L132_1, L133_1, L134_1, L135_1, L136_1, L137_1, L138_1, L139_1, L140_1, L141_1, L142_1, L143_1, L144_1, L145_1, L146_1, L147_1, L148_1, L149_1, L150_1, L151_1, L152_1, L153_1, L154_1, L155_1, L156_1, L157_1, L158_1, L159_1, L160_1, L161_1, L162_1, L163_1, L164_1, L165_1, L166_1, L167_1, L168_1, L169_1, L170_1, L171_1, L172_1, L173_1, L174_1, L175_1, L176_1, L177_1, L178_1, L179_1, L180_1, L181_1, L182_1, L183_1, L184_1, L185_1, L186_1, L187_1, L188_1, L189_1, L190_1, L191_1, L192_1, L193_1, L194_1, L195_1, L196_1, L197_1, L198_1, L199_1, L200_1, L201_1, L202_1, L203_1, L204_1, L205_1, L206_1, L207_1, L208_1, L209_1, L210_1, L211_1, L212_1, L213_1, L214_1, L215_1, L216_1, L217_1, L218_1, L219_1, L220_1, L221_1, L222_1, L223_1, L224_1, L225_1, L226_1, L227_1, L228_1, L229_1, L230_1 L1_1 = math L1_1 = L1_1.fmod @@ -46,3 +27,18 @@ L13_1 = string L13_1 = L13_1.len L14_1 = string L14_1 = L14_1.gsub + +L1_2 = 2 +L1_1 = 1 + L1_2 +L1_1 = true +L1_2 = false +L1_1 = L1_1 and L1_20 + +L41_1 = L37_1 +L42_1 = 20 +L43_1 = 76 +L44_1 = 201 +L45_1 = 132 +L46_1 = 98 +L47_1 = 93 +L41_1 = (L41_1(L42_1, L43_1, L44_1, L45_1, L46_1, L47_1))