From b4e60f09e50833a8942a732449e9b913ea2eced1 Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Thu, 30 Nov 2023 12:55:41 -0500 Subject: [PATCH] Made the backend compile and be more recursive :3. --- Cargo.toml | 3 +++ src/codegen/fasm.rs | 30 ++++++++++++++++++------------ src/lex/tok.rs | 2 ++ src/parse/ast.rs | 8 ++++---- src/parse/parse.rs | 15 +++++---------- 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a40e8ca..3bca400 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,9 @@ name = "skylang" version = "0.1.0" edition = "2021" +[lib] +proc-macro = true + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index 81ebabf..31854e8 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -1,5 +1,6 @@ use crate::parse::ast::*; use std::rc::Rc; +use skylang::temp; #[macro_export] macro_rules! fasm_codegen { @@ -20,10 +21,9 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { let mut asm_data = String::new(); // Define asm_start, used for the entry point. let mut asm_start = String::new(); - macro_rules! unwrap { ($item:expr) => { - asm_start.push_str(fasm_codegen!(fun: &vec![*$item.as_ref()]).as_str()); + asm_start.push_str(fasm_codegen!(fun: &vec![$item.as_ref().clone()]).as_str()); } } @@ -36,7 +36,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { asm_start.push_str("_start:\n"); asm_data.push_str("\nsegment readable writable\n"); } - + // Iterate over expressions. for expr in exprs.iter() { // Use patern matching on `expr`. @@ -46,7 +46,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { unwrap!(e.left); asm_start.push_str(format!("\tmov r10, rax\n").as_str()); unwrap!(e.right); - asm_start.push_str(format!("\tmov r11, rax").as_str()); + asm_start.push_str(format!("\tmov r11, rax\n").as_str()); match e.operator { // If the operator is addition. MathOperator::OP_ADD => { @@ -181,31 +181,37 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { Expr::If(e) => { // Increment the temporary variable/function counter. - tmp_counter += 1; // Compare the left and right value. - - asm_start.push_str(format!("\tcmp rax, {}\n", e.left, e.right.unwrap()).as_str()); + unwrap!(e.left); + 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()); // Check what the condition is. match e.cond { COND_OP::EQ => { // If the compared values are equal to each other jump to the temporary function. - asm_start.push_str(format!("je .{}", temp(tmp_counter)).as_str()); + asm_start.push_str(format!("je .{}", temp!()).as_str()); }, COND_OP::NE => { // If the compared values are not equal to eachother jump to the temporary function. - asm_start.push_str(format!("jne .{}", temp(tmp_counter)).as_str()); + asm_start.push_str(format!("jne .{}", temp!()).as_str()); } } // Create the temporary function. - asm_func.push_str(format!(".{}:\n", temp(tmp_counter)).as_str()); + asm_func.push_str(format!(".{}:\n", temp!()).as_str()); asm_func.push_str(fasm_codegen!(fun: &e.action).as_str()); asm_func.push_str("\tret\n"); - } - _ => unsafe { + }, + Expr::Number(n) => { + asm_func.push_str(format!("\tmov rax, {}\n", n).as_str()) + }, + 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; ::std::ptr::write(ptr, 124010240120401240.12410240124120401240); }, diff --git a/src/lex/tok.rs b/src/lex/tok.rs index 073ca03..1d4e473 100644 --- a/src/lex/tok.rs +++ b/src/lex/tok.rs @@ -51,6 +51,8 @@ pub enum Token { Fnaf, // fnaf #[token("let")] Let, // let + #[token("global")] + Global, // global #[token("if")] If, // if #[token("else")] diff --git a/src/parse/ast.rs b/src/parse/ast.rs index c792afc..e3edb69 100644 --- a/src/parse/ast.rs +++ b/src/parse/ast.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Expr<'a> { MathExpr(Math<'a>), FunCall(FunCall<'a>), @@ -35,7 +35,7 @@ pub enum MathOperator { // FUNCTIONS -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FunCall<'a> { pub name: &'a str, pub params: Vec>>, @@ -81,8 +81,8 @@ pub struct ParamReference { #[derive(Debug)] pub struct IfCondition<'a> { - pub left: Expr<'a>, - pub right: Expr<'a>, + pub left: Rc>, + pub right: Rc>, pub cond: COND_OP, pub action: Vec> } diff --git a/src/parse/parse.rs b/src/parse/parse.rs index 99598e7..5869da9 100644 --- a/src/parse/parse.rs +++ b/src/parse/parse.rs @@ -34,7 +34,7 @@ pub fn parse_math(mut tokens: Lexer) -> Option { None } -pub fn parse_var_declaration(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 { @@ -44,12 +44,7 @@ pub fn parse_var_declaration(mut tokens: Lexer) -> Option { if unwrap!(tokens) == Equal { let temp_token = unwrap!(tokens); if let Number(n) = temp_token { - let value = Value::Number(n); - println!("{:?}", value); - tok = Some(Expr::VarDefinition(VarDefinition {name, value})); - } else if temp_token == Identifier { - let value = Value::Var(VarReference { name: tokens.slice() }); - tok = Some(Expr::VarDefinition(VarDefinition {name, value})); + tok = Some(Expr::GlobalDefinition(Rc::new(VarDefinition {name, value: n}))); } } } @@ -62,9 +57,9 @@ pub fn parse_value<'a>(token: &(Option>, &'a str)) -> Option) -> Option { if unwrap!(tokens) == LeftParen { let mut params = Vec::new(); while let Some(value) = parse_value!(tokens) { - params.push(value); + params.push(Rc::new(value)); } tok = Some(Expr::FunCall(FunCall {name, params: params.clone()})); }