hmm
This commit is contained in:
parent
4f8ca415aa
commit
42e6b66eb5
6 changed files with 86 additions and 26 deletions
|
|
@ -3,28 +3,43 @@ use crate::language_frontend::abstract_syntax_tree::definitions::*;
|
||||||
// Option and Result -> define in Std
|
// Option and Result -> define in Std
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
Ident(String),
|
// var/fun_name
|
||||||
|
Ident(Identifier),
|
||||||
|
|
||||||
|
// 4
|
||||||
IntLiteral(i64),
|
IntLiteral(i64),
|
||||||
|
|
||||||
|
// 12.5
|
||||||
FloatLiteral(f64),
|
FloatLiteral(f64),
|
||||||
|
|
||||||
|
// "eepy"
|
||||||
StringLiteral(String),
|
StringLiteral(String),
|
||||||
|
|
||||||
|
// true
|
||||||
BoolLiteral(bool),
|
BoolLiteral(bool),
|
||||||
|
|
||||||
|
// 'c'
|
||||||
CharLiteral(char),
|
CharLiteral(char),
|
||||||
|
|
||||||
|
// var x = intPlusOne(12)
|
||||||
CallExpr(Call),
|
CallExpr(Call),
|
||||||
|
|
||||||
|
// !x
|
||||||
UnaryExpr(Unary),
|
UnaryExpr(Unary),
|
||||||
|
|
||||||
|
// 1 + 11
|
||||||
BinaryExpr(Binary),
|
BinaryExpr(Binary),
|
||||||
|
|
||||||
|
// x = 64
|
||||||
AssignmentExpr(Assignment),
|
AssignmentExpr(Assignment),
|
||||||
|
|
||||||
|
// var foo = "bar"
|
||||||
VarExpr(Var),
|
VarExpr(Var),
|
||||||
|
|
||||||
|
// if(...) { ... } else { ... }
|
||||||
|
Condition(Condition),
|
||||||
|
|
||||||
|
// fun helloWorld() { ... }
|
||||||
FunctionExpr(Function),
|
FunctionExpr(Function),
|
||||||
|
|
||||||
Error,
|
Error,
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,21 @@ use std::{ops::Range, rc::Rc};
|
||||||
|
|
||||||
use crate::language_frontend::abstract_syntax_tree::ast::Expr;
|
use crate::language_frontend::abstract_syntax_tree::ast::Expr;
|
||||||
|
|
||||||
/// Abstract Syntax Tree
|
// Abstract Syntax Tree
|
||||||
pub type BlockStatement = Vec<Statement>;
|
|
||||||
|
pub type BlockExpression = Vec<Expr>;
|
||||||
|
|
||||||
pub type Span = Range<usize>;
|
pub type Span = Range<usize>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum Statement {
|
|
||||||
Var(Ident, Option<Type>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum BinaryOp {
|
pub enum BinaryOp {
|
||||||
|
// Arithmetic
|
||||||
Multiply,
|
Multiply,
|
||||||
Divide,
|
Divide,
|
||||||
Add,
|
Add,
|
||||||
Substract,
|
Substract,
|
||||||
|
|
||||||
|
// Comparision
|
||||||
Equals,
|
Equals,
|
||||||
NotEquals,
|
NotEquals,
|
||||||
Less,
|
Less,
|
||||||
|
|
@ -26,15 +24,16 @@ pub enum BinaryOp {
|
||||||
Greater,
|
Greater,
|
||||||
GreaterEquals,
|
GreaterEquals,
|
||||||
|
|
||||||
|
// Logical
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
|
// todo: bitwise
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum UnaryOp {
|
pub enum UnaryOp {
|
||||||
Not,
|
Not,
|
||||||
Minus,
|
Negate,
|
||||||
Plus,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
|
@ -82,19 +81,20 @@ impl Value {
|
||||||
// Structs
|
// Structs
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Ident(pub Rc<str>);
|
pub struct Identifier(pub String);
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct While {
|
pub struct While {
|
||||||
pub condition: Expr,
|
pub condition: Box<Expr>,
|
||||||
pub body: BlockStatement,
|
pub body: BlockExpression,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Example: `if (a > 12) { ... }`
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Condition {
|
pub struct Condition {
|
||||||
pub condition: Expr,
|
pub condition: Box<Expr>,
|
||||||
pub if_body: BlockStatement,
|
pub if_body: BlockExpression,
|
||||||
pub else_body: Option<BlockStatement>,
|
pub else_body: Option<BlockExpression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Example: `x = y`
|
/// Example: `x = y`
|
||||||
|
|
@ -108,7 +108,7 @@ pub struct Assignment {
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Var {
|
pub struct Var {
|
||||||
pub ty: Option<Type>,
|
pub ty: Option<Type>,
|
||||||
pub ident: String,
|
pub ident: Identifier,
|
||||||
pub value: Box<Expr>,
|
pub value: Box<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,14 +145,17 @@ pub struct Binary {
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub params: Option<Vec<(Ident, Type)>>,
|
pub params: Option<Vec<(Identifier, Type)>>,
|
||||||
pub return_type: Option<Type>,
|
pub return_type: Option<Type>,
|
||||||
pub body: Option<Vec<Expr>>,
|
pub body: Option<BlockExpression>,
|
||||||
pub body_expr: Option<Box<Expr>>,
|
pub body_expr: Option<Box<Expr>>, // ' -> (return)'
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Call {
|
pub struct Call {
|
||||||
pub callee: Box<Expr>,
|
/// name of the function being called
|
||||||
|
pub name: Box<Identifier>,
|
||||||
|
|
||||||
|
/// arguments supplied
|
||||||
pub arguments: Vec<Expr>,
|
pub arguments: Vec<Expr>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ where
|
||||||
.map(|(name, rhs)| {
|
.map(|(name, rhs)| {
|
||||||
Expr::VarExpr(Var {
|
Expr::VarExpr(Var {
|
||||||
ty: None,
|
ty: None,
|
||||||
ident: name,
|
ident: Identifier(String::from(name)),
|
||||||
value: Box::new(rhs),
|
value: Box::new(rhs),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
@ -157,12 +157,12 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unary_expr() {
|
fn test_unary_expr() {
|
||||||
let negate_two = parse("-2");
|
let negate_two = parse("!2");
|
||||||
assert!(negate_two.is_ok());
|
assert!(negate_two.is_ok());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
negate_two.clone().unwrap(),
|
negate_two.clone().unwrap(),
|
||||||
vec![Expr::UnaryExpr(Unary {
|
vec![Expr::UnaryExpr(Unary {
|
||||||
operator: UnaryOp::Minus,
|
operator: UnaryOp::Negate,
|
||||||
operand: Box::new(Expr::IntLiteral(2)),
|
operand: Box::new(Expr::IntLiteral(2)),
|
||||||
})]
|
})]
|
||||||
)
|
)
|
||||||
|
|
@ -176,7 +176,7 @@ mod tests {
|
||||||
var_bool.clone().unwrap(),
|
var_bool.clone().unwrap(),
|
||||||
vec![Expr::VarExpr(Var {
|
vec![Expr::VarExpr(Var {
|
||||||
ty: None,
|
ty: None,
|
||||||
ident: String::from("isUwU"),
|
ident: Identifier(String::from("isUwU")),
|
||||||
value: Box::new(Expr::BoolLiteral(true))
|
value: Box::new(Expr::BoolLiteral(true))
|
||||||
})]
|
})]
|
||||||
)
|
)
|
||||||
|
|
@ -204,7 +204,7 @@ mod tests {
|
||||||
var_without_expl_type.clone().unwrap(),
|
var_without_expl_type.clone().unwrap(),
|
||||||
vec![Expr::VarExpr(Var {
|
vec![Expr::VarExpr(Var {
|
||||||
ty: None,
|
ty: None,
|
||||||
ident: String::from("x"),
|
ident: Identifier(String::from("x")),
|
||||||
value: Box::new(Expr::IntLiteral(12))
|
value: Box::new(Expr::IntLiteral(12))
|
||||||
})]
|
})]
|
||||||
)
|
)
|
||||||
|
|
@ -225,6 +225,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_function_decl() {
|
fn test_function_decl() {
|
||||||
|
// test without a body or args
|
||||||
let empty_fun = parse("fun helloWorld() { }");
|
let empty_fun = parse("fun helloWorld() { }");
|
||||||
assert!(empty_fun.is_ok());
|
assert!(empty_fun.is_ok());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
@ -238,6 +239,7 @@ mod tests {
|
||||||
})]
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// tests if empty new lines within a function works
|
||||||
let empty_fun_with_new_lines = parse(
|
let empty_fun_with_new_lines = parse(
|
||||||
r"fun emptyMulLines() {
|
r"fun emptyMulLines() {
|
||||||
|
|
||||||
|
|
@ -255,6 +257,7 @@ mod tests {
|
||||||
})]
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// tests for return expr in functions
|
||||||
let fun_that_returns_int = parse(
|
let fun_that_returns_int = parse(
|
||||||
r"fun returnsInt(): int {
|
r"fun returnsInt(): int {
|
||||||
-> 12
|
-> 12
|
||||||
|
|
|
||||||
37
src/llvm_backend/llvm.rs
Normal file
37
src/llvm_backend/llvm.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
use chumsky::prelude::todo;
|
||||||
|
use inkwell::{
|
||||||
|
OptimizationLevel,
|
||||||
|
builder::{self, Builder},
|
||||||
|
context::Context,
|
||||||
|
execution_engine::ExecutionEngine,
|
||||||
|
module::Module,
|
||||||
|
types::BasicTypeEnum,
|
||||||
|
values::{BasicValueEnum, FunctionValue},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::language_frontend::abstract_syntax_tree::{
|
||||||
|
ast::Expr,
|
||||||
|
definitions::{Function, Type},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct CodeGen<'ctx> {
|
||||||
|
pub(crate) context: &'ctx Context,
|
||||||
|
pub(crate) module: Module<'ctx>,
|
||||||
|
pub(crate) builder: Builder<'ctx>,
|
||||||
|
pub(crate) exec_engine: ExecutionEngine<'ctx>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> CodeGen<'ctx> {
|
||||||
|
pub fn new(context: &'ctx Context, module_name: &str, opt_level: OptimizationLevel) -> Self {
|
||||||
|
let module = context.create_module(module_name);
|
||||||
|
let exec_engine = module.create_jit_execution_engine(opt_level).unwrap();
|
||||||
|
let builder = context.create_builder();
|
||||||
|
|
||||||
|
CodeGen {
|
||||||
|
context,
|
||||||
|
module,
|
||||||
|
builder,
|
||||||
|
exec_engine,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/llvm_backend/mod.rs
Normal file
1
src/llvm_backend/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod llvm;
|
||||||
|
|
@ -3,6 +3,7 @@ use chumsky::input::{Input, Stream};
|
||||||
use logos::Logos;
|
use logos::Logos;
|
||||||
|
|
||||||
mod language_frontend;
|
mod language_frontend;
|
||||||
|
mod llvm_backend;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
language_frontend::abstract_syntax_tree::parser::parse, language_frontend::lexer::tokens::Token,
|
language_frontend::abstract_syntax_tree::parser::parse, language_frontend::lexer::tokens::Token,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue