diff --git a/src/main.rs b/src/main.rs index 17677ce..edf6529 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use crate::lexer::{Lex, Lexer, Token, TokenType}; use efcl::{bold, color, Color}; -use parse::{create_parser, Parser}; +use parse::{create_parser, AssemblyArchitecture, Parser}; use std::fs::File; use std::io::{prelude::*, BufReader}; use std::io::{stdin, stdout, Write}; @@ -17,7 +17,7 @@ struct Opt { verbose: bool, #[structopt(short, long)] - asm: bool, + asm: Option, #[structopt(short, long)] filename: Option, @@ -78,9 +78,13 @@ fn run_file(filename: String, verbose: bool) { } } -fn interactive(verbose: bool, asm: bool) { +fn interactive(verbose: bool, asm: Option) { let mut p = create_parser(verbose); + if let Some(a) = asm { + p.set_asm_arch(a); + } + loop { print!("{}", color!(Color::GREEN, bold!("\n> ").as_str())); stdout().flush().expect("Failed to flush stdout"); @@ -115,7 +119,7 @@ fn interactive(verbose: bool, asm: bool) { let out = p.parse(tokens); - if asm { + if asm.is_some() { for x in p.output_asm() { println!("{}", color!(Color::BLACK, x.as_str())); } @@ -137,6 +141,13 @@ fn main() { if let Some(filename) = opt.filename { run_file(filename, opt.verbose); } else { - interactive(opt.verbose, opt.asm); + let mut asm = None; + if opt.asm == Some("x86".to_string()) || opt.asm == Some("x86-64".to_string()) { + asm = Some(AssemblyArchitecture::X86_64); + } else if opt.asm == Some("RISCV".to_string()) || opt.asm == Some("RISC-V".to_string()) { + asm = Some(AssemblyArchitecture::RISCV); + } + + interactive(opt.verbose, asm); } } diff --git a/src/parse.rs b/src/parse.rs index 26a8c08..04a8831 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -6,6 +6,12 @@ use super::lexer::{Token, TokenType}; use efcl::{bold, color, Color}; use std::collections::HashMap; +#[derive(Debug, Copy, Clone)] +pub enum AssemblyArchitecture { + X86_64, + RISCV, +} + pub trait Parser { fn variable_check_pop(&mut self) -> Option; fn match_token_type(&mut self, token: Token); @@ -17,6 +23,7 @@ pub trait Parser { fn asm_sub(&mut self); fn output_asm(&mut self) -> Vec; fn reset_asm(&mut self); + fn set_asm_arch(&mut self, assembly_arch: AssemblyArchitecture); } #[derive(Debug)] @@ -30,7 +37,9 @@ pub struct ParserState { function_memory: HashMap>, token_index: usize, assembly: Vec, + assembly_arch: AssemblyArchitecture, temp_reg_index: i8, + temp_reg_index_init: i8, } impl Parser for ParserState { @@ -38,9 +47,23 @@ impl Parser for ParserState { return self.assembly.clone(); } + fn set_asm_arch(&mut self, assembly_arch: AssemblyArchitecture) { + self.assembly_arch = assembly_arch; + match assembly_arch { + AssemblyArchitecture::RISCV => { + self.temp_reg_index_init = 0; + self.temp_reg_index = self.temp_reg_index_init; + } + AssemblyArchitecture::X86_64 => { + self.temp_reg_index_init = 8; + self.temp_reg_index = self.temp_reg_index_init; + } + } + } + fn reset_asm(&mut self) { self.assembly = vec![]; - self.temp_reg_index = 0; + self.temp_reg_index = self.temp_reg_index_init; } fn convert_to_bool(&mut self, first: Option, token: Token) { @@ -139,29 +162,62 @@ impl Parser for ParserState { } fn asm_li(&mut self, token: Token) { - self.assembly - .push(format!("li t{} {}", self.temp_reg_index, token.value)); - self.temp_reg_index += 1; + match self.assembly_arch { + AssemblyArchitecture::RISCV => { + self.assembly + .push(format!("li t{} {}", self.temp_reg_index, token.value)); + self.temp_reg_index += 1; + } + AssemblyArchitecture::X86_64 => { + self.assembly + .push(format!("mov r{} {}", self.temp_reg_index, token.value)); + self.temp_reg_index += 1; + } + } } fn asm_add(&mut self) { - self.assembly.push(format!( - "add t{} t{} t{}", - self.temp_reg_index - 2, - self.temp_reg_index - 2, - self.temp_reg_index - 1 - )); - self.temp_reg_index -= 1; + match self.assembly_arch { + AssemblyArchitecture::RISCV => { + self.assembly.push(format!( + "add t{} t{} t{}", + self.temp_reg_index - 2, + self.temp_reg_index - 2, + self.temp_reg_index - 1 + )); + self.temp_reg_index -= 1; + } + AssemblyArchitecture::X86_64 => { + self.assembly.push(format!( + "add r{} r{}", + self.temp_reg_index - 2, + self.temp_reg_index - 1 + )); + self.temp_reg_index -= 1; + } + } } fn asm_sub(&mut self) { - self.assembly.push(format!( - "sub t{} t{} t{}", - self.temp_reg_index - 2, - self.temp_reg_index - 2, - self.temp_reg_index - 1 - )); - self.temp_reg_index -= 1; + match self.assembly_arch { + AssemblyArchitecture::RISCV => { + self.assembly.push(format!( + "sub t{} t{} t{}", + self.temp_reg_index - 2, + self.temp_reg_index - 2, + self.temp_reg_index - 1 + )); + self.temp_reg_index -= 1; + } + AssemblyArchitecture::X86_64 => { + self.assembly.push(format!( + "sub r{} r{}", + self.temp_reg_index - 2, + self.temp_reg_index - 1 + )); + self.temp_reg_index -= 1; + } + } } fn match_token_type(&mut self, token: Token) { @@ -650,7 +706,9 @@ pub fn create_parser(verbose: bool) -> ParserState { function_stack: Vec::::new(), token_index: 0, assembly: Vec::::new(), + assembly_arch: AssemblyArchitecture::RISCV, temp_reg_index: 0, + temp_reg_index_init: 0, } }