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
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Expr {
|
||||
Ident(String),
|
||||
// var/fun_name
|
||||
Ident(Identifier),
|
||||
|
||||
// 4
|
||||
IntLiteral(i64),
|
||||
|
||||
// 12.5
|
||||
FloatLiteral(f64),
|
||||
|
||||
// "eepy"
|
||||
StringLiteral(String),
|
||||
|
||||
// true
|
||||
BoolLiteral(bool),
|
||||
|
||||
// 'c'
|
||||
CharLiteral(char),
|
||||
|
||||
// var x = intPlusOne(12)
|
||||
CallExpr(Call),
|
||||
|
||||
// !x
|
||||
UnaryExpr(Unary),
|
||||
|
||||
// 1 + 11
|
||||
BinaryExpr(Binary),
|
||||
|
||||
// x = 64
|
||||
AssignmentExpr(Assignment),
|
||||
|
||||
// var foo = "bar"
|
||||
VarExpr(Var),
|
||||
|
||||
// if(...) { ... } else { ... }
|
||||
Condition(Condition),
|
||||
|
||||
// fun helloWorld() { ... }
|
||||
FunctionExpr(Function),
|
||||
|
||||
Error,
|
||||
|
|
|
|||
|
|
@ -2,23 +2,21 @@ use std::{ops::Range, rc::Rc};
|
|||
|
||||
use crate::language_frontend::abstract_syntax_tree::ast::Expr;
|
||||
|
||||
/// Abstract Syntax Tree
|
||||
pub type BlockStatement = Vec<Statement>;
|
||||
// Abstract Syntax Tree
|
||||
|
||||
pub type BlockExpression = Vec<Expr>;
|
||||
|
||||
pub type Span = Range<usize>;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Statement {
|
||||
Var(Ident, Option<Type>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum BinaryOp {
|
||||
// Arithmetic
|
||||
Multiply,
|
||||
Divide,
|
||||
Add,
|
||||
Substract,
|
||||
|
||||
// Comparision
|
||||
Equals,
|
||||
NotEquals,
|
||||
Less,
|
||||
|
|
@ -26,15 +24,16 @@ pub enum BinaryOp {
|
|||
Greater,
|
||||
GreaterEquals,
|
||||
|
||||
// Logical
|
||||
And,
|
||||
Or,
|
||||
// todo: bitwise
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum UnaryOp {
|
||||
Not,
|
||||
Minus,
|
||||
Plus,
|
||||
Negate,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
|
@ -82,19 +81,20 @@ impl Value {
|
|||
// Structs
|
||||
//---------------------------------------
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Ident(pub Rc<str>);
|
||||
pub struct Identifier(pub String);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct While {
|
||||
pub condition: Expr,
|
||||
pub body: BlockStatement,
|
||||
pub condition: Box<Expr>,
|
||||
pub body: BlockExpression,
|
||||
}
|
||||
|
||||
/// Example: `if (a > 12) { ... }`
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Condition {
|
||||
pub condition: Expr,
|
||||
pub if_body: BlockStatement,
|
||||
pub else_body: Option<BlockStatement>,
|
||||
pub condition: Box<Expr>,
|
||||
pub if_body: BlockExpression,
|
||||
pub else_body: Option<BlockExpression>,
|
||||
}
|
||||
|
||||
/// Example: `x = y`
|
||||
|
|
@ -108,7 +108,7 @@ pub struct Assignment {
|
|||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Var {
|
||||
pub ty: Option<Type>,
|
||||
pub ident: String,
|
||||
pub ident: Identifier,
|
||||
pub value: Box<Expr>,
|
||||
}
|
||||
|
||||
|
|
@ -145,14 +145,17 @@ pub struct Binary {
|
|||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Function {
|
||||
pub name: String,
|
||||
pub params: Option<Vec<(Ident, Type)>>,
|
||||
pub params: Option<Vec<(Identifier, Type)>>,
|
||||
pub return_type: Option<Type>,
|
||||
pub body: Option<Vec<Expr>>,
|
||||
pub body_expr: Option<Box<Expr>>,
|
||||
pub body: Option<BlockExpression>,
|
||||
pub body_expr: Option<Box<Expr>>, // ' -> (return)'
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Call {
|
||||
pub callee: Box<Expr>,
|
||||
/// name of the function being called
|
||||
pub name: Box<Identifier>,
|
||||
|
||||
/// arguments supplied
|
||||
pub arguments: Vec<Expr>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ where
|
|||
.map(|(name, rhs)| {
|
||||
Expr::VarExpr(Var {
|
||||
ty: None,
|
||||
ident: name,
|
||||
ident: Identifier(String::from(name)),
|
||||
value: Box::new(rhs),
|
||||
})
|
||||
});
|
||||
|
|
@ -157,12 +157,12 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_unary_expr() {
|
||||
let negate_two = parse("-2");
|
||||
let negate_two = parse("!2");
|
||||
assert!(negate_two.is_ok());
|
||||
assert_eq!(
|
||||
negate_two.clone().unwrap(),
|
||||
vec![Expr::UnaryExpr(Unary {
|
||||
operator: UnaryOp::Minus,
|
||||
operator: UnaryOp::Negate,
|
||||
operand: Box::new(Expr::IntLiteral(2)),
|
||||
})]
|
||||
)
|
||||
|
|
@ -176,7 +176,7 @@ mod tests {
|
|||
var_bool.clone().unwrap(),
|
||||
vec![Expr::VarExpr(Var {
|
||||
ty: None,
|
||||
ident: String::from("isUwU"),
|
||||
ident: Identifier(String::from("isUwU")),
|
||||
value: Box::new(Expr::BoolLiteral(true))
|
||||
})]
|
||||
)
|
||||
|
|
@ -204,7 +204,7 @@ mod tests {
|
|||
var_without_expl_type.clone().unwrap(),
|
||||
vec![Expr::VarExpr(Var {
|
||||
ty: None,
|
||||
ident: String::from("x"),
|
||||
ident: Identifier(String::from("x")),
|
||||
value: Box::new(Expr::IntLiteral(12))
|
||||
})]
|
||||
)
|
||||
|
|
@ -225,6 +225,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_function_decl() {
|
||||
// test without a body or args
|
||||
let empty_fun = parse("fun helloWorld() { }");
|
||||
assert!(empty_fun.is_ok());
|
||||
assert_eq!(
|
||||
|
|
@ -238,6 +239,7 @@ mod tests {
|
|||
})]
|
||||
);
|
||||
|
||||
// tests if empty new lines within a function works
|
||||
let empty_fun_with_new_lines = parse(
|
||||
r"fun emptyMulLines() {
|
||||
|
||||
|
|
@ -255,6 +257,7 @@ mod tests {
|
|||
})]
|
||||
);
|
||||
|
||||
// tests for return expr in functions
|
||||
let fun_that_returns_int = parse(
|
||||
r"fun returnsInt(): int {
|
||||
-> 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;
|
||||
|
||||
mod language_frontend;
|
||||
mod llvm_backend;
|
||||
|
||||
use crate::{
|
||||
language_frontend::abstract_syntax_tree::parser::parse, language_frontend::lexer::tokens::Token,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue