diff --git a/src/main.rs b/src/main.rs index c9c4b5d..6bc99cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::io; mod parser; fn main() -> Result<(), io::Error> { - let file = std::fs::read_to_string("test.asm")?; + let file = std::fs::read_to_string("../test.at")?; parser::run(&file); Ok(()) } diff --git a/src/parser.rs b/src/parser.rs index ae01149..20bd085 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,5 +1,6 @@ use dbg_pls::DebugPls; -use logos::{Lexer, Logos}; +use logos::{Lexer, Logos, Span}; +use std::iter::Peekable; #[derive(Debug, Clone, PartialEq, Eq, Logos, DebugPls)] pub enum Token<'a> { @@ -46,3 +47,117 @@ pub fn run(src: &str) { let tokens = lex(src).collect::>(); dbg_pls::color!(tokens); } + +#[derive(Debug, PartialEq, Eq)] +pub struct Stmt { + pub kind: StmtKind, + pub span: Span, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum StmtKind { + Mov { to: Expr, from: Expr }, + Add { to: Expr, value: Expr }, + Sub { to: Expr, value: Expr }, + Mul { to: Expr, value: Expr }, + Div { to: Expr, value: Expr }, + Jmp { to: Expr }, + Je { to: Expr }, + Cmp { rhs: Expr, lhs: Expr }, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Expr { + pub kind: ExprKind, + pub span: Span, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum ExprKind { + Register, + Number, + Addr(Box), +} + +struct Parser<'a, I> +where + I: Iterator>, +{ + iter: Peekable, +} + +struct CompilerError; + +type Result = std::result::Result; + +macro_rules! expect { + ($self:ident, $token:pat) => { + if let $token = $self.next()? { + return Err(CompilerError); + } + }; +} + +fn stmt(kind: StmtKind, span: Span) -> Stmt { + Stmt { kind, span } +} + +impl<'a, I> Parser<'a, I> +where + I: Iterator>, +{ + fn program(&mut self) -> Result> { + todo!() + } + + fn stmt(&mut self) -> Result { + Ok(match self.next()? { + Token::Mov => { + let to = self.expr()?; + expect!(self, Token::Comma); + let from = self.expr()?; + stmt(StmtKind::Mov { to, from }, Default::default()) + } + Token::Jmp => { + let to = self.expr()?; + Stmt { + kind: StmtKind::Jmp { to }, + span: Default::default(), + } + } + Token::Je => { + let to = self.expr()?; + stmt(StmtKind::Je { to }, Default::default()) + } + Token::Cmp => { + let lhs = self.expr()?; + expect!(self, Token::Comma); + let rhs = self.expr()?; + stmt(StmtKind::Cmp { lhs, rhs }, Default::default()) + } + Token::Add => {} + Token::Sub => {} + Token::Mul => {} + Token::Div => {} + Token::BracketOpen => {} + Token::BracketClose => {} + Token::Comma => {} + Token::Label(_) => {} + Token::Number(_) => {} + Token::Word(_) => {} + Token::Error => {} + }) + } + + fn expr(&mut self) -> Result { + todo!() + } + + fn peek(&mut self) -> Result<&Token<'a>> { + self.iter.peek().ok_or(CompilerError) + } + + fn next(&mut self) -> Result> { + self.iter.next().ok_or(CompilerError) + } +} diff --git a/test.asm b/test.at similarity index 87% rename from test.asm rename to test.at index 86f80fa..0fd78b1 100644 --- a/test.asm +++ b/test.at @@ -7,6 +7,7 @@ jmp exit // loop false: +mov r1, [8] jmp false