diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index 69c7aa2..6b270df 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -1,19 +1,33 @@ -use std::rc::Rc; use crate::parse::ast::*; use skylang::temp; +use std::rc::Rc; -const REGISTERS: [&str; 9] = ["r10", "r11", "r12", "r13", "r14", "r15", "rax", "rdi", "rsi"]; - +const REGISTERS: [&str; 9] = ["r10", "r11", "r12", "r13", "r14", "rsp", "rbp", "rdp", "rdi"]; +#[derive(Debug)] pub struct FasmCodegen { register_counter: usize, - operation_queue: Vec + operation_queue: Vec, + use_queue: bool, +} + +#[derive(Debug)] +enum OperationQueue { + RegisterCounter(usize), + Instruction(String), +} + +impl Default for FasmCodegen { + fn default() -> Self { + Self::new() + } } impl FasmCodegen { pub fn new() -> Self { FasmCodegen { register_counter: 0, - operation_queue: Vec::new() + operation_queue: Vec::new(), + use_queue: false } } @@ -28,7 +42,7 @@ impl FasmCodegen { self.fasm_codegen($exprs, false) }}; } - + // Define asm_func, used for functions. let mut asm_func = String::new(); // Define asm_data, used for variables. @@ -57,28 +71,45 @@ impl FasmCodegen { match expr { // If the expression is a math expression. Expr::MathExpr(e) => { - if let Expr::MathExpr(m) = e.right.as_ref() { - let codegen = fasm_codegen!(fun: &vec![Expr::MathExpr(m.clone())]); - self.operation_queue.push(codegen); + if let Expr::MathExpr(_m) = e.right.as_ref() { + self.register_counter += 1; + + self.operation_queue.push(OperationQueue::RegisterCounter(self.register_counter)); + self.use_queue = true; + } else { + self.use_queue = false; } + let mut register_counter = Box::new(self.register_counter); + if self.use_queue { + println!("self.use_queue"); + if let Some(OperationQueue::RegisterCounter(q)) = self.operation_queue.pop() { + register_counter = Box::new(q); + } + } + dbg!(*register_counter, self.register_counter, self.use_queue); unwrap!(e.left); self.register_counter += 1; - asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[self.register_counter]).as_str()); + dbg!(*register_counter, self.register_counter, self.use_queue); + asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[*register_counter]).as_str()); unwrap!(e.right); self.register_counter += 1; - asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[self.register_counter]).as_str()); + dbg!(*register_counter, self.register_counter, self.use_queue); + asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[*register_counter]).as_str()); + self.register_counter += 1; match e.operator { // If the operator is addition. MathOperator::OP_ADD => { - asm_start.push_str(format!("\tadd {}, {}\n", REGISTERS[self.register_counter - 1], REGISTERS[self.register_counter]).as_str()); - asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[self.register_counter - 1]).as_str()); + asm_start.push_str(format!("\tadd {}, {}\n", REGISTERS[*register_counter - 1], REGISTERS[*register_counter]).as_str()); + asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[*register_counter - 1]).as_str()); + // r10 ← r10 + r11; rax ← r10; // The sum will now be stored in the %rax register. }, // If the operator is multiplication. MathOperator::OP_MULT => { - asm_start.push_str(format!("\timul {}, {}\n", REGISTERS[self.register_counter - 1], REGISTERS[self.register_counter]).as_str()); - asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[self.register_counter - 1]).as_str()); + asm_start.push_str(format!("\timul {}, {}\n", REGISTERS[*register_counter - 1], REGISTERS[*register_counter]).as_str()); + asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[*register_counter - 1]).as_str()); + // r10 ← r10 * r11; rax ← r10; // The product will now be stored in the %rax register. }, @@ -94,6 +125,7 @@ impl FasmCodegen { MathOperator::OP_SUB => { asm_start.push_str("\tsub r10, r11\n"); asm_start.push_str("\tmov rax, r10\n"); + // r10 ← r10 - r11; rax ← r10; // The difference will now be stored in the %rax register. }, @@ -116,49 +148,49 @@ impl FasmCodegen { 0 => { // First parameter. Put in %rdi. unwrap!(p); - asm_start.push_str(format!("\tmov rdi, rax\n").as_str()); + asm_start.push_str("\tmov rdi, rax\n".to_string().as_str()); // rdi ← e.params[0]; }, 1 => { // Second parameter. Put in %rsi. unwrap!(p); - asm_start.push_str(format!("\tmov rsi, rax\n").as_str()); + asm_start.push_str("\tmov rsi, rax\n".to_string().as_str()); // rsi ← e.params[1]; }, 2 => { // Third parameter. Put in %rdx. unwrap!(p); - asm_start.push_str(format!("\tmov rdx, rax\n").as_str()); + asm_start.push_str("\tmov rdx, rax\n".to_string().as_str()); // rdx ← e.params[2]; }, 3 => { // Fourth parameter. Put in %rcx. unwrap!(p); - asm_start.push_str(format!("\tmov rcx, rax\n").as_str()); + asm_start.push_str("\tmov rcx, rax\n".to_string().as_str()); // rcx ← e.params[3]; }, 4 => { // Fifth parameter. Put in %r8. unwrap!(p); - asm_start.push_str(format!("\tmov r8, rax").as_str()); + asm_start.push_str("\tmov r8, rax".to_string().as_str()); // r8 ← e.params[4]; }, 5 => { // Sixth parameter. Put in %r9. unwrap!(p); - asm_start.push_str(format!("\tmov r9, rax\n").as_str()); + asm_start.push_str("\tmov r9, rax\n".to_string().as_str()); // r9 ← e.params[5]; }, _ => { // Parameters after the sixth parameter are pushed to the stack. unwrap!(p); - asm_start.push_str(format!("\tpush rax\n").as_str()); + asm_start.push_str("\tpush rax\n".to_string().as_str()); // STACK_TOP ← e.params[(6+)]; } } @@ -206,7 +238,7 @@ impl FasmCodegen { asm_start.push_str("mov rdi, rax"); unwrap!(e.right); asm_start.push_str("mov rsi, rax"); - asm_start.push_str(format!("\tcmp rdi, rsi\n").as_str()); + asm_start.push_str("\tcmp rdi, rsi\n".to_string().as_str()); // Check what the condition is. match e.cond { COND_OP::EQ => { @@ -232,7 +264,7 @@ impl FasmCodegen { no => unsafe { // Write some data I randomly typed to your memory because don't going around playing with something that I haven't implemented yet. println!("{:?} is not. implemented.", no); - let mut ptr = 0x00 as *mut f64; + let ptr = std::ptr::null_mut::(); ::std::ptr::write(ptr, 124010240120401240.12410240124120401240); }, } diff --git a/src/codegen/fasm.rs~ b/src/codegen/fasm.rs~ deleted file mode 100644 index e69de29..0000000 diff --git a/src/codegen/mod.rs~ b/src/codegen/mod.rs~ deleted file mode 100644 index e69de29..0000000 diff --git a/src/lex/mod.rs~ b/src/lex/mod.rs~ deleted file mode 100644 index 2f5793d..0000000 --- a/src/lex/mod.rs~ +++ /dev/null @@ -1 +0,0 @@ -pub mod tok; diff --git a/src/lex/parse.rs~ b/src/lex/parse.rs~ deleted file mode 100644 index 7fade2d..0000000 --- a/src/lex/parse.rs~ +++ /dev/null @@ -1,149 +0,0 @@ -#![allow(unused)] - -use super::tok::*; - - -fn check_single_char<'a>(word: &'a str) -> Option> { - macro_rules! tok { - ($tt:expr) => { - Some(Token::new($tt, word)) - }; - }; - - let tok = match word { - ";" => tok!(Semicolon), - "=" => tok!(Equal), - "(" => tok!(LeftParen), - ")" => tok!(RightParen), - "{" => tok!(LeftBrace), - "}" => tok!(RightBrace), - "," => tok!(Comma), - "." => tok!(Dot), - "-" => tok!(Minus), - "+" => tok!(Plus), - "/" => tok!(Slash), - "*" => tok!(Star), - "%" => tok!(Percent), - "!" => tok!(Bang), - ":" => tok!(Colon), - "<" => tok!(Less), - ">" => tok!(Greater), - - _ => None - }; - - tok -} - -fn check_keyword<'a>(word: &'a str) -> Option> { - macro_rules! tok { - ($tt:expr) => { - Some(Token::new($tt, word)) - }; - }; - - let tok = match word { - "fn" => tok!(Fn), - "let" => tok!(Let), - "if" => tok!(If), - "else" => tok!(Else), - "while" => tok!(While), - "elif" => tok!(Elif), - "return" => tok!(Return), - "for" => tok!(For), - "in" => tok!(In), - "break" => tok!(Break), - "continue" => tok!(Continue), - "true" => tok!(True), - "false" => tok!(False), - - _ => None - }; - - tok -} - -fn check_two_char<'a>(word: &'a str) -> Option> { - macro_rules! tok { - ($tt:expr) => { - Some(Token::new($tt, word)) - }; - }; - - let tok = match word { - "==" => tok!(EqualEqual), - "!=" => tok!(BangEqual), - "<=" => tok!(LessEqual), - ">=" => tok!(GreaterEqual), - - _ => None - }; - - tok -} - -fn match_string_literal<'a>(word: &'a str) -> Option> { - macro_rules! tok { - ($tt:expr) => { - Some(Token::new($tt, word)) - }; - }; - - - let chars = word.chars(); - - if word.starts_with("\"") { - while let Some(char) = chars.next() { - if char == '\"' { - return tok!(String); - } - } - } - if word.starts_with("\'") { - while let Some(char) = chars.next() { - if char == '\'' { - return tok!(String); - } - } - } - - None -} - -fn match_int_literal<'a>(word: &'a str) -> Option> { - macro_rules! tok { - ($tt:expr) => { - Some(Token::new($tt, word)) - }; - }; - - let chars = word.chars(); - - while let Some(char) = chars.next() { - if char.is_digit(10) { - return tok!(Number); - } else { - return None; - } - } - - None -} - -fn match_identifier<'a>(word: &'a str) -> Option> { - macro_rules! tok { - ($tt:expr) => { - Some(Token::new($tt, word)) - }; - }; - - let chars = word.chars(); - - if chars.next().is_ascii_alphabetic() { - while let Some(char) = chars.next() { - if chars.next().is_ascii() { - - } - } - } -} diff --git a/src/lex/tok.rs b/src/lex/tok.rs index 1d4e473..f535e67 100644 --- a/src/lex/tok.rs +++ b/src/lex/tok.rs @@ -106,3 +106,51 @@ pub fn lex_str(this: &str) -> Vec<(Token, &str)> { buf } + + +impl std::fmt::Display for Token { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Semicolon => write!(f, ";"), + Equal => write!(f, "="), + LeftParen => write!(f, "("), + RightParen => write!(f, ")"), + LeftBrace => write!(f, "{{"), + RightBrace => write!(f, "}}"), + Comma => write!(f, ","), + Dot => write!(f, "."), + Minus => write!(f, "-"), + Plus => write!(f, "+"), + Slash => write!(f, "/"), + Star => write!(f, "*"), + Percent => write!(f, "%"), + Bang => write!(f, "!"), + Colon => write!(f, ":"), + Less => write!(f, "<"), + Greater => write!(f, ">"), + Pipe => write!(f, "|"), + Fnaf => write!(f, "fnaf"), + Let => write!(f, "let"), + Global => write!(f, "global"), + If => write!(f, "if"), + Else => write!(f, "else"), + While => write!(f, "while"), + Elif => write!(f, "elif"), + Return => write!(f, "return"), + For => write!(f, "for"), + In => write!(f, "in"), + Break => write!(f, "break"), + Continue => write!(f, "continue"), + EqualEqual => write!(f, "=="), + BangEqual => write!(f, "!="), + LessEqual => write!(f, "<="), + GreaterEqual => write!(f, ">="), + String => write!(f, "[string]"), + Number(n) => write!(f, "{}", n), + Identifier => write!(f, "identifier"), + True => write!(f, "true"), + False => write!(f, "false"), + Null => write!(f, "none"), + } + } +} diff --git a/src/lex/tok.rs~ b/src/lex/tok.rs~ deleted file mode 100644 index 9c1c423..0000000 --- a/src/lex/tok.rs~ +++ /dev/null @@ -1,124 +0,0 @@ -#![allow(unused)] -pub use TokenType::*; -use super::parse::*; - -#[derive(Debug)] -pub struct Token<'a> { - tt: TokenType, - word: &'a str, -} - -#[derive(Debug)] -pub enum TokenType { - EOF, - - // SINGLE CHARACTER TOKENS - Semicolon, // ; - Equal, // = - LeftParen, // ( - RightParen, // ) - LeftBrace, // { - RightBrace, // } - Comma, // , - Dot, // . - Minus, // - - Plus, // + - Slash, // / - Star, // * - Percent, // % - Bang, // ! - Colon, // : - Less, // < - Greater, // > - - // KEYWORDS - Fn, // fn - Let, // let - If, // if - Else, // else - While, // while - Elif, // elif - Return, // return - For, // for - In, // in - Break, // break - Continue, // continue - - // TWO CHARACTER TOKENS - EqualEqual, // == - BangEqual, // != - LessEqual, // <= - GreaterEqual, // >= - - // LITERALS - String, // A string literal. - Number, // An integer. - Identifier, // An identifier. - True, // true - False, // false - Null, // None - - // ERROR - Error, // A syntax error. -} - -#[derive(Debug)] -pub struct Lexer<'a> { - source: &'a str, - tokens: Vec>, - current: usize, - after: &'a str -} - -impl<'a> Lexer<'a> { - pub fn new() -> Self { - Lexer { - source: "", - tokens: Vec::new(), - current: 0, - after: "" - } - } -} - -impl<'a> std::iter::Iterator for Lexer<'a> { - -} - -impl<'a> From<&'a str> for Lexer<'a> { - fn from(value: &'a str) -> Self { - Lexer { - source: value, - tokens: Vec::new(), - current: 0, - after: value - } - } -} - -impl<'a> From<&'a std::string::String> for Lexer<'a> { - fn from(value: &'a std::string::String) -> Self { - Lexer { - source: value.as_str(), - tokens: Vec::new(), - current: 0, - after: value.as_str() - } - } -} - -impl<'a> Token<'a> { - pub fn new(tt: TokenType, word: &'a str) -> Self { - Token { - tt, - word - } - } - - pub fn empty() -> Self { - Token { - tt: EOF, - word: "" - } - } -} diff --git a/src/main.rs b/src/main.rs index b579b4e..4c19d99 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,9 @@ #![feature(associated_type_bounds)] -#![allow(warnings)] - pub mod lex; pub mod codegen; use crate::codegen::fasm::*; use crate::lex::tok::*; -use crate::parse::ast::*; + use crate::parse::parse::*; use logos::Logos; @@ -54,7 +52,7 @@ fn main() { // println!("{}", fc); let parsed = "3*10+5"; - let mut lexer = Token::lexer(parsed); + let lexer = Token::lexer(parsed); println!("\"{}\"", parsed); arrow!(" "); @@ -63,6 +61,7 @@ fn main() { let parsed = parse_math(lexer); println!("{:?}", parsed); arrow!(" "); - println!("{}", FasmCodegen::new().fasm_codegen(&vec![parsed.unwrap()], true)); + let mut code = FasmCodegen::new(); + println!("{}", code.fasm_codegen(&vec![parsed.unwrap()], true)); } diff --git a/src/main.rs~ b/src/main.rs~ deleted file mode 100644 index 748d553..0000000 --- a/src/main.rs~ +++ /dev/null @@ -1,5 +0,0 @@ -pub mod lex; - -fn main() { - println!("{:?}", lex::parse::match_identifier("goren-")); -} diff --git a/src/parse/ast.rs~ b/src/parse/ast.rs~ deleted file mode 100644 index e69de29..0000000 diff --git a/src/parse/mod.rs~ b/src/parse/mod.rs~ deleted file mode 100644 index e69de29..0000000 diff --git a/src/parse/parse.rs b/src/parse/parse.rs index 53354e6..86dcebb 100644 --- a/src/parse/parse.rs +++ b/src/parse/parse.rs @@ -27,19 +27,17 @@ pub fn parse_math(mut tokens: Lexer) -> Option { pub fn parse_global_declaration(mut tokens: Lexer) -> Option { let mut tok = None; - if unwrap!(tokens) == Let { - if unwrap!(tokens) == Identifier { - let name = tokens.slice(); + if unwrap!(tokens) == Let && unwrap!(tokens) == Identifier { + let name = tokens.slice(); - println!("{:?}", name); - if unwrap!(tokens) == Equal { - let temp_token = unwrap!(tokens); - if let Number(n) = temp_token { - tok = Some(Expr::GlobalDefinition(Rc::new(VarDefinition {name, value: n}))); - } - } - } - } + println!("{:?}", name); + if unwrap!(tokens) == Equal { + let temp_token = unwrap!(tokens); + if let Number(n) = temp_token { + tok = Some(Expr::GlobalDefinition(Rc::new(VarDefinition {name, value: n}))); + } + } + } tok } diff --git a/src/parse/parse.rs~ b/src/parse/parse.rs~ deleted file mode 100644 index e69de29..0000000