compile some things

This commit is contained in:
nora 2022-06-20 12:05:26 +02:00
parent e01c429076
commit 9253e6036c

View file

@ -1,7 +1,18 @@
#[derive(Debug, Clone, Copy)] use std::collections::HashMap;
use dbg_pls::DebugPls;
use logos::Span;
use crate::{
error::{CompilerError, Result},
parser,
parser::{ExprKind, StmtKind},
};
#[derive(Debug, Clone, Copy, DebugPls)]
pub struct Register(u8); pub struct Register(u8);
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, DebugPls)]
pub enum Place { pub enum Place {
Register(Register), Register(Register),
/// `[r5]` /// `[r5]`
@ -10,18 +21,18 @@ pub enum Place {
AddrLiteral(u64), AddrLiteral(u64),
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, DebugPls)]
pub enum Value { pub enum Value {
Literal(u64), Literal(u64),
Place(Place), Place(Place),
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, DebugPls)]
pub struct Location { pub struct Location {
index: usize, index: usize,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, DebugPls)]
pub enum Stmt { pub enum Stmt {
Mov { to: Place, from: Value }, Mov { to: Place, from: Value },
Add { to: Place, value: Value }, Add { to: Place, value: Value },
@ -31,3 +42,75 @@ pub enum Stmt {
Jmp { to: Location }, Jmp { to: Location },
Cmp { lhs: Value, rhs: Value }, Cmp { lhs: Value, rhs: Value },
} }
struct CompileCtx {
stmts: Vec<Stmt>,
spans: Vec<Span>,
labels: HashMap<String, usize>,
}
impl CompileCtx {
fn compile(&mut self, ast: impl Iterator<Item = parser::Stmt>) -> Result<()> {
for stmt in ast {
self.compile_stmt(stmt)?;
}
Ok(())
}
fn compile_stmt(&mut self, p_stmt: parser::Stmt) -> Result<()> {
match p_stmt.kind {
StmtKind::Mov { from, to } => {
let from = self.compile_value(from)?;
let to = self.compile_place(to)?;
let stmt = Stmt::Mov { from, to };
self.stmts.push(stmt);
self.spans.push(p_stmt.span);
}
_ => todo!("other stmt"),
}
Ok(())
}
fn compile_place(&mut self, expr: parser::Expr) -> Result<Place> {
match expr.kind {
ExprKind::Register(r) => Ok(Place::Register(Register(r))),
ExprKind::Number(_) => Err(CompilerError::simple(
"number literals are not allowed in place position".to_string(),
expr.span,
)),
ExprKind::Symbol(_) => Err(CompilerError::simple(
"symbol literals are not allowed in place position".to_string(),
expr.span,
)),
ExprKind::Addr(addr) => match addr.kind {
ExprKind::Register(r) => Ok(Place::AddrRegister(Register(r))),
ExprKind::Number(n) => Ok(Place::AddrLiteral(n)),
ExprKind::Addr(nested) => Err(CompilerError::help(
"cannot dereference result of another dereference".to_string(),
nested.span,
"save the first result in a temporary register".to_string(),
)),
ExprKind::Symbol(_) => todo!("compile to AddrLiteral"),
},
}
}
fn compile_value(&mut self, expr: parser::Expr) -> Result<Value> {
match expr.kind {
ExprKind::Number(n) => Ok(Value::Literal(n)),
ExprKind::Symbol(_) => todo!("compile to Literal"),
_ => Ok(Value::Place(self.compile_place(expr)?)),
}
}
}
pub fn compile(ast: impl Iterator<Item = parser::Stmt>) -> Result<(Vec<Stmt>, Vec<Span>)> {
let mut ctx = CompileCtx {
stmts: Vec::new(),
spans: Vec::new(),
labels: HashMap::new(),
};
ctx.compile(ast)?;
Ok((ctx.stmts, ctx.spans))
}