This commit is contained in:
LunarAkai 2025-08-05 23:00:59 +02:00
commit 05ebc02909
7 changed files with 171 additions and 154 deletions

62
src/ast/ast.rs Normal file
View file

@ -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<Expression<'src>>),
Add(Box<Expression<'src>>, Box<Expression<'src>>),
Substract(Box<Expression<'src>>, Box<Expression<'src>>),
Multiply(Box<Expression<'src>>, Box<Expression<'src>>),
Divide(Box<Expression<'src>>, Box<Expression<'src>>),
Var {
name: &'src str,
rhs: Box<Expression<'src>>,
then: Box<Expression<'src>>,
},
Function {
name: &'src str,
args: Vec<&'src str>,
body: Box<Expression<'src>>,
then: Box<Expression<'src>>,
},
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!(),
}
}
}

View file

@ -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!(),
}
}
}

View file

@ -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<Expression<'src>>),
Add(Box<Expression<'src>>, Box<Expression<'src>>),
Substract(Box<Expression<'src>>, Box<Expression<'src>>),
Multiply(Box<Expression<'src>>, Box<Expression<'src>>),
Divide(Box<Expression<'src>>, Box<Expression<'src>>),
Var {
name: &'src str,
rhs: Box<Expression<'src>>,
then: Box<Expression<'src>>,
},
Function {
name: &'src str,
args: Vec<&'src str>,
body: Box<Expression<'src>>,
then: Box<Expression<'src>>,
}
}

View file

@ -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<String, PointerValue<'ctx>>,
fn_value_opt: Option<FunctionValue<'ctx>>
}
impl<'a, 'ctx> Compiler<'a, 'ctx> {
/// Gets a defined function given its name.
#[inline]
fn get_function(&self, name: &str) -> Option<FunctionValue<'ctx>> {
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()
}
}

View file

@ -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<String, PointerValue<'ctx>>,
functions: HashMap<String, FunctionValue<'ctx>>,
}
//--------------------------
// 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<Expr>,
right: Box<Expr>,
},
Call {
fn_name: String,
args: Vec<Expr>,
},
Conditional {
cond: Box<Expr>,
consequence: Box<Expr>,
alternative: Box<Expr>,
},
For {
var_name: String,
start: Box<Expr>,
end: Box<Expr>,
step: Option<Box<Expr>>,
body: Box<Expr>,
},
Number(f64),
Variable(String),
VarIn {
variables: Vec<(String, Option<Expr>)>,
body: Box<Expr>,
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<String>,
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<Expr>,
pub is_anon: bool,
}
pub struct Parser<'a> {
tokens: Vec<Token<'a>>,
pos: usize,
prec: &'a mut HashMap<char, i32>,
}
}

View file

@ -33,5 +33,5 @@ fn main() {
}
};
println!("\n[result]\n{}", ast.eval());
println!("\n[result]\n{}", ast.evaluate());
}

View file

@ -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<chumsky::error::Simple<'src, Token<'src>>>>
{
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
}