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::ir::{Command, IRepr};
|
||||||
|
|
||||||
use crate::{
|
|
||||||
lexer::Keyword,
|
|
||||||
parser::{LispAtom, SExpression},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum InstructionFrom {
|
enum InstructionFrom {
|
||||||
|
@ -40,144 +35,124 @@ enum InstructionTo {
|
||||||
|
|
||||||
RegisterSP,
|
RegisterSP,
|
||||||
RegisterSB,
|
RegisterSB,
|
||||||
|
|
||||||
|
IncSP,
|
||||||
|
DecSP,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
struct Command {
|
struct Instruction {
|
||||||
data_from: InstructionFrom,
|
from: InstructionFrom,
|
||||||
data_to: InstructionTo,
|
to: InstructionTo,
|
||||||
data: i8,
|
value: i8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Scope {
|
pub struct Code {
|
||||||
variables: Vec<String>,
|
instructions: Vec<Instruction>,
|
||||||
stack_position: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
impl From<IRepr> for Code {
|
||||||
pub struct EightBitLang {
|
fn from(value: IRepr) -> Self {
|
||||||
instructions: Vec<Command>,
|
value.commands.into_iter().map(|x| Code::from(x)).sum()
|
||||||
labels: Option<HashMap<String, usize>>,
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GenerateCode {
|
impl From<Command> for Code {
|
||||||
fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error>
|
fn from(value: Command) -> Self {
|
||||||
where
|
use Instruction as I;
|
||||||
Self: Sized;
|
use InstructionFrom as IF;
|
||||||
|
use InstructionTo as IT;
|
||||||
type Error;
|
match value {
|
||||||
}
|
Command::PopR1 => vec![
|
||||||
|
I::new(IF::RegisterSP, IT::RamAddressLower, 0x00),
|
||||||
impl GenerateCode for SExpression {
|
I::new(IF::RAM, IT::RegisterA, 0x00),
|
||||||
fn to_code(self, codegen_scope: &mut Scope) -> Result<EightBitLang, Self::Error> {
|
I::new(IF::ROM, IT::DecSP, 0x00),
|
||||||
match self {
|
],
|
||||||
SExpression::Atom(a) => a.to_code(codegen_scope),
|
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!(),
|
_ => todo!(),
|
||||||
}
|
}.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Error = Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenerateCode for LispAtom {
|
impl AddAssign for Code {
|
||||||
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 {
|
|
||||||
fn add_assign(&mut self, mut rhs: Self) {
|
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);
|
self.instructions.append(&mut rhs.instructions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Command> for EightBitLang {
|
impl AddAssign<Instruction> for Code {
|
||||||
fn from(value: Command) -> Self {
|
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 {
|
Self {
|
||||||
instructions: vec![value],
|
instructions: value,
|
||||||
labels: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EightBitLang {
|
impl Sum for Code {
|
||||||
fn push(value: i8, codegen_scope: &mut Scope) -> Self {
|
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||||
use InstructionFrom as IF;
|
let mut sum = Self::new();
|
||||||
use InstructionTo as IT;
|
|
||||||
|
|
||||||
codegen_scope.stack_position += 1;
|
for i in iter {
|
||||||
|
sum += i;
|
||||||
|
}
|
||||||
|
|
||||||
let mut commands = Vec::new();
|
sum
|
||||||
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));
|
|
||||||
|
|
||||||
|
impl Code {
|
||||||
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
instructions: commands,
|
instructions: vec![]
|
||||||
labels: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Instruction {
|
||||||
fn new(data_from: InstructionFrom, data_to: InstructionTo, data: i8) -> Self {
|
fn new(from: InstructionFrom, to: InstructionTo, value: i8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data_from,
|
from,
|
||||||
data_to,
|
to,
|
||||||
data,
|
value,
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Scope {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
variables: Vec::new(),
|
|
||||||
stack_position: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
14
src/ir.rs
14
src/ir.rs
|
@ -12,11 +12,11 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct IRepr {
|
pub struct IRepr {
|
||||||
commands: Vec<Command>,
|
pub commands: Vec<Command>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
enum Command {
|
pub enum Command {
|
||||||
PushInt(isize),
|
PushInt(isize),
|
||||||
PushSum,
|
PushSum,
|
||||||
PopR1,
|
PopR1,
|
||||||
|
@ -168,9 +168,6 @@ impl ToIRMacro for Macro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(&commands);
|
|
||||||
dbg!(&ir_scope);
|
|
||||||
|
|
||||||
while body != NIL {
|
while body != NIL {
|
||||||
match body {
|
match body {
|
||||||
SExpression::Atom(_a) => todo!(),
|
SExpression::Atom(_a) => todo!(),
|
||||||
|
@ -181,12 +178,11 @@ impl ToIRMacro for Macro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(&commands);
|
|
||||||
dbg!(&ir_scope);
|
|
||||||
|
|
||||||
commands += Command::Leave;
|
commands += Command::Leave;
|
||||||
|
|
||||||
todo!()
|
ir_scope.stack_position = ir_scope.stack_positions.pop().unwrap();
|
||||||
|
|
||||||
|
Ok(commands)
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
|
21
src/main.rs
21
src/main.rs
|
@ -8,12 +8,11 @@ mod error;
|
||||||
|
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
// pub use error::*;
|
// pub use error::*;
|
||||||
use ir::IRepr;
|
|
||||||
use lexer::TokenString;
|
|
||||||
use parser::SExpression;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
code_gen::{EightBitLang, GenerateCode, Scope},
|
code_gen::Code,
|
||||||
|
lexer::TokenString,
|
||||||
|
parser::SExpression,
|
||||||
ir::generate_code,
|
ir::generate_code,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,17 +22,19 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
// let code = r#"(mul 2 (add 3 4))"#.to_string();
|
// let code = r#"(mul 2 (add 3 4))"#.to_string();
|
||||||
|
|
||||||
// let code = "(add 3 4) (add 1 2)";
|
let code = "(add 3 4) (add 1 2)";
|
||||||
let code = "(let ((a 3)) (out (add 1 a)) (out (add 2 a)))";
|
// 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())?;
|
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);
|
dbg!(code);
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -65,8 +65,7 @@ impl SExpression {
|
||||||
state.expression[state.index].row, state.expression[state.index].col
|
state.expression[state.index].row, state.expression[state.index].col
|
||||||
))),
|
))),
|
||||||
};
|
};
|
||||||
|
expr
|
||||||
dbg!(expr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expression(state: &mut State) -> Result<Self, Error> {
|
fn parse_expression(state: &mut State) -> Result<Self, Error> {
|
||||||
|
@ -78,7 +77,7 @@ impl SExpression {
|
||||||
}
|
}
|
||||||
state.index += 1;
|
state.index += 1;
|
||||||
|
|
||||||
let expression_1 = dbg!(Self::parse_sexpression(state)?);
|
let expression_1 = Self::parse_sexpression(state)?;
|
||||||
state.index += 1;
|
state.index += 1;
|
||||||
|
|
||||||
// Is pair
|
// Is pair
|
||||||
|
|
Loading…
Reference in a new issue