From e309d2208a1ba2f96a0b380c2e6b42739b4dd309 Mon Sep 17 00:00:00 2001 From: vanten-s Date: Sun, 11 Aug 2024 04:25:14 +0200 Subject: [PATCH] Works :) --- src/assembler.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++--- src/error.rs | 2 + src/main.rs | 11 ++++- src/parser.rs | 16 +++---- 4 files changed, 122 insertions(+), 15 deletions(-) diff --git a/src/assembler.rs b/src/assembler.rs index 88f255d..07580ff 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -1,13 +1,111 @@ -use crate::parser::Instruction; +use std::collections::HashMap; + +use crate::{ + parser::{Instruction, Value}, + Result, +}; + +type Function = fn(&mut Assembler, usize); pub struct Assembler { - instruction: Instruction, + functions: HashMap, + stack: Vec, + assembled: Vec, +} + +trait Assemble { + fn assemble(self, assembler: &mut Assembler) -> Result<()>; +} + +impl Assemble for Value { + fn assemble(self, assembler: &mut Assembler) -> Result<()> { + match self { + Self::Instruction(instruction) => instruction.assemble(assembler), + Value::IntegerLiteral(v) => { + let bytes = v.to_le_bytes(); + + assembler.push(v.to_string()); + + assembler.add_instruction(&[0x68]); + assembler.add_instruction(&bytes); + + Ok(()) + } + _ => todo!() + } + } +} + +impl Assemble for Instruction { + fn assemble(self, assembler: &mut Assembler) -> Result<()> { + let n_arguments = self.arguments.len(); + + for argument in self.arguments { + argument.assemble(assembler)?; + } + + let function = match assembler.functions.get(&self.name) { + Some(v) => v, + None => return Err(crate::Error::UndefinedIdentifier(self.name)) + }; + + function(assembler, n_arguments); + + Ok(()) + } } impl Assembler { - pub fn assemble(instruction: Instruction) -> Vec { - let assembler = Assembler { instruction }; + pub fn assemble(instruction: Instruction) -> Result> { + let mut assembler = Self { + functions: Self::default_functions(), + stack: Vec::new(), + assembled: Vec::new(), + }; + instruction.assemble(&mut assembler)?; + Ok(assembler.assembled) + } - todo!() + fn add_instruction(&mut self, instruction: &[u8]) { + self.assembled.extend_from_slice(instruction); + } + + fn push(&mut self, identifier: String) { + self.stack.push(identifier); + } + + fn pop(&mut self) { + self.stack.pop(); + } + + fn get_stack_location(&self, identifier: &str) -> Option { + self.stack + .iter() + .position(|x| x == identifier) + .map(|x| x as u32) + } + + fn default_functions() -> HashMap { + let mut map: HashMap = HashMap::new(); + + map.insert( + "+".to_string(), + |assembler, n_arguments| { + if n_arguments != 2 { todo!() } + + assembler.add_instruction(&[0x58]); // Pop EAX + assembler.pop(); + + assembler.add_instruction(&[0x03, 0x04, 0x24]); // add (%esp), %eax + + assembler.add_instruction(&[0x5B]); // Pop EBX + assembler.pop(); + + assembler.add_instruction(&[0x50]); // Push EAX + assembler.push("".to_string()); + }, + ); + + map } } diff --git a/src/error.rs b/src/error.rs index e87f302..bd450ce 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,7 @@ #[derive(Clone, Debug, Hash)] pub enum Error { SyntaxError(SyntaxError), + UndefinedIdentifier(String), } #[derive(Clone, Debug, Hash)] @@ -16,6 +17,7 @@ impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Error::SyntaxError(e) => write!(f, "Error at: {}:{}. {}", e.row, e.column, e.message), + Error::UndefinedIdentifier(e) => write!(f, "Error: undefined identifier: {e}"), } } } diff --git a/src/main.rs b/src/main.rs index 4ddbd27..1ce4ac5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,14 @@ mod error; pub use error::*; fn main() { - let code = "(+ 1 2)".to_string(); + let code = "(+ 1 (+ 5 5))".to_string(); - dbg!(parser::Parser::parse(code).unwrap()); + let parsed = dbg!(parser::Parser::parse(code).unwrap()); + let assembled = assembler::Assembler::assemble(parsed).unwrap(); + + for byte in assembled { + print!("{byte:#X}, "); + } + + println!(""); } diff --git a/src/parser.rs b/src/parser.rs index 31548f0..2294c82 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -7,17 +7,17 @@ pub struct Parser { lines: Vec>, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct Instruction { - name: String, - arguments: Vec, + pub name: String, + pub arguments: Vec, } -#[derive(Debug)] -enum Value { +#[derive(Debug, Clone)] +pub(crate) enum Value { Instruction(Instruction), StringLiteral(String), - IntegerLiteral(usize), + IntegerLiteral(u32), Identifier(String), } @@ -105,7 +105,7 @@ impl Parser { Ok(accumulator) } - fn integer_literal(&mut self) -> Result { + fn integer_literal(&mut self) -> Result { let mut accumulator = String::new(); while self.lines[self.row][self.column].is_numeric() { @@ -115,7 +115,7 @@ impl Parser { self.jump_whitespace(); - match accumulator.parse::() { + match accumulator.parse() { Ok(v) => Ok(v), Err(_e) => Err(Error::SyntaxError(SyntaxError { row: self.row,