From 0b4e7deda03ed873081652179f90be5e025a4130 Mon Sep 17 00:00:00 2001 From: Goren Barak Date: Tue, 28 Nov 2023 14:59:08 -0500 Subject: [PATCH] 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 + } +}