Find constants
This commit is contained in:
parent
12e2fab066
commit
d74a887c4e
@ -1 +1 @@
|
||||
c = max(5, 7)
|
||||
global c = max(5, 7)
|
||||
12
src/ast.rs
12
src/ast.rs
@ -241,12 +241,16 @@ impl Parse for Statement {
|
||||
let then = stream.parse()?;
|
||||
stream.expect(Token::Keyword(Keyword::End))?;
|
||||
Ok(Self::If(cond, then))
|
||||
} else if peeked == Some(Token::Keyword(Keyword::Local)) {
|
||||
stream.next();
|
||||
} else if let Some(Token::Keyword(Keyword::Local | Keyword::Global)) = peeked {
|
||||
let access_modifier = match stream.next() {
|
||||
Some(Token::Keyword(Keyword::Local)) => AccessModifier::Local,
|
||||
Some(Token::Keyword(Keyword::Global)) => AccessModifier::Global,
|
||||
_ => panic!(),
|
||||
};
|
||||
let name = stream.parse()?;
|
||||
stream.expect(Token::Symbol('='))?;
|
||||
let expr = stream.parse()?;
|
||||
Ok(Statement::Assignment(AccessModifier::Local, name, expr))
|
||||
Ok(Statement::Assignment(access_modifier, name, expr))
|
||||
} else if let Some(Token::Word(_)) = peeked
|
||||
&& stream.peek2() == Some(Token::Symbol('='))
|
||||
{
|
||||
@ -263,7 +267,7 @@ impl Parse for Statement {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum AccessModifier {
|
||||
Local,
|
||||
Global,
|
||||
|
||||
74
src/compile.rs
Normal file
74
src/compile.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::{
|
||||
ast::{AccessModifier, Block, Expression, Literal, Statement},
|
||||
vm::{Constant, VMNumber},
|
||||
};
|
||||
|
||||
struct State {
|
||||
pub constants: Vec<Constant>,
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
||||
let mut constants = HashSet::new();
|
||||
|
||||
for statement in &self.statements {
|
||||
constants.extend(statement.kind.find_constants());
|
||||
}
|
||||
|
||||
constants
|
||||
}
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
||||
match self {
|
||||
Statement::Assignment(access, name, expr) => {
|
||||
let mut constants = HashSet::new();
|
||||
if *access == AccessModifier::Global {
|
||||
constants.insert(Constant::String(name.kind.clone()));
|
||||
}
|
||||
constants.extend(expr.kind.find_constants());
|
||||
constants
|
||||
}
|
||||
Statement::Return(expr) => expr.kind.find_constants(),
|
||||
Statement::If(cond, then) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.extend(cond.kind.find_constants());
|
||||
constants.extend(then.find_constants());
|
||||
constants
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Expression {
|
||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
||||
match self {
|
||||
Expression::ValueRef(_) => HashSet::new(),
|
||||
Expression::BinOp(_, lhs, rhs) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.extend(lhs.kind.find_constants());
|
||||
constants.extend(rhs.kind.find_constants());
|
||||
constants
|
||||
}
|
||||
Expression::FunctionDefinition(_, block) => block.find_constants(),
|
||||
Expression::FunctionCall(expr, params) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.extend(expr.kind.find_constants());
|
||||
for param in ¶ms.kind.0 {
|
||||
constants.extend(param.kind.find_constants());
|
||||
}
|
||||
constants
|
||||
}
|
||||
Expression::Literal(literal) => match literal {
|
||||
Literal::Number(value) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.insert(Constant::Number(value.to_bits()));
|
||||
constants
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,9 @@ use crate::{
|
||||
};
|
||||
|
||||
mod ast;
|
||||
mod compile;
|
||||
mod token_stream;
|
||||
mod vm;
|
||||
|
||||
static TEST: &str = include_str!("../examples/test.lua");
|
||||
|
||||
@ -23,7 +25,8 @@ fn main() {
|
||||
let chunk = stream.parse::<Block>().unwrap();
|
||||
stream.expect(Token::Eof).unwrap();
|
||||
|
||||
dbg!(chunk);
|
||||
dbg!(&chunk);
|
||||
|
||||
println!("Hello, world!");
|
||||
let constants = chunk.find_constants();
|
||||
dbg!(&constants);
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ pub enum Keyword {
|
||||
Function,
|
||||
End,
|
||||
Local,
|
||||
Global,
|
||||
Return,
|
||||
If,
|
||||
Then,
|
||||
@ -23,6 +24,7 @@ impl Keyword {
|
||||
"function" => Keyword::Function,
|
||||
"end" => Keyword::End,
|
||||
"local" => Keyword::Local,
|
||||
"global" => Keyword::Global,
|
||||
"return" => Keyword::Return,
|
||||
"if" => Keyword::If,
|
||||
"then" => Keyword::Then,
|
||||
@ -37,6 +39,7 @@ impl ToString for Keyword {
|
||||
Keyword::Function => "function",
|
||||
Keyword::End => "end",
|
||||
Keyword::Local => "local",
|
||||
Keyword::Global => "global",
|
||||
Keyword::Return => "return",
|
||||
Keyword::If => "if",
|
||||
Keyword::Then => "then",
|
||||
|
||||
23
src/vm.rs
Normal file
23
src/vm.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::ast::LuaNumber;
|
||||
|
||||
pub type VMNumber = u64;
|
||||
|
||||
#[derive(Clone, Hash, PartialEq, Eq)]
|
||||
pub enum Constant {
|
||||
String(String),
|
||||
Number(VMNumber),
|
||||
}
|
||||
|
||||
impl Debug for Constant {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
|
||||
Self::Number(arg0) => f
|
||||
.debug_tuple("Number")
|
||||
.field(&LuaNumber::from_bits(*arg0))
|
||||
.finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user