mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
feat: HIR instead of instructions
This commit is contained in:
parent
cb0efd3dd4
commit
4f97a39f86
|
@ -1,2 +1,2 @@
|
|||
(def message str "Hello, World")
|
||||
(def message "Hello, World")
|
||||
(print message)
|
1
example/if.vy
Normal file
1
example/if.vy
Normal file
|
@ -0,0 +1 @@
|
|||
(if (equal 1 1) (print "a"))
|
|
@ -20,12 +20,12 @@ pub enum Value {
|
|||
impl fmt::Display for Value {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Value::True => write!(f, "#t"),
|
||||
Value::False => write!(f, "#f"),
|
||||
Value::Int(i) => write!(f, "{}", i),
|
||||
Value::Float(fl) => write!(f, "{}", fl),
|
||||
Value::String(s) => write!(f, "{}", s),
|
||||
Value::Symbol(s) => write!(f, "{}", s),
|
||||
Value::True => write!(f, "$True"),
|
||||
Value::False => write!(f, "$False"),
|
||||
Value::Int(i) => write!(f, "${}", i),
|
||||
Value::Float(fl) => write!(f, "${}", fl),
|
||||
Value::String(s) => write!(f, "$\"{}\"", s),
|
||||
Value::Symbol(s) => write!(f, "${}", s),
|
||||
Value::List(car, cdr) => {
|
||||
write!(f, "(")?;
|
||||
write!(f, "{}", car)?;
|
||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -12,9 +12,9 @@ pub mod front;
|
|||
use front::parser::parse;
|
||||
|
||||
/// A middle-end for the compiler.
|
||||
/// Contains instructions generator.
|
||||
/// Contains high intermediate representation (HIR).
|
||||
pub mod middle;
|
||||
use middle::gen::generate_instructions;
|
||||
use crate::middle::hir::to_hirs;
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
@ -29,19 +29,14 @@ fn main() {
|
|||
let mut checked_tree = Vec::new();
|
||||
for node in tree {
|
||||
match node {
|
||||
Ok(node) => checked_tree.push(node),
|
||||
Ok(node) => checked_tree.push(node.0),
|
||||
Err(err) => println!("{:?}", err),
|
||||
}
|
||||
};
|
||||
|
||||
// Generate instructions
|
||||
let instructions = generate_instructions(checked_tree.into_iter());
|
||||
|
||||
// Write instructions to file
|
||||
let mut file = File::create(format!("{}.vyir" , input.file_stem().unwrap().to_str().unwrap())).unwrap();
|
||||
for instruction in instructions {
|
||||
file.write_all(instruction.to_string().as_bytes()).expect("Failed to write instructions to file");
|
||||
}
|
||||
// Convert the tree to HIR
|
||||
let hir = to_hirs(&checked_tree);
|
||||
println!("{:#?}", hir);
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
use std::borrow::Borrow;
|
||||
|
||||
use crate::front::parser::Value;
|
||||
use super::instr::Instructions;
|
||||
|
||||
pub fn generate_instructions(ast: impl Iterator<Item = (Value, (usize, usize))>) -> Vec<Instructions> {
|
||||
let mut instructions: Vec<Instructions> = Vec::new();
|
||||
for (value, _) in ast {
|
||||
match value {
|
||||
Value::List(car, cdr) => {
|
||||
match &*car.borrow() {
|
||||
Value::Symbol(ref function_name) => {
|
||||
match function_name.as_str() {
|
||||
"def" => {
|
||||
let name: Box<str> = match &cdr[0].borrow() {
|
||||
Value::Symbol(name) => name.clone().into(),
|
||||
_ => panic!("Expected symbol as first argument of define"),
|
||||
};
|
||||
|
||||
match &cdr[1].borrow() {
|
||||
Value::Int(value) => instructions.push(Instructions::Store {
|
||||
value: Value::Int(*value),
|
||||
name,
|
||||
}),
|
||||
Value::Float(value) => instructions.push(Instructions::Store {
|
||||
value: Value::Float(*value),
|
||||
name,
|
||||
}),
|
||||
Value::String(value) => instructions.push(Instructions::Store {
|
||||
value: Value::String(value.clone()),
|
||||
name,
|
||||
}),
|
||||
_ => todo!(),
|
||||
};
|
||||
},
|
||||
_ => {
|
||||
dbg!(function_name);
|
||||
todo!();
|
||||
}
|
||||
} // --- End match `function_name` ---
|
||||
},
|
||||
_ => {
|
||||
dbg!(car);
|
||||
todo!();
|
||||
}
|
||||
} // --- End match `car` ---
|
||||
}
|
||||
_ => {
|
||||
dbg!(value);
|
||||
todo!();
|
||||
}
|
||||
} // --- End match `value` ---
|
||||
}
|
||||
|
||||
instructions
|
||||
}
|
116
src/middle/hir.rs
Normal file
116
src/middle/hir.rs
Normal file
|
@ -0,0 +1,116 @@
|
|||
use std::{rc::Rc, borrow::Borrow};
|
||||
|
||||
use crate::front::parser::Value;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum HIRLiteral {
|
||||
True, False, Nil,
|
||||
Int(i64), Float(f64),
|
||||
String(String), Symbol(String),
|
||||
List(Box<HIRLiteral>, Vec<HIRLiteral>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum HIR {
|
||||
Declare { name: String, value: HIRLiteral },
|
||||
Set { name: String, value: HIRLiteral },
|
||||
Let { bindings: Vec<(String, HIR)>, body: Vec<HIR> },
|
||||
If { condition: Box<HIR>, then: Box<HIR>, else_: Option<Box<HIR>> },
|
||||
Call { func: String, args: Rc<Vec<HIR>> },
|
||||
|
||||
Quoted { body: HIRLiteral },
|
||||
Literal(HIRLiteral),
|
||||
}
|
||||
|
||||
pub fn to_hirs(ast: &Vec<Value>) -> Vec<HIR> {
|
||||
let mut hir = Vec::new();
|
||||
for node in ast {
|
||||
match node {
|
||||
Value::List(car, cdr) => {
|
||||
match &*car.borrow() {
|
||||
Value::Symbol(ref function) => {
|
||||
match function.as_str() {
|
||||
|
||||
"quote" => {
|
||||
hir.push(HIR::Quoted { body: to_hir_literal(&cdr[0].clone()) });
|
||||
},
|
||||
|
||||
"if" => {
|
||||
let cond = to_hir_single(&cdr[0].clone());
|
||||
let then = to_hir_single(&cdr[1].clone());
|
||||
let else_ = if cdr.len() > 2 { Some(Box::new(to_hir_single(&cdr[2].clone()))) }
|
||||
else { None };
|
||||
|
||||
hir.push(HIR::If { condition: Box::new(cond), then: Box::new(then), else_ });
|
||||
}
|
||||
|
||||
"def" => {
|
||||
let name: String = match &cdr[0].clone() {
|
||||
Value::Symbol(name) => name.clone(),
|
||||
_ => panic!("def expects a symbol as first argument"),
|
||||
};
|
||||
let value = &cdr[1].clone();
|
||||
|
||||
hir.push(HIR::Declare { name, value: to_hir_literal(value) });
|
||||
},
|
||||
|
||||
"print" => {
|
||||
let value = &cdr[0].clone();
|
||||
|
||||
hir.push(HIR::Call { func: "print".to_string(), args: Rc::new(vec![to_hir_single(value)]) });
|
||||
},
|
||||
|
||||
"equal" => {
|
||||
let left = &cdr[0].clone();
|
||||
let right = &cdr[1].clone();
|
||||
|
||||
hir.push(HIR::Call { func: "equal".to_string(), args: Rc::new(vec![to_hir_single(left), to_hir_single(right)]) });
|
||||
},
|
||||
|
||||
_ => {
|
||||
dbg!(function);
|
||||
todo!();
|
||||
}
|
||||
} // --- End match `function` ---
|
||||
},
|
||||
_ => {
|
||||
dbg!(car);
|
||||
todo!();
|
||||
} // --- End match `car` ---
|
||||
}
|
||||
},
|
||||
_ => hir.push(to_hir_single(node)),
|
||||
} // --- End match `node` ---
|
||||
}
|
||||
hir
|
||||
}
|
||||
|
||||
fn to_hir_single(value: &Value) -> HIR {
|
||||
match value {
|
||||
Value::List(car, cdr) => {
|
||||
let mut vec: Vec<Value> = Vec::new();
|
||||
let list: Value = Value::List(car.clone(), cdr.clone());
|
||||
vec.push(list);
|
||||
let result = to_hirs(&vec)[0].clone();
|
||||
result
|
||||
},
|
||||
_ => HIR::Literal(to_hir_literal(value)),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_hir_literal(value: &Value) -> HIRLiteral {
|
||||
match value {
|
||||
Value::True => HIRLiteral::True,
|
||||
Value::False => HIRLiteral::False,
|
||||
Value::Int(i) => HIRLiteral::Int(*i),
|
||||
Value::Float(fl) => HIRLiteral::Float(*fl),
|
||||
Value::String(s) => HIRLiteral::String(s.clone()),
|
||||
Value::Symbol(s) => HIRLiteral::Symbol(s.clone()),
|
||||
Value::List(car, cdr) => {
|
||||
let car_literal = to_hir_literal(&car);
|
||||
let cdr_literal = cdr.iter().map(|a| to_hir_literal(a)).collect::<Vec<HIRLiteral>>();
|
||||
HIRLiteral::List(Box::new(car_literal), cdr_literal)
|
||||
},
|
||||
Value::Nil => HIRLiteral::Nil,
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
use std::fmt;
|
||||
|
||||
use crate::front::parser::Value;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Instructions {
|
||||
Store { value: Value, name: Box<str> },
|
||||
Push { value: Value },
|
||||
}
|
||||
|
||||
impl fmt::Display for Instructions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Instructions::Store { value, name } => write!(f, "store {} {}", value, name),
|
||||
Instructions::Push { value } => write!(f, "push {}", value),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,2 +1 @@
|
|||
pub mod instr;
|
||||
pub mod gen;
|
||||
pub mod hir;
|
Loading…
Reference in a new issue