hmmm
This commit is contained in:
parent
d7795e52f9
commit
05ebc02909
7 changed files with 171 additions and 154 deletions
62
src/ast/ast.rs
Normal file
62
src/ast/ast.rs
Normal 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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>>,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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>,
|
||||
}
|
||||
}
|
||||
|
|
@ -33,5 +33,5 @@ fn main() {
|
|||
}
|
||||
};
|
||||
|
||||
println!("\n[result]\n{}", ast.eval());
|
||||
println!("\n[result]\n{}", ast.evaluate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue