Did some things to make it more recursive, but still doesn't compile

recursive
Goren Barak 2023-11-28 14:59:08 -05:00
parent 4d4ab24382
commit 0b4e7deda0
7 changed files with 147 additions and 19 deletions

6
justfile Normal file
View File

@ -0,0 +1,6 @@
run:
cargo run -r
test:
cargo test
build:
cargo build -r

66
src/#main.rs# Normal file
View File

@ -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()]));
}

View File

@ -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) => {

View File

@ -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() {

View File

@ -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()]));
}

View File

@ -8,15 +8,16 @@ pub enum Expr<'a> {
VarDefinition(VarDefinition<'a>),
Return(Vec<Expr<'a>>),
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<Value<'a>>,
pub right: Rc<Value<'a>>,
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 {

View File

@ -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<Token>) -> Option<Expr> {
// 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<Token>) -> Option<Expr> {
let mut tok = None;
if unwrap!(tokens) == Let {
@ -31,13 +57,13 @@ pub fn parse_var_declaration(mut tokens: Lexer<Token>) -> Option<Expr> {
tok
}
pub fn parse_value<'a>(token: (Option<Result<Token, ()>>, &'a str)) -> Option<Value<'a>> {
if let Some(Ok(tt)) = token.0 {
pub fn parse_value<'a>(token: &(Option<Result<Token, ()>>, &'a str)) -> Option<Value<'a>> {
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<Token>) -> Option<Expr> {
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<Token>) -> Option<Expr> {
tok
}
pub fn match_operator(tokens: &mut Lexer<Token>) -> Option<MathOperator> {
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
}
}