Get compliation to work
This commit is contained in:
parent
50f6459abe
commit
f71008e8c2
@ -38,11 +38,13 @@ impl LocalCounter {
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
||||
pub fn find_constants(&self, scope: &mut Scope) -> HashSet<Constant> {
|
||||
let mut constants = HashSet::new();
|
||||
|
||||
let mut inner_scope = scope.clone();
|
||||
|
||||
for statement in &self.statements {
|
||||
constants.extend(statement.kind.find_constants());
|
||||
constants.extend(statement.kind.find_constants(&mut inner_scope));
|
||||
}
|
||||
|
||||
constants
|
||||
@ -51,8 +53,9 @@ impl Block {
|
||||
pub fn compile(&self, state: &mut State, scope: &mut Scope) -> Vec<Instruction> {
|
||||
let mut instructions = Vec::new();
|
||||
|
||||
let mut inner_scope = scope.clone();
|
||||
for statement in &self.statements {
|
||||
instructions.extend(statement.kind.compile(state, &mut scope.clone()));
|
||||
instructions.extend(statement.kind.compile(state, &mut inner_scope));
|
||||
}
|
||||
|
||||
instructions
|
||||
@ -60,21 +63,23 @@ impl Block {
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
||||
pub fn find_constants(&self, scope: &mut Scope) -> 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()));
|
||||
} else {
|
||||
scope.locals.insert(name.kind.clone(), 0);
|
||||
}
|
||||
constants.extend(expr.kind.find_constants());
|
||||
constants.extend(expr.kind.find_constants(scope));
|
||||
constants
|
||||
}
|
||||
Statement::Return(expr) => expr.kind.find_constants(),
|
||||
Statement::Return(expr) => expr.kind.find_constants(scope),
|
||||
Statement::If(cond, then) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.extend(cond.kind.find_constants());
|
||||
constants.extend(then.find_constants());
|
||||
constants.extend(cond.kind.find_constants(scope));
|
||||
constants.extend(then.find_constants(scope));
|
||||
constants
|
||||
}
|
||||
}
|
||||
@ -108,21 +113,27 @@ impl Statement {
|
||||
}
|
||||
|
||||
impl Expression {
|
||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
||||
pub fn find_constants(&self, scope: &mut Scope) -> HashSet<Constant> {
|
||||
match self {
|
||||
Expression::ValueRef(_) => HashSet::new(),
|
||||
Expression::BinOp(_, lhs, rhs) => {
|
||||
Expression::ValueRef(name) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.extend(lhs.kind.find_constants());
|
||||
constants.extend(rhs.kind.find_constants());
|
||||
if !scope.locals.contains_key(name) {
|
||||
constants.insert(Constant::String(name.clone()));
|
||||
}
|
||||
constants
|
||||
}
|
||||
Expression::FunctionDefinition(_, block) => block.find_constants(),
|
||||
Expression::BinOp(_, lhs, rhs) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.extend(lhs.kind.find_constants(scope));
|
||||
constants.extend(rhs.kind.find_constants(scope));
|
||||
constants
|
||||
}
|
||||
Expression::FunctionDefinition(_, block) => block.find_constants(scope),
|
||||
Expression::FunctionCall(expr, params) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.extend(expr.kind.find_constants());
|
||||
constants.extend(expr.kind.find_constants(scope));
|
||||
for param in ¶ms.kind.0 {
|
||||
constants.extend(param.kind.find_constants());
|
||||
constants.extend(param.kind.find_constants(scope));
|
||||
}
|
||||
constants
|
||||
}
|
||||
@ -195,9 +206,25 @@ impl Expression {
|
||||
));
|
||||
}
|
||||
|
||||
instructions.push(Instruction::Call(
|
||||
function_register,
|
||||
params.kind.0.len() as u16,
|
||||
return_regs.len() as u16 + 1,
|
||||
));
|
||||
|
||||
(instructions, return_regs)
|
||||
}
|
||||
Expression::Literal(literal) => todo!(),
|
||||
Expression::Literal(literal) => {
|
||||
let mut instructions = Vec::new();
|
||||
let reg = scope.register_counter.next();
|
||||
instructions.push(Instruction::GetGlobal(
|
||||
reg,
|
||||
state.get_constant(&match literal {
|
||||
Literal::Number(value) => Constant::Number(value.to_bits()),
|
||||
}),
|
||||
));
|
||||
(instructions, vec![reg])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,10 @@ fn main() {
|
||||
|
||||
dbg!(&chunk);
|
||||
|
||||
let constants = chunk.find_constants().into_iter().collect::<Vec<_>>();
|
||||
let constants = chunk
|
||||
.find_constants(&mut Default::default())
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>();
|
||||
dbg!(&constants);
|
||||
|
||||
let instructions = chunk.compile(&mut compile::State { constants }, &mut Default::default());
|
||||
|
||||
14
src/vm.rs
14
src/vm.rs
@ -22,7 +22,7 @@ impl Debug for Constant {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Instruction {
|
||||
/// R(A) := R(B)
|
||||
Move(u16, u16),
|
||||
@ -36,3 +36,15 @@ pub enum Instruction {
|
||||
/// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1))
|
||||
Call(u16, u16, u16),
|
||||
}
|
||||
|
||||
impl Debug for Instruction {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Move(arg0, arg1) => write!(f, "MOVE {} {}", arg0, arg1),
|
||||
Self::LoadK(arg0, arg1) => write!(f, "LOADK {} {}", arg0, arg1),
|
||||
Self::SetGlobal(arg0, arg1) => write!(f, "SETGLOBAL {} {}", arg0, arg1),
|
||||
Self::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
|
||||
Self::Call(arg0, arg1, arg2) => write!(f, "CALL {} {} {}", arg0, arg1, arg2),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user