-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
3top1a
committed
Jan 19, 2025
1 parent
e622370
commit 2fade2b
Showing
9 changed files
with
198 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,13 @@ | ||
use crate::ast::Expression; | ||
use std::collections::HashMap; | ||
use std::str::from_utf8; | ||
use crate::ast::Expression; | ||
|
||
// Codegen notes for myself: | ||
// - Make the codegen also do comments, they will get removed in the optimization step | ||
// - Functions: https://brainfuck.org/function_tutorial.b | ||
// - | ||
// - | ||
|
||
|
||
/// Because we do not yet know the length of functions, we need to make a list of all the | ||
/// Because we do not yet know the length of functions, we need to make a list of all the | ||
/// basic instructions and their purpose. This will be used to generate the code after initial | ||
/// analysis. | ||
enum AbstractInstruction { | ||
|
||
} | ||
|
||
enum AbstractInstruction {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
use crate::ast::Expression; | ||
use std::collections::HashMap; | ||
|
||
|
||
/// Intermediate representation | ||
/// The main purpuse of this is to convert the nested expression into a linear flat instruction list | ||
/// that is more similar to the way brainfuck works | ||
/// | ||
/// Resources: | ||
/// - https://andreabergia.com/series/stack-based-virtual-machines/ | ||
#[derive(Clone, Debug)] | ||
pub enum IR { | ||
/// Push a single byte on the stack | ||
Push(u8), | ||
/// Pop a value from the stack (zero it out) | ||
Pop, | ||
|
||
/// Add the two top most values | ||
ADD, | ||
/// Subtract the two topmost values | ||
SUB, | ||
/// Multiply the two topmost values | ||
MUL, | ||
/// Check for equality of the two topmost values | ||
EQ, | ||
|
||
/// Duplicate the topmost value | ||
DUP, | ||
|
||
/// Push topmost byte to variable storage | ||
STORE(String), | ||
/// Retrieve a named value | ||
/// This removes the variable from the storage | ||
LOAD(String), | ||
/// Start if block | ||
START_IF, | ||
/// End if block | ||
CLOSE_IF, | ||
|
||
// TODO Else blocks | ||
// TODO Functions and frames | ||
} | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct IRGenerator { | ||
ir: Vec<IR>, | ||
variables: HashMap<String, usize> | ||
} | ||
|
||
impl IRGenerator { | ||
pub fn new() -> IRGenerator { | ||
Self { | ||
ir: vec![], | ||
variables: HashMap::new(), | ||
} | ||
} | ||
|
||
pub fn generate(&mut self, ast: Vec<Expression>) -> Vec<IR> { | ||
for expr in ast { | ||
self.generate_expression(expr); | ||
} | ||
|
||
self.ir.clone() | ||
} | ||
|
||
fn load(&mut self, expr: Expression) { | ||
match expr { | ||
Expression::Number(n) => { | ||
self.ir.push(IR::Push(n)); | ||
} | ||
|
||
Expression::Path(path) => { | ||
// Duplicate the value | ||
self.ir.push(IR::LOAD(path.clone())); | ||
self.ir.push(IR::DUP); | ||
self.ir.push(IR::STORE(path)); | ||
} | ||
|
||
_ => { | ||
todo!("Not implemented: {:?}", expr); | ||
} | ||
} | ||
} | ||
|
||
fn generate_expression(&mut self, expression: Expression) { | ||
match expression { | ||
Expression::Number(n) => { | ||
self.ir.push(IR::Push(n)); | ||
} | ||
|
||
Expression::Closure {body} => { | ||
for expr in body { | ||
self.generate_expression(expr); | ||
} | ||
} | ||
|
||
Expression::Assignment {name, value} => { | ||
self.generate_expression(*value); | ||
|
||
self.variables.insert(name.clone(), 0); | ||
self.ir.push(IR::STORE(name)); | ||
} | ||
|
||
Expression::Call {name, args} => { | ||
// Load all arguments | ||
for arg in args { | ||
self.load(arg); | ||
} | ||
|
||
if name == "+" { | ||
self.ir.push(IR::ADD); | ||
} else if name == "-" { | ||
self.ir.push(IR::SUB); | ||
} else if name == "*" { | ||
self.ir.push(IR::MUL); | ||
} else if name == "==" { | ||
self.ir.push(IR::EQ); | ||
} else { | ||
todo!("Not implemented: {:?}", name); | ||
} | ||
} | ||
|
||
_ => { | ||
dbg!("Not implemented:", expression); | ||
} | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.