Get compliation to work
This commit is contained in:
parent
50f6459abe
commit
f71008e8c2
@ -38,11 +38,13 @@ impl LocalCounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Block {
|
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 constants = HashSet::new();
|
||||||
|
|
||||||
|
let mut inner_scope = scope.clone();
|
||||||
|
|
||||||
for statement in &self.statements {
|
for statement in &self.statements {
|
||||||
constants.extend(statement.kind.find_constants());
|
constants.extend(statement.kind.find_constants(&mut inner_scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
constants
|
constants
|
||||||
@ -51,8 +53,9 @@ impl Block {
|
|||||||
pub fn compile(&self, state: &mut State, scope: &mut Scope) -> Vec<Instruction> {
|
pub fn compile(&self, state: &mut State, scope: &mut Scope) -> Vec<Instruction> {
|
||||||
let mut instructions = Vec::new();
|
let mut instructions = Vec::new();
|
||||||
|
|
||||||
|
let mut inner_scope = scope.clone();
|
||||||
for statement in &self.statements {
|
for statement in &self.statements {
|
||||||
instructions.extend(statement.kind.compile(state, &mut scope.clone()));
|
instructions.extend(statement.kind.compile(state, &mut inner_scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
instructions
|
instructions
|
||||||
@ -60,21 +63,23 @@ impl Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Statement {
|
impl Statement {
|
||||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
pub fn find_constants(&self, scope: &mut Scope) -> HashSet<Constant> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Assignment(access, name, expr) => {
|
Statement::Assignment(access, name, expr) => {
|
||||||
let mut constants = HashSet::new();
|
let mut constants = HashSet::new();
|
||||||
if *access == AccessModifier::Global {
|
if *access == AccessModifier::Global {
|
||||||
constants.insert(Constant::String(name.kind.clone()));
|
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
|
constants
|
||||||
}
|
}
|
||||||
Statement::Return(expr) => expr.kind.find_constants(),
|
Statement::Return(expr) => expr.kind.find_constants(scope),
|
||||||
Statement::If(cond, then) => {
|
Statement::If(cond, then) => {
|
||||||
let mut constants = HashSet::new();
|
let mut constants = HashSet::new();
|
||||||
constants.extend(cond.kind.find_constants());
|
constants.extend(cond.kind.find_constants(scope));
|
||||||
constants.extend(then.find_constants());
|
constants.extend(then.find_constants(scope));
|
||||||
constants
|
constants
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,21 +113,27 @@ impl Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn find_constants(&self) -> HashSet<Constant> {
|
pub fn find_constants(&self, scope: &mut Scope) -> HashSet<Constant> {
|
||||||
match self {
|
match self {
|
||||||
Expression::ValueRef(_) => HashSet::new(),
|
Expression::ValueRef(name) => {
|
||||||
Expression::BinOp(_, lhs, rhs) => {
|
|
||||||
let mut constants = HashSet::new();
|
let mut constants = HashSet::new();
|
||||||
constants.extend(lhs.kind.find_constants());
|
if !scope.locals.contains_key(name) {
|
||||||
constants.extend(rhs.kind.find_constants());
|
constants.insert(Constant::String(name.clone()));
|
||||||
|
}
|
||||||
constants
|
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) => {
|
Expression::FunctionCall(expr, params) => {
|
||||||
let mut constants = HashSet::new();
|
let mut constants = HashSet::new();
|
||||||
constants.extend(expr.kind.find_constants());
|
constants.extend(expr.kind.find_constants(scope));
|
||||||
for param in ¶ms.kind.0 {
|
for param in ¶ms.kind.0 {
|
||||||
constants.extend(param.kind.find_constants());
|
constants.extend(param.kind.find_constants(scope));
|
||||||
}
|
}
|
||||||
constants
|
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)
|
(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);
|
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);
|
dbg!(&constants);
|
||||||
|
|
||||||
let instructions = chunk.compile(&mut compile::State { constants }, &mut Default::default());
|
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 {
|
pub enum Instruction {
|
||||||
/// R(A) := R(B)
|
/// R(A) := R(B)
|
||||||
Move(u16, u16),
|
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))
|
/// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1))
|
||||||
Call(u16, u16, u16),
|
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