From 05ebc02909190ed016aa4a3a4bc5c1bc8f4d6d96 Mon Sep 17 00:00:00 2001 From: LunarAkai Date: Tue, 5 Aug 2025 23:00:59 +0200 Subject: [PATCH] hmmm --- src/ast/ast.rs | 62 ++++++++++++++++ src/ast/evaluator.rs | 33 --------- src/ast/mod.rs | 30 +------- src/code_generation/compiler.rs | 25 ------- src/code_generation/mod.rs | 127 +++++++++++++++++--------------- src/main.rs | 2 +- src/parser.rs | 46 ++++++++++-- 7 files changed, 171 insertions(+), 154 deletions(-) create mode 100644 src/ast/ast.rs delete mode 100644 src/ast/evaluator.rs diff --git a/src/ast/ast.rs b/src/ast/ast.rs new file mode 100644 index 0000000..1f695cc --- /dev/null +++ b/src/ast/ast.rs @@ -0,0 +1,62 @@ +/// Abstract Syntax Tree +#[derive(Debug)] +pub enum Expression<'src> { + VariableName(&'src str), + Integer(i64), + Float(f64), + String(String), + Bool(bool), + + Negatation(Box>), + Add(Box>, Box>), + Substract(Box>, Box>), + Multiply(Box>, Box>), + Divide(Box>, Box>), + + Var { + name: &'src str, + rhs: Box>, + then: Box>, + }, + + Function { + name: &'src str, + args: Vec<&'src str>, + body: Box>, + then: Box>, + }, + + Unit +} + +impl<'src> Expression<'src> { + pub fn evaluate(&self) -> String { + match self { + Expression::VariableName(_) => todo!(), + + Expression::Integer(_) => todo!(), + + Expression::Float(_) => todo!(), + + Expression::String(_) => todo!(), + + Expression::Bool(_) => todo!(), + + Expression::Negatation(expression) => todo!(), + + Expression::Add(expression, expression1) => todo!(), + + Expression::Substract(expression, expression1) => todo!(), + + Expression::Multiply(expression, expression1) => todo!(), + + Expression::Divide(expression, expression1) => todo!(), + + Expression::Var { name, rhs, then } => todo!(), + + Expression::Function { name, args, body, then } => todo!(), + + Expression::Unit => todo!(), + } + } +} diff --git a/src/ast/evaluator.rs b/src/ast/evaluator.rs deleted file mode 100644 index 0765dd3..0000000 --- a/src/ast/evaluator.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::ast::Expression; - - - -impl<'src> Expression<'src> { - pub fn eval(&self) -> String { - match self { - Expression::VariableName(_) => todo!(), - - Expression::Integer(_) => todo!(), - - Expression::Float(_) => todo!(), - - Expression::String(_) => todo!(), - - Expression::Bool(_) => todo!(), - - Expression::Negatation(expression) => todo!(), - - Expression::Add(expression, expression1) => todo!(), - - Expression::Substract(expression, expression1) => todo!(), - - Expression::Multiply(expression, expression1) => todo!(), - - Expression::Divide(expression, expression1) => todo!(), - - Expression::Var { name, rhs, then } => todo!(), - - Expression::Function { name, args, body, then } => todo!(), - } - } -} \ No newline at end of file diff --git a/src/ast/mod.rs b/src/ast/mod.rs index c37a3b2..5bd84ba 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -2,35 +2,7 @@ use std::ops::Range; use crate::ast::op::Op; - -pub mod evaluator; pub mod op; +pub mod ast; -/// Abstract Syntax Tree -#[derive(Debug)] -pub enum Expression<'src> { - VariableName(&'src str), - Integer(i64), - Float(f64), - String(String), - Bool(bool), - - Negatation(Box>), - Add(Box>, Box>), - Substract(Box>, Box>), - Multiply(Box>, Box>), - Divide(Box>, Box>), - - Var { - name: &'src str, - rhs: Box>, - then: Box>, - }, - Function { - name: &'src str, - args: Vec<&'src str>, - body: Box>, - then: Box>, - } -} diff --git a/src/code_generation/compiler.rs b/src/code_generation/compiler.rs index c5fa592..4a24b53 100644 --- a/src/code_generation/compiler.rs +++ b/src/code_generation/compiler.rs @@ -2,28 +2,3 @@ use std::collections::HashMap; use inkwell::{builder::Builder, context::Context, module::Module, values::{FunctionValue, PointerValue}}; -use crate::code_generation::Function; - -pub struct Compiler<'a, 'ctx> { - pub context: &'ctx Context, - pub builder: &'a Builder<'ctx>, - pub module: &'a Module<'ctx>, - pub function: &'a Function, - - variables: HashMap>, - fn_value_opt: Option> -} - -impl<'a, 'ctx> Compiler<'a, 'ctx> { - /// Gets a defined function given its name. - #[inline] - fn get_function(&self, name: &str) -> Option> { - self.module.get_function(name) - } - - /// Returns the `FunctionValue` representing the function being compiled. - #[inline] - fn fn_value(&self) -> FunctionValue<'ctx> { - self.fn_value_opt.unwrap() - } -} \ No newline at end of file diff --git a/src/code_generation/mod.rs b/src/code_generation/mod.rs index 6f66e7a..6887f20 100644 --- a/src/code_generation/mod.rs +++ b/src/code_generation/mod.rs @@ -1,71 +1,76 @@ +use std::collections::HashMap; + +use inkwell::values::{BasicValueEnum, FunctionValue, PointerValue}; + +use crate::ast::ast::Expression; + pub mod compiler; // LLVM Codegen +struct CodegenContext<'ctx> { + builder: inkwell::builder::Builder<'ctx>, + module: inkwell::module::Module<'ctx>, + context: &'ctx inkwell::context::Context, + variables: HashMap>, + functions: HashMap>, +} -//-------------------------- -// Parser -//------------------------- -use std::collections::HashMap; +impl<'ctx, 'src> Expression<'src> { + fn codegen(&self, ctx: &mut CodegenContext<'ctx>) -> BasicValueEnum<'ctx> { + match self { + Expression::VariableName(name) => { + todo!() + }, -use logos::Lexer; + Expression::Integer(_) => { + todo!() + }, -use crate::tokens::Token; + Expression::Float(_) => { + todo!() + }, -/// Defines a primitive expression -#[derive(Debug)] -pub enum Expr { - Binary { - op: char, - left: Box, - right: Box, - }, - Call { - fn_name: String, - args: Vec, - }, - Conditional { - cond: Box, - consequence: Box, - alternative: Box, - }, - For { - var_name: String, - start: Box, - end: Box, - step: Option>, - body: Box, - }, - Number(f64), - Variable(String), - VarIn { - variables: Vec<(String, Option)>, - body: Box, + Expression::String(_) => { + todo!() + }, + + Expression::Bool(_) => { + todo!() + }, + + Expression::Negatation(expression) => { + todo!() + }, + + Expression::Add(expression, expression1) => { + todo!() + }, + + Expression::Substract(expression, expression1) => { + todo!() + }, + + Expression::Multiply(expression, expression1) => { + todo!() + }, + + Expression::Divide(expression, expression1) => { + todo!() + }, + + Expression::Var { name, rhs, then } => { + todo!() + }, + + Expression::Function { name, args, body, then } => { + todo!() + }, + + Expression::Unit => { + todo!() + }, + } } - -} - - -/// Defines the prototype (name and parameters) of a function -#[derive(Debug)] -pub struct Prototype { - pub name: String, - pub args: Vec, - pub is_op: bool, - pub prec: usize, -} - -/// Defines a user-defined or external function -#[derive(Debug)] -pub struct Function { - pub prototype: Prototype, - pub body: Option, - pub is_anon: bool, -} - -pub struct Parser<'a> { - tokens: Vec>, - pos: usize, - prec: &'a mut HashMap, -} +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d6c1873..f8d8eca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,5 +33,5 @@ fn main() { } }; - println!("\n[result]\n{}", ast.eval()); + println!("\n[result]\n{}", ast.evaluate()); } diff --git a/src/parser.rs b/src/parser.rs index f033150..b8dde67 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,12 +1,20 @@ use chumsky::{combinator::Or, prelude::{choice, just, recursive}, recursive, select, text::{self, ascii::ident}, IterParser, Parser}; -use crate::{ast::Expression, tokens::Token}; +use crate::{ast::ast::Expression, tokens::Token}; #[allow(clippy::let_and_return)] -pub fn parser<'src>( -) -> impl Parser<'src, &'src [Token<'src>], Expression<'src>, chumsky::extra::Err>>> -{ +pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>> { + let ident = select! { + Token::Ident(ident) => ident + }; + + let keyword = |kw: &'static str| select! { + Token::Keyword(k) if k == kw => () + }; + + let eq = just(Token::Equals); + let expr = recursive( |expr| { @@ -53,5 +61,33 @@ pub fn parser<'src>( binary_2 }); - expr + let decl = recursive(|decl| { + let r#var = keyword("var") + .ignore_then(ident.clone()) + .then_ignore(eq.clone()) + .then(decl.clone()) + .then(decl.clone()) + .map(|((name, rhs), then)| Expression::Var { + name, + rhs: Box::new(rhs), + then: Box::new(then), + }); + + let r#fun = keyword("fun") + .ignore_then(ident.clone()) + .then(ident.clone().repeated().collect()) + .then_ignore(eq.clone()) + .then(decl.clone()) + .then(decl.clone()) + .map(|(((name, args), body), then)| Expression::Function { + name, + args, + body: Box::new(body), + then: Box::new(then), + }); + + var.or(r#fun).or(expr) + }); + + decl } \ No newline at end of file