From 0b4e7deda03ed873081652179f90be5e025a4130 Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Tue, 28 Nov 2023 14:59:08 -0500 Subject: [PATCH 1/7] Did some things to make it more recursive, but still doesn't compile --- justfile | 6 +++++ src/#main.rs# | 66 +++++++++++++++++++++++++++++++++++++++++++++ src/codegen/fasm.rs | 2 +- src/lex/tok.rs | 3 +-- src/main.rs | 18 +++++++++++-- src/parse/ast.rs | 24 ++++++++++------- src/parse/parse.rs | 47 ++++++++++++++++++++++++++++---- 7 files changed, 147 insertions(+), 19 deletions(-) create mode 100644 justfile create mode 100644 src/#main.rs# diff --git a/justfile b/justfile new file mode 100644 index 0000000..3bdde5c --- /dev/null +++ b/justfile @@ -0,0 +1,6 @@ +run: + cargo run -r +test: + cargo test +build: + cargo build -r diff --git a/src/#main.rs# b/src/#main.rs# new file mode 100644 index 0000000..5605800 --- /dev/null +++ b/src/#main.rs# @@ -0,0 +1,66 @@ +#![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; + +pub mod parse; + +macro_rules! arrow { + ($spaces:expr) => { + println!("{}↓", $spaces); + } +} + +fn main() { + // let fc = fasm_codegen!( + // vec![ + // Expr::VarDefinition(VarDefinition {name: "goren", value: Value::Number(10)}), + // Expr::MathExpr(Math { + // left: &Value::Var(VarReference { name: "goren"}), + // right: &Value::Number(17), + // operator: MathOperator::OP_MULT + // } + // ), + // Expr::FunDefinition(FunDefinition { + // name: "adder", contents: vec![ + // Expr::MathExpr( + // Math { + // left: &Value::Param(ParamReference {param_number: 0}), + // right: &Value::Param(ParamReference {param_number: 1}), + // operator: MathOperator::OP_ADD + // } + // ) + // ] + // }), + + // Expr::FunCall( + // FunCall { + // name: "adder", + // params: vec![Value::Var(VarReference {name: "goren"}), Value::Number(6)] + // } + // ), + + // Expr::Breakpoint + // ] + // ); + + + // println!("{}", fc); + let parsed = "30 * 60"; + + let mut lexer = Token::lexer(parsed); + + println!("\"{}\"", parsed); + arrow!(" "); + println!("{:?}", lex_str(parsed)); + arrow!(" "); + let parsed = parse_math(lexer); + println!("{:?}", parsed); + arrow!(" "); + println!("{}", fasm_codegen!(&vec![parsed.unwrap()])); +} diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index d840aca..6f2f0a2 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -4,7 +4,7 @@ use crate::parse::ast::*; macro_rules! fasm_codegen { // Macro to make calling fasm_codegen function easier. ($exprs:expr) => { - fasm_codegen(&$exprs, true) + fasm_codegen($exprs, true) }; (fun: $exprs:expr) => { diff --git a/src/lex/tok.rs b/src/lex/tok.rs index 2b45e73..073ca03 100644 --- a/src/lex/tok.rs +++ b/src/lex/tok.rs @@ -85,7 +85,7 @@ pub enum Token { String, // A string literal. #[regex("[0-9]+", |lex| lex.slice().parse().ok())] Number(u64), // An integer. - #[regex(r#"[^[0-9]^"^-^[ \t\n\f]^\.^=^(^)^{^}.^,^;]+[^"^-^=^\..^[ \t\n\f]^(^)^{^}^,^;]*"#)] + #[regex(r#"[^[0-9]^"^-^[ \t\n\f]^\.^=^(^)^{^}.^,^;^[+-/*%]]+[^"^-^=^\..^[ \t\n\f]^(^)^{^}^,^;^[+-/*%]]*"#)] Identifier, // An identifier. #[token("true")] True, // true @@ -96,7 +96,6 @@ pub enum Token { } pub fn lex_str(this: &str) -> Vec<(Token, &str)> { - println!("\"{}\"", this); let mut buf = Vec::new(); let mut lexer = Token::lexer(this); while let Some(Ok(token)) = lexer.next() { diff --git a/src/main.rs b/src/main.rs index fc7ef6c..f7c2ff1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,12 @@ use logos::Logos; pub mod parse; +macro_rules! arrow { + ($spaces:expr) => { + println!("{}↓", $spaces); + } +} + fn main() { // let fc = fasm_codegen!( // vec![ @@ -45,9 +51,17 @@ fn main() { // println!("{}", fc); - let parsed = "hello(hi)"; + let parsed = "30 * 60"; let mut lexer = Token::lexer(parsed); + + println!("\"{}\"", parsed); + arrow!(" "); println!("{:?}", lex_str(parsed)); - println!("{:?}", parse_fun_call(lexer)); + arrow!(" "); + let parsed = parse_math(lexer); + println!("{:?}", parsed); + arrow!(" "); + println!("{}", fasm_codegen!(&vec![parsed.unwrap()])); } + diff --git a/src/parse/ast.rs b/src/parse/ast.rs index 4414421..3dbb355 100644 --- a/src/parse/ast.rs +++ b/src/parse/ast.rs @@ -8,15 +8,16 @@ pub enum Expr<'a> { VarDefinition(VarDefinition<'a>), Return(Vec>), If(IfCondition<'a>), + Breakpoint } // MATH EXPRESSION -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone)] pub struct Math<'a> { - pub left: &'a Value<'a>, - pub right: &'a Value<'a>, + pub left: Rc>, + pub right: Rc>, pub operator: MathOperator } @@ -73,12 +74,7 @@ pub struct ParamReference { pub param_number: u64, } -#[derive(Debug, Copy, Clone)] -pub enum Value<'a> { - Var(VarReference<'a>), - Param(ParamReference), - Number(u64), -} +// CONDITIONS #[derive(Debug)] pub struct IfCondition<'a> { @@ -94,6 +90,16 @@ pub enum COND_OP { NE, } +// VALUE + +#[derive(Debug, Copy, Clone)] +pub enum Value<'a> { + Var(VarReference<'a>), + Param(ParamReference), + Number(u64), +} + + impl<'a> Value<'a> { pub fn unwrap(&self) -> String { match self { diff --git a/src/parse/parse.rs b/src/parse/parse.rs index d12a7f1..15f0e44 100644 --- a/src/parse/parse.rs +++ b/src/parse/parse.rs @@ -1,13 +1,39 @@ use super::ast::*; use crate::lex::tok::*; use logos::Lexer; +use std::rc::Rc; +#[macro_export] macro_rules! unwrap { ($var:expr) => { $var.next().unwrap().unwrap() } } +#[macro_export] +macro_rules! parse_value { + ($parse:expr) => { + parse_value(&($parse.next(), $parse.slice())) + } +} + +pub fn parse_math(mut tokens: Lexer) -> Option { + // Is it a Value? → Is it an operator? → Is it a value? + + if let Some(left) = parse_value!(tokens) { + if let Some(operator) = match_operator(&mut tokens) { + if let Some(right) = parse_value!(tokens) { + let left = Rc::new(left); + let right = Rc::new(right); + + return Some(Expr::MathExpr(Math {left: left, right: right, operator})) + } + } + } + + None +} + pub fn parse_var_declaration(mut tokens: Lexer) -> Option { let mut tok = None; if unwrap!(tokens) == Let { @@ -31,13 +57,13 @@ pub fn parse_var_declaration(mut tokens: Lexer) -> Option { tok } -pub fn parse_value<'a>(token: (Option>, &'a str)) -> Option> { - if let Some(Ok(tt)) = token.0 { +pub fn parse_value<'a>(token: &(Option>, &'a str)) -> Option> { + if let Some(Ok(tt)) = &token.0 { let mut value = None; if let Number(n) = tt { - value = Some(Value::Number(n)); - } else if tt == Identifier { + value = Some(Value::Number(*n)); + } else if *tt == Identifier { value = Some(Value::Var(VarReference { name: token.1 })); } @@ -58,7 +84,7 @@ pub fn parse_fun_call(mut tokens: Lexer) -> Option { let name = tokens.slice(); if unwrap!(tokens) == LeftParen { let mut params = Vec::new(); - while let Some(value) = parse_value((tokens.next(), tokens.slice())) { + while let Some(value) = parse_value!(tokens) { params.push(value); } tok = Some(Expr::FunCall(FunCall {name, params: params.clone()})); @@ -67,3 +93,14 @@ pub fn parse_fun_call(mut tokens: Lexer) -> Option { tok } + +pub fn match_operator(tokens: &mut Lexer) -> Option { + match unwrap!(tokens) { + Plus => Some(MathOperator::OP_ADD), + Minus => Some(MathOperator::OP_SUB), + Slash => Some(MathOperator::OP_DIV), + Star => Some(MathOperator::OP_MULT), + Percent => Some(MathOperator::OP_MOD), + _ => None + } +} From cb89bc0e9a26d6539111f82331996e142b94df9c Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Tue, 28 Nov 2023 18:00:31 -0500 Subject: [PATCH 2/7] Made skylang more recursive. --- src/codegen/fasm.rs | 48 +++++++++++++++++++-------- src/parse/ast.rs | 80 +++++++++++++++++++++------------------------ src/parse/parse.rs | 2 +- 3 files changed, 72 insertions(+), 58 deletions(-) diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index 6f2f0a2..05ca253 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -1,4 +1,5 @@ use crate::parse::ast::*; +use std::rc::Rc; #[macro_export] macro_rules! fasm_codegen { @@ -27,6 +28,13 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { // 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());- + } + } + + // If not_a_function, push necessary headers to the asm_start variable. if not_a_function { asm_start.push_str("format ELF64 executable 3\n"); @@ -42,8 +50,10 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { match expr { // If the expression is a math expression. Expr::MathExpr(e) => { - asm_start.push_str(format!("\tmov r10, {}\n", e.left.unwrap()).as_str()); - asm_start.push_str(format!("\tmov r11, {}\n", e.right.unwrap()).as_str()); + 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()); match e.operator { // If the operator is addition. MathOperator::OP_ADD => { @@ -91,43 +101,51 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { for (i, p) in e.params.iter().enumerate() { match i { 0 => { - // First parameter. Put in %rdi.← asm_start.push_str(format!("\tmov rdi, {}\n", p.unwrap()).as_str()); + // First parameter. Put in %rdi. + unwrap!(p); + asm_start.push_str(format!("\tmov rdi, rax\n").as_str()); // rdi ← e.params[0]; }, 1 => { // Second parameter. Put in %rsi. - asm_start.push_str(format!("\tmov rsi, {}\n", p.unwrap()).as_str()); + unwrap!(p); + asm_start.push_str(format!("\tmov rsi, rax\n").as_str()); // rsi ← e.params[1]; }, - 2 => { + 2 => { // Third parameter. Put in %rdx. - asm_start.push_str(format!("\tmov rdx, {}\n", p.unwrap()).as_str()); + unwrap!(p); + asm_start.push_str(format!("\tmov rdx, rax\n").as_str()); // rdx ← e.params[2]; }, 3 => { // Fourth parameter. Put in %rcx. - asm_start.push_str(format!("\tmov rcx, {}\n", p.unwrap()).as_str()); + unwrap!(p); + asm_start.push_str(format!("\tmov rcx, rax\n").as_str()); // rcx ← e.params[3]; }, 4 => { // Fifth parameter. Put in %r8. - asm_start.push_str(format!("\tmov r8, {}\n", p.unwrap()).as_str()); + unwrap!(p); + asm_start.push_str(format!("\tmov r8, rax").as_str()); // r8 ← e.params[4]; }, 5 => { // Sixth parameter. Put in %r9. - asm_start.push_str(format!("\tmov r9, {}\n", p.unwrap()).as_str()); + unwrap!(p); + asm_start.push_str(format!("\tmov r9, rax\n").as_str()); // r9 ← e.params[5]; }, _ => { // Parameters after the sixth parameter are pushed to the stack. - asm_start.push_str(format!("\tpush {}\n", p.unwrap()).as_str()); + unwrap!(p); + asm_start.push_str(format!("\tpush rax\n").as_str()); // STACK_TOP ← e.params[(6+)]; } } @@ -138,9 +156,10 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { }, // Define a global variable. - Expr::VarDefinition(e) => { - // Define a 64-bit variable. - asm_data.push_str(format!("\t{} dq {}", e.name, e.value.unwrap()).as_str()); + Expr::GlobalDefinition(e) => { + // Define a 64-bit global variable. + + asm_data.push_str(format!("\t{} dq {}", e.name, e.value).as_str()); }, // Breakpoint. @@ -173,7 +192,8 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { // Increment the temporary variable/function counter. tmp_counter += 1; // Compare the left and right value. - asm_start.push_str(format!("\tcmp {}, {}\n", e.left.unwrap(), e.right.unwrap()).as_str()); + + asm_start.push_str(format!("\tcmp rax, {}\n", e.left, e.right.unwrap()).as_str()); // Check what the condition is. match e.cond { COND_OP::EQ => { diff --git a/src/parse/ast.rs b/src/parse/ast.rs index 3dbb355..c792afc 100644 --- a/src/parse/ast.rs +++ b/src/parse/ast.rs @@ -4,11 +4,14 @@ use std::rc::Rc; pub enum Expr<'a> { MathExpr(Math<'a>), FunCall(FunCall<'a>), - FunDefinition(FunDefinition<'a>), - VarDefinition(VarDefinition<'a>), + FunDefinition(Rc>), + GlobalDefinition(Rc>), Return(Vec>), - If(IfCondition<'a>), - + If(Rc>), + Var(VarReference<'a>), + Param(ParamReference), + Number(u64), + Breakpoint } @@ -16,8 +19,8 @@ pub enum Expr<'a> { #[derive(Debug, Clone)] pub struct Math<'a> { - pub left: Rc>, - pub right: Rc>, + pub left: Rc>, + pub right: Rc>, pub operator: MathOperator } @@ -35,7 +38,7 @@ pub enum MathOperator { #[derive(Debug)] pub struct FunCall<'a> { pub name: &'a str, - pub params: Vec>, + pub params: Vec>>, } #[derive(Debug)] @@ -52,7 +55,7 @@ pub struct FunParamDef<'a> { #[derive(Debug)] pub struct FunParamCall<'a> { - pub value: Value<'a>, + pub value: Expr<'a>, } // VARIABLES @@ -60,7 +63,7 @@ pub struct FunParamCall<'a> { #[derive(Debug)] pub struct VarDefinition<'a> { pub name: &'a str, - pub value: Value<'a>, + pub value: u64, } @@ -78,8 +81,8 @@ pub struct ParamReference { #[derive(Debug)] pub struct IfCondition<'a> { - pub left: Value<'a>, - pub right: Value<'a>, + pub left: Expr<'a>, + pub right: Expr<'a>, pub cond: COND_OP, pub action: Vec> } @@ -91,37 +94,28 @@ pub enum COND_OP { } // VALUE - -#[derive(Debug, Copy, Clone)] -pub enum Value<'a> { - Var(VarReference<'a>), - Param(ParamReference), - Number(u64), -} - - -impl<'a> Value<'a> { - pub fn unwrap(&self) -> String { - match self { - Value::Param(e) => { - match e.param_number { - 0 => { return "rdi".to_string(); }, - 1 => { return "rsi".to_string(); }, - 2 => { return "rdx".to_string(); }, - 3 => { return "rcx".to_string(); }, - 4 => { return "r8".to_string(); }, - 5 => { return "r9".to_string(); }, - _ => { unimplemented!() } - } - }, +// impl<'a> Value<'a> { +// pub fn unwrap(&self) -> String { +// match self { +// Value::Param(e) => { +// match e.param_number { +// 0 => { return "rdi".to_string(); }, +// 1 => { return "rsi".to_string(); }, +// 2 => { return "rdx".to_string(); }, +// 3 => { return "rcx".to_string(); }, +// 4 => { return "r8".to_string(); }, +// 5 => { return "r9".to_string(); }, +// _ => { unimplemented!() } +// } +// }, - Value::Number(e) => { - return e.to_string(); - }, +// Value::Number(e) => { +// return e.to_string(); +// }, - Value::Var(e) => { - return format!("[{}]", e.name.to_string()); - }, - } - } -} +// Value::Var(e) => { +// return format!("[{}]", e.name.to_string()); +// }, +// } +// } +// } diff --git a/src/parse/parse.rs b/src/parse/parse.rs index 15f0e44..99598e7 100644 --- a/src/parse/parse.rs +++ b/src/parse/parse.rs @@ -57,7 +57,7 @@ pub fn parse_var_declaration(mut tokens: Lexer) -> Option { tok } -pub fn parse_value<'a>(token: &(Option>, &'a str)) -> Option> { +pub fn parse_value<'a>(token: &(Option>, &'a str)) -> Option> { if let Some(Ok(tt)) = &token.0 { let mut value = None; From 102df4a53134e9698cdb8f7cfc836fcddfd2519b Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Tue, 28 Nov 2023 18:21:01 -0500 Subject: [PATCH 3/7] Removed a minor syntax error. --- src/codegen/fasm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index 05ca253..7ea0224 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -30,7 +30,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { 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()]).as_str()); } } From 1016345107be2d95ba9498f26da0e216b6573839 Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Tue, 28 Nov 2023 19:16:23 -0500 Subject: [PATCH 4/7] Did some things. This reverts commit 102df4a53134e9698cdb8f7cfc836fcddfd2519b. --- src/codegen/fasm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index 7ea0224..05ca253 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -30,7 +30,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { 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()]).as_str());- } } From fb098123d5b7e72e221b27ca7e6223d25389951c Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Tue, 28 Nov 2023 19:20:05 -0500 Subject: [PATCH 5/7] Did some work :p. --- src/codegen/fasm.rs | 21 +++++---------------- src/parse/ast.rs | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index 05ca253..87a8d17 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -8,19 +8,12 @@ macro_rules! fasm_codegen { fasm_codegen($exprs, true) }; - (fun: $exprs:expr) => { + (function: $exprs:expr) => { fasm_codegen($exprs, false) } } -pub fn temp(counter: u64) -> String { - format!("tmp{:?}", counter) -} - pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { - // A counter for how many temporary variables have been created. This is used to create new ones. The new ones will be called tmp1, tmp2, etc. - let mut tmp_counter: u64 = 0; - // Define asm_func, used for functions. let mut asm_func = String::new(); // Define asm_data, used for variables. @@ -30,7 +23,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { 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()]).as_str()); } } @@ -166,7 +159,6 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { Expr::Breakpoint => { // Write the interrupt for a debugger breakpoint. asm_start.push_str("\tint3\n"); - asm_start.push_str("\txor rax, rax\n"); }, // Return something from a function. @@ -174,8 +166,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { // Do the operation that should later be returned. asm_start.push_str(fasm_codegen!(fun: &e).as_str()); // Move the return value to rbp + 8. - asm_start.push_str("mov [rbp + 8], rax"); - // 8(%rbp) ← return_value + // [rbp + 8] ← return_value }, // A function defenition. @@ -183,7 +174,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { // In x86-64 assembly, a function is defined as :. Push this to the `asm_func`. asm_func.push_str(format!("{}:\n", e.name).as_str()); // Call the function itself specifying that you are defining a function, and push the returned value to `asm_func`. - asm_func.push_str(fasm_codegen!(fun: &e.contents).as_str()); + asm_func.push_str(fasm_codegen!(function: &e.contents).as_str()); // Use the ret instruction to return from the procedure. asm_func.push_str("\tret\n"); }, @@ -213,15 +204,13 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { asm_func.push_str("\tret\n"); } - _ => unsafe { // Write some data I randomly typed to your memory because don't going around playing with something that I haven't implemented yet. let mut ptr = 0x00 as *mut f64; ::std::ptr::write(ptr, 124010240120401240.12410240124120401240); }, } - - + } diff --git a/src/parse/ast.rs b/src/parse/ast.rs index c792afc..1cc0379 100644 --- a/src/parse/ast.rs +++ b/src/parse/ast.rs @@ -1,5 +1,3 @@ -use std::rc::Rc; - #[derive(Debug)] pub enum Expr<'a> { MathExpr(Math<'a>), @@ -80,11 +78,24 @@ pub struct ParamReference { // CONDITIONS #[derive(Debug)] +<<<<<<< HEAD pub struct IfCondition<'a> { pub left: Expr<'a>, pub right: Expr<'a>, pub cond: COND_OP, pub action: Vec> +======= +pub struct IfStatement<'a> { + pub condition: Condition<'a>, + pub if_true: Vec>, +} + +#[derive(Debug)] +pub struct Condition<'a> { + pub left: Value<'a>, + pub right: Value<'a>, + pub between: COND_OP, +>>>>>>> parent of 2f942d3 (Added if statements, and made `Expr::Return` work.) } #[derive(Debug)] From db6d6a91a1299937a2063f9d92be590dd06990e1 Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Tue, 28 Nov 2023 19:23:20 -0500 Subject: [PATCH 6/7] Fix things related to git. --- src/codegen/fasm.rs | 4 ++-- src/parse/ast.rs | 15 ++------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/codegen/fasm.rs b/src/codegen/fasm.rs index 87a8d17..81ebabf 100644 --- a/src/codegen/fasm.rs +++ b/src/codegen/fasm.rs @@ -8,7 +8,7 @@ macro_rules! fasm_codegen { fasm_codegen($exprs, true) }; - (function: $exprs:expr) => { + (fun: $exprs:expr) => { fasm_codegen($exprs, false) } } @@ -174,7 +174,7 @@ pub fn fasm_codegen(exprs: &Vec, not_a_function: bool) -> String { // In x86-64 assembly, a function is defined as :. Push this to the `asm_func`. asm_func.push_str(format!("{}:\n", e.name).as_str()); // Call the function itself specifying that you are defining a function, and push the returned value to `asm_func`. - asm_func.push_str(fasm_codegen!(function: &e.contents).as_str()); + asm_func.push_str(fasm_codegen!(fun: &e.contents).as_str()); // Use the ret instruction to return from the procedure. asm_func.push_str("\tret\n"); }, diff --git a/src/parse/ast.rs b/src/parse/ast.rs index 1cc0379..c792afc 100644 --- a/src/parse/ast.rs +++ b/src/parse/ast.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + #[derive(Debug)] pub enum Expr<'a> { MathExpr(Math<'a>), @@ -78,24 +80,11 @@ pub struct ParamReference { // CONDITIONS #[derive(Debug)] -<<<<<<< HEAD pub struct IfCondition<'a> { pub left: Expr<'a>, pub right: Expr<'a>, pub cond: COND_OP, pub action: Vec> -======= -pub struct IfStatement<'a> { - pub condition: Condition<'a>, - pub if_true: Vec>, -} - -#[derive(Debug)] -pub struct Condition<'a> { - pub left: Value<'a>, - pub right: Value<'a>, - pub between: COND_OP, ->>>>>>> parent of 2f942d3 (Added if statements, and made `Expr::Return` work.) } #[derive(Debug)] From b4e60f09e50833a8942a732449e9b913ea2eced1 Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Thu, 30 Nov 2023 12:55:41 -0500 Subject: [PATCH 7/7] 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()})); }