add Scope

This commit is contained in:
nganhkhoa 2021-05-19 17:26:21 +07:00
parent af4750c57b
commit 236c3aeb68
4 changed files with 64 additions and 164 deletions

View File

@ -1,4 +1,5 @@
mod expression_reducer; mod expression_reducer;
mod scope;
use full_moon::ast::*; use full_moon::ast::*;
@ -86,7 +87,6 @@ impl Visitor for ConstantFolder {
fn visit_local_assignment<'a>(&mut self, local_assignment: &LocalAssignment<'a>) { fn visit_local_assignment<'a>(&mut self, local_assignment: &LocalAssignment<'a>) {
let mut names = local_assignment.names().iter(); let mut names = local_assignment.names().iter();
let mut expressions = local_assignment.expressions().iter(); let mut expressions = local_assignment.expressions().iter();
loop { loop {
let name = names.next().map(|x| x.token().to_string()); let name = names.next().map(|x| x.token().to_string());
let expr = expressions.next().map(|x| x.clone() /* reduced */); let expr = expressions.next().map(|x| x.clone() /* reduced */);

View File

@ -0,0 +1,48 @@
use crate::visitor::constant_folder::expression_reducer::Variable;
type Local = Vec<Variable>;
pub struct Scope {
scope: Vec<Local>,
}
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))
});
}
}

View File

@ -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<String>),
/// variable referencing
Var(Variable),
/// Binary operation between expression
BinOp(Box<Expression>, Box<Expression>, BinOp),
/// Index into array
Index(Box<Expression>, Box<Expression>),
/// Comparision expression (1 < 2)
Comparision(Box<Expression>, Box<Expression>, CompareOp),
/// Function call
FunctionCall(),
}
/// Variable has a name and the expression attached to it
pub struct Variable {
name: String,
value: Option<Box<Expression>>,
}
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<Variable>) -> 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
}
}

View File

@ -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 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 = math
L1_1 = L1_1.fmod L1_1 = L1_1.fmod
@ -46,3 +27,18 @@ L13_1 = string
L13_1 = L13_1.len L13_1 = L13_1.len
L14_1 = string L14_1 = string
L14_1 = L14_1.gsub 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))