add Scope
This commit is contained in:
parent
af4750c57b
commit
236c3aeb68
@ -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 */);
|
||||||
|
48
src/visitor/constant_folder/scope.rs
Normal file
48
src/visitor/constant_folder/scope.rs
Normal 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))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user