hmm
This commit is contained in:
parent
0c30f0022d
commit
d7795e52f9
10 changed files with 276 additions and 31 deletions
|
|
@ -1,18 +1,33 @@
|
|||
use crate::ast::Expression;
|
||||
|
||||
|
||||
impl Expression {
|
||||
pub fn eval(&self) -> isize {
|
||||
|
||||
impl<'src> Expression<'src> {
|
||||
pub fn eval(&self) -> String {
|
||||
match self {
|
||||
Expression::Integer(n) => *n,
|
||||
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::Negate(rhs) => -rhs.eval(),
|
||||
|
||||
Expression::Add(lhs, rhs) => lhs.eval() + rhs.eval(),
|
||||
Expression::Substract(lhs, rhs) => lhs.eval() - rhs.eval(),
|
||||
Expression::Multiply(lhs, rhs) => lhs.eval() * rhs.eval(),
|
||||
Expression::Divide(lhs, rhs) => lhs.eval() / rhs.eval(),
|
||||
Expression::Function { name, args, body, then } => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,36 @@
|
|||
pub mod evaluator;
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::ast::op::Op;
|
||||
|
||||
|
||||
pub mod evaluator;
|
||||
pub mod op;
|
||||
|
||||
|
||||
/// Abstract Syntax Tree
|
||||
#[derive(Debug)]
|
||||
pub enum Expression {
|
||||
Integer(isize),
|
||||
Negate(Box<Expression>),
|
||||
// Binary operators,
|
||||
Add(Box<Expression>, Box<Expression>),
|
||||
Substract(Box<Expression>, Box<Expression>),
|
||||
Multiply(Box<Expression>, Box<Expression>),
|
||||
Divide(Box<Expression>, Box<Expression>),
|
||||
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>>,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
19
src/ast/op.rs
Normal file
19
src/ast/op.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum Op {
|
||||
Add,
|
||||
Subtract,
|
||||
Multiply,
|
||||
Divide,
|
||||
}
|
||||
|
||||
impl Op {
|
||||
pub fn eval(&self) -> String {
|
||||
let text: &str = match self {
|
||||
Op::Add => "+",
|
||||
Op::Subtract => "-",
|
||||
Op::Multiply => "*",
|
||||
Op::Divide => "/",
|
||||
};
|
||||
text.to_string()
|
||||
}
|
||||
}
|
||||
29
src/code_generation/compiler.rs
Normal file
29
src/code_generation/compiler.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
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()
|
||||
}
|
||||
}
|
||||
71
src/code_generation/mod.rs
Normal file
71
src/code_generation/mod.rs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
pub mod compiler;
|
||||
|
||||
// LLVM Codegen
|
||||
|
||||
|
||||
//--------------------------
|
||||
// Parser
|
||||
//-------------------------
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use logos::Lexer;
|
||||
|
||||
use crate::tokens::Token;
|
||||
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// 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>,
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ use crate::{parser::parser, tokens::Token};
|
|||
mod tokens;
|
||||
mod ast;
|
||||
mod parser;
|
||||
mod code_generation;
|
||||
|
||||
fn main() {
|
||||
let lexer = Token::lexer("(1 + 1) * 3");
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
use chumsky::{prelude::{just, recursive}, recursive, select, IterParser, Parser};
|
||||
use chumsky::{combinator::Or, prelude::{choice, just, recursive}, recursive, select, text::{self, ascii::ident}, IterParser, Parser};
|
||||
|
||||
use crate::{ast::Expression, tokens::Token};
|
||||
|
||||
|
||||
#[allow(clippy::let_and_return)]
|
||||
/* ANCHOR: parser */
|
||||
pub fn parser<'src>(
|
||||
) -> impl Parser<'src, &'src [Token<'src>], Expression, chumsky::extra::Err<chumsky::error::Simple<'src, Token<'src>>>>
|
||||
) -> impl Parser<'src, &'src [Token<'src>], Expression<'src>, chumsky::extra::Err<chumsky::error::Simple<'src, Token<'src>>>>
|
||||
{
|
||||
recursive(
|
||||
|p|
|
||||
let expr = recursive(
|
||||
|expr|
|
||||
{
|
||||
let atom = {
|
||||
let parenthesized = p
|
||||
let parenthesized = expr
|
||||
.clone()
|
||||
.delimited_by(just(Token::ParenBegin), just(Token::ParenEnd));
|
||||
|
||||
|
|
@ -25,7 +24,7 @@ pub fn parser<'src>(
|
|||
|
||||
let unary = just(Token::Substract)
|
||||
.repeated()
|
||||
.foldr(atom, |_op, rhs| Expression::Negate(Box::new(rhs)));
|
||||
.foldr(atom, |_op, rhs| Expression::Negatation(Box::new(rhs)));
|
||||
|
||||
let binary_1 = unary.clone().foldl(
|
||||
just(Token::Multiply)
|
||||
|
|
@ -52,5 +51,7 @@ pub fn parser<'src>(
|
|||
);
|
||||
|
||||
binary_2
|
||||
})
|
||||
});
|
||||
|
||||
expr
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ use logos::{Lexer, Logos};
|
|||
|
||||
#[derive(Logos, Debug, Clone, PartialEq)]
|
||||
#[logos(skip r"[ \t\r\n\f]+")] // Skips whitespace
|
||||
pub enum Token<'source> {
|
||||
pub enum Token<'src> {
|
||||
#[token("false", |_| false)]
|
||||
#[token("true", |_| true)]
|
||||
Bool(bool),
|
||||
|
|
@ -37,11 +37,11 @@ pub enum Token<'source> {
|
|||
#[token("}")]
|
||||
BraceEnd,
|
||||
|
||||
#[regex("[0-9]+", |lex| lex.slice().parse::<isize>().unwrap())]
|
||||
Integer(isize),
|
||||
#[regex("[0-9]+", |lex| lex.slice().parse::<i64>().unwrap())]
|
||||
Integer(i64),
|
||||
|
||||
#[regex(r"[_a-zA-Z][_0-9a-zA-Z]*")]
|
||||
Ident(&'source str),
|
||||
Ident(&'src str),
|
||||
|
||||
#[regex(r#""([^"\\\x00-\x1F]|\\(["\\bnfrt/]|u[a-fA-F0-9]{4}))*""#, |lex| lex.slice().to_owned())]
|
||||
String(String),
|
||||
|
|
@ -51,7 +51,7 @@ pub enum Token<'source> {
|
|||
#[token("var")]
|
||||
#[token("if")]
|
||||
#[token("else")]
|
||||
Keyword(&'source str),
|
||||
Keyword(&'src str),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue