Beginning
This commit is contained in:
parent
d9bea76666
commit
d81272f085
199
src/code_gen.rs
199
src/code_gen.rs
|
@ -1,11 +1,6 @@
|
|||
use std::{collections::HashMap, ops::AddAssign};
|
||||
use std::{iter::Sum, ops::{Add, AddAssign}};
|
||||
|
||||
use color_eyre::eyre::Error;
|
||||
|
||||
use crate::{
|
||||
lexer::Keyword,
|
||||
parser::{LispAtom, SExpression},
|
||||
};
|
||||
use crate::ir::{Command, IRepr};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum InstructionFrom {
|
||||
|
@ -40,144 +35,124 @@ enum InstructionTo {
|
|||
|
||||
RegisterSP,
|
||||
RegisterSB,
|
||||
|
||||
IncSP,
|
||||
DecSP,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct Command {
|
||||
data_from: InstructionFrom,
|
||||
data_to: InstructionTo,
|
||||
data: i8,
|
||||
struct Instruction {
|
||||
from: InstructionFrom,
|
||||
to: InstructionTo,
|
||||
value: i8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Scope {
|
||||
variables: Vec<String>,
|
||||
stack_position: usize,
|
||||
pub struct Code {
|
||||
instructions: Vec<Instruction>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct EightBitLang {
|
||||
instructions: Vec<Command>,
|
||||
labels: Option<HashMap<String, usize>>,
|
||||
impl From<IRepr> for Code {
|
||||
fn from(value: IRepr) -> Self {
|
||||
value.commands.into_iter().map(|x| Code::from(x)).sum()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GenerateCode {
|
||||
fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
type Error;
|
||||
}
|
||||
|
||||
impl GenerateCode for SExpression {
|
||||
fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error> {
|
||||
match self {
|
||||
SExpression::Atom(a) => a.to_code(codegen_scope),
|
||||
impl From<Command> for Code {
|
||||
fn from(value: Command) -> Self {
|
||||
use Instruction as I;
|
||||
use InstructionFrom as IF;
|
||||
use InstructionTo as IT;
|
||||
match value {
|
||||
Command::PopR1 => vec![
|
||||
I::new(IF::RegisterSP, IT::RamAddressLower, 0x00),
|
||||
I::new(IF::RAM, IT::RegisterA, 0x00),
|
||||
I::new(IF::ROM, IT::DecSP, 0x00),
|
||||
],
|
||||
Command::PopR2 => vec![
|
||||
I::new(IF::RegisterSP, IT::RamAddressLower, 0x00),
|
||||
I::new(IF::RAM, IT::RegisterB, 0x00),
|
||||
I::new(IF::ROM, IT::DecSP, 0x00),
|
||||
],
|
||||
Command::PushInt(val) => vec![
|
||||
I::new(IF::RegisterSP, IT::RamAddressLower, 0x00),
|
||||
I::new(IF::ROM, IT::RAM, val as i8),
|
||||
I::new(IF::ROM, IT::IncSP, 0x00),
|
||||
],
|
||||
Command::PushSum => vec![
|
||||
I::new(IF::RegisterSP, IT::RamAddressLower, 0x00),
|
||||
I::new(IF::ALU, IT::RAM, 0x00),
|
||||
I::new(IF::ROM, IT::IncSP, 0x00),
|
||||
],
|
||||
_ => todo!(),
|
||||
}
|
||||
}.into()
|
||||
}
|
||||
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl GenerateCode for LispAtom {
|
||||
fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error> {
|
||||
match self {
|
||||
LispAtom::Keyword(keyword) => keyword.to_code(codegen_scope),
|
||||
LispAtom::Integer(number) => number.to_code(codegen_scope),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl GenerateCode for isize {
|
||||
fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error> {
|
||||
if let Err(_e) = i8::try_from(self) {
|
||||
return Err(Error::msg("Yo integer too big brah"));
|
||||
}
|
||||
|
||||
return Ok(EightBitLang::push(self as i8, codegen_scope));
|
||||
}
|
||||
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl GenerateCode for Keyword {
|
||||
fn to_code(self, _codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error> {
|
||||
match self {
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl AddAssign for EightBitLang {
|
||||
impl AddAssign for Code {
|
||||
fn add_assign(&mut self, mut rhs: Self) {
|
||||
let mut labels = self.labels.clone().unwrap();
|
||||
if rhs.labels.is_some() || self.labels.is_some() {
|
||||
if self.labels.is_none() {
|
||||
labels = rhs.labels.unwrap();
|
||||
} else if rhs.labels.is_none() {
|
||||
} else {
|
||||
labels = HashMap::new();
|
||||
for label in rhs.labels.unwrap() {
|
||||
labels.insert(label.0, label.1 + self.instructions.len());
|
||||
}
|
||||
}
|
||||
self.labels = Some(labels);
|
||||
}
|
||||
self.instructions.append(&mut rhs.instructions);
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Command> for EightBitLang {
|
||||
fn from(value: Command) -> Self {
|
||||
impl AddAssign<Instruction> for Code {
|
||||
fn add_assign(&mut self, rhs: Instruction) {
|
||||
self.instructions.push(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Code {
|
||||
fn add(mut self, rhs: Self) -> Self::Output {
|
||||
self += rhs;
|
||||
self
|
||||
}
|
||||
|
||||
type Output = Self;
|
||||
}
|
||||
|
||||
impl Add<Instruction> for Code {
|
||||
fn add(mut self, rhs: Instruction) -> Self::Output {
|
||||
self += rhs;
|
||||
self
|
||||
}
|
||||
|
||||
type Output = Self;
|
||||
}
|
||||
|
||||
impl From<Vec<Instruction>> for Code {
|
||||
fn from(value: Vec<Instruction>) -> Self {
|
||||
Self {
|
||||
instructions: vec![value],
|
||||
labels: None,
|
||||
instructions: value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EightBitLang {
|
||||
fn push(value: i8, codegen_scope: &mut Scope) -> Self {
|
||||
use InstructionFrom as IF;
|
||||
use InstructionTo as IT;
|
||||
impl Sum for Code {
|
||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||
let mut sum = Self::new();
|
||||
|
||||
codegen_scope.stack_position += 1;
|
||||
for i in iter {
|
||||
sum += i;
|
||||
}
|
||||
|
||||
let mut commands = Vec::new();
|
||||
commands.push(Command::new(IF::RegisterSP, IT::RegisterA, 0x00));
|
||||
commands.push(Command::new(IF::ROM, IT::RegisterB, 0x01));
|
||||
commands.push(Command::new(IF::ALU, IT::RegisterSP, 0x00));
|
||||
commands.push(Command::new(IF::RegisterSP, IT::RamAddressLower, 0x00));
|
||||
commands.push(Command::new(IF::ROM, IT::RAM, value));
|
||||
sum
|
||||
}
|
||||
}
|
||||
|
||||
impl Code {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
instructions: commands,
|
||||
labels: None,
|
||||
instructions: vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Command {
|
||||
fn new(data_from: InstructionFrom, data_to: InstructionTo, data: i8) -> Self {
|
||||
impl Instruction {
|
||||
fn new(from: InstructionFrom, to: InstructionTo, value: i8) -> Self {
|
||||
Self {
|
||||
data_from,
|
||||
data_to,
|
||||
data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
variables: Vec::new(),
|
||||
stack_position: 0,
|
||||
from,
|
||||
to,
|
||||
value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
src/ir.rs
14
src/ir.rs
|
@ -12,11 +12,11 @@ use crate::{
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct IRepr {
|
||||
commands: Vec<Command>,
|
||||
pub commands: Vec<Command>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum Command {
|
||||
pub enum Command {
|
||||
PushInt(isize),
|
||||
PushSum,
|
||||
PopR1,
|
||||
|
@ -168,9 +168,6 @@ impl ToIRMacro for Macro {
|
|||
}
|
||||
}
|
||||
|
||||
dbg!(&commands);
|
||||
dbg!(&ir_scope);
|
||||
|
||||
while body != NIL {
|
||||
match body {
|
||||
SExpression::Atom(_a) => todo!(),
|
||||
|
@ -181,12 +178,11 @@ impl ToIRMacro for Macro {
|
|||
}
|
||||
}
|
||||
|
||||
dbg!(&commands);
|
||||
dbg!(&ir_scope);
|
||||
|
||||
commands += Command::Leave;
|
||||
|
||||
todo!()
|
||||
ir_scope.stack_position = ir_scope.stack_positions.pop().unwrap();
|
||||
|
||||
Ok(commands)
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
|
|
21
src/main.rs
21
src/main.rs
|
@ -8,12 +8,11 @@ mod error;
|
|||
|
||||
use color_eyre::eyre::Result;
|
||||
// pub use error::*;
|
||||
use ir::IRepr;
|
||||
use lexer::TokenString;
|
||||
use parser::SExpression;
|
||||
|
||||
use crate::{
|
||||
code_gen::{EightBitLang, GenerateCode, Scope},
|
||||
code_gen::Code,
|
||||
lexer::TokenString,
|
||||
parser::SExpression,
|
||||
ir::generate_code,
|
||||
};
|
||||
|
||||
|
@ -23,17 +22,19 @@ fn main() -> Result<()> {
|
|||
|
||||
// let code = r#"(mul 2 (add 3 4))"#.to_string();
|
||||
|
||||
// let code = "(add 3 4) (add 1 2)";
|
||||
let code = "(let ((a 3)) (out (add 1 a)) (out (add 2 a)))";
|
||||
let code = "(add 3 4) (add 1 2)";
|
||||
// let code = "(let ((a 3)) (out (add 1 a)) (out (add 2 a)))";
|
||||
|
||||
let lexed: TokenString = dbg!((code.parse())?);
|
||||
let lexed: TokenString = code.parse()?;
|
||||
|
||||
let parsed: Vec<SExpression> = (lexed.try_into())?;
|
||||
println!("{parsed:?}");
|
||||
for instruction in parsed.clone() {
|
||||
println!("{instruction}");
|
||||
}
|
||||
|
||||
let code: IRepr = generate_code(parsed)?;
|
||||
let code = generate_code(parsed)?;
|
||||
|
||||
// let code: EightBitLang = code.to_code(&mut Scope::new())?;
|
||||
let code: Code = code.into();
|
||||
|
||||
dbg!(code);
|
||||
/*
|
||||
|
|
|
@ -65,8 +65,7 @@ impl SExpression {
|
|||
state.expression[state.index].row, state.expression[state.index].col
|
||||
))),
|
||||
};
|
||||
|
||||
dbg!(expr)
|
||||
expr
|
||||
}
|
||||
|
||||
fn parse_expression(state: &mut State) -> Result<Self, Error> {
|
||||
|
@ -78,7 +77,7 @@ impl SExpression {
|
|||
}
|
||||
state.index += 1;
|
||||
|
||||
let expression_1 = dbg!(Self::parse_sexpression(state)?);
|
||||
let expression_1 = Self::parse_sexpression(state)?;
|
||||
state.index += 1;
|
||||
|
||||
// Is pair
|
||||
|
|
Loading…
Reference in a new issue