idk
This commit is contained in:
parent
a4b7b56d67
commit
79975ffcba
4 changed files with 102 additions and 30 deletions
|
|
@ -148,7 +148,7 @@ pub struct Function {
|
||||||
pub params: Option<Vec<(String, Type)>>,
|
pub params: Option<Vec<(String, Type)>>,
|
||||||
pub return_type: Option<Type>,
|
pub return_type: Option<Type>,
|
||||||
pub body: Option<BlockExpression>,
|
pub body: Option<BlockExpression>,
|
||||||
pub body_expr: Option<Box<Expr>>, // ' -> (return)'
|
pub return_expr: Box<Option<Expr>>, // ' -> (return)'
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,52 @@
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
pub mod definitions;
|
pub mod definitions;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! token {
|
||||||
|
(var) => {
|
||||||
|
just(Token::Var)
|
||||||
|
};
|
||||||
|
(=) => {
|
||||||
|
just(Token::Assign)
|
||||||
|
};
|
||||||
|
(if) => {
|
||||||
|
just(Token::If)
|
||||||
|
};
|
||||||
|
(else) => {
|
||||||
|
just(Token::Else)
|
||||||
|
};
|
||||||
|
(->) => {
|
||||||
|
just(Token::Return)
|
||||||
|
};
|
||||||
|
(:) => {
|
||||||
|
just(Token::Colon)
|
||||||
|
};
|
||||||
|
(,) => {
|
||||||
|
just(Token::Comma)
|
||||||
|
};
|
||||||
|
(*) => {
|
||||||
|
just(Token::Multiply)
|
||||||
|
};
|
||||||
|
(/) => {
|
||||||
|
just(Token::Divide)
|
||||||
|
};
|
||||||
|
(+) => {
|
||||||
|
just(Token::Add)
|
||||||
|
};
|
||||||
|
(-) => {
|
||||||
|
just(Token::Substract)
|
||||||
|
};
|
||||||
|
(lp) => {
|
||||||
|
just(Token::LParen)
|
||||||
|
};
|
||||||
|
(rp) => {
|
||||||
|
just(Token::RParen)
|
||||||
|
};
|
||||||
|
(lbrace) => {
|
||||||
|
just(Token::LBrace)
|
||||||
|
};
|
||||||
|
(rbrace) => {
|
||||||
|
just(Token::RBrace)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use chumsky::{
|
use chumsky::{
|
||||||
Boxed, ConfigIterParser, IterParser, ParseResult, Parser,
|
Boxed, ConfigIterParser, IterParser, ParseResult, Parser,
|
||||||
combinator::Or,
|
combinator::Or,
|
||||||
|
container::Seq,
|
||||||
error::{Rich, Simple},
|
error::{Rich, Simple},
|
||||||
extra,
|
extra,
|
||||||
input::{Input, Stream, ValueInput},
|
input::{Input, Stream, ValueInput},
|
||||||
|
|
@ -14,11 +15,15 @@ use chumsky::{
|
||||||
newline, whitespace,
|
newline, whitespace,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use inkwell::Either;
|
||||||
use logos::{Logos, source};
|
use logos::{Logos, source};
|
||||||
|
|
||||||
use crate::language_frontend::{
|
use crate::{
|
||||||
|
language_frontend::{
|
||||||
abstract_syntax_tree::{ast::Expr, definitions::*},
|
abstract_syntax_tree::{ast::Expr, definitions::*},
|
||||||
lexer::tokens::Token,
|
lexer::tokens::Token,
|
||||||
|
},
|
||||||
|
token,
|
||||||
};
|
};
|
||||||
|
|
||||||
// goal of parsing is to construct an abstract syntax tree
|
// goal of parsing is to construct an abstract syntax tree
|
||||||
|
|
@ -50,15 +55,13 @@ where
|
||||||
Token::StringLiteral(s) => Expr::StringLiteral(s),
|
Token::StringLiteral(s) => Expr::StringLiteral(s),
|
||||||
}
|
}
|
||||||
.labelled("value")
|
.labelled("value")
|
||||||
.or(expr
|
.or(expr.clone().delimited_by(token!(lp), token!(rp)));
|
||||||
.clone()
|
|
||||||
.delimited_by(just(Token::LParen), just(Token::RParen)));
|
|
||||||
|
|
||||||
// Product
|
// Product
|
||||||
let mul_div = atom.clone().foldl(
|
let mul_div = atom.clone().foldl(
|
||||||
choice((
|
choice((
|
||||||
just(Token::Multiply).to(BinaryOp::Multiply),
|
token!(*).to(BinaryOp::Multiply),
|
||||||
just(Token::Divide).to(BinaryOp::Divide),
|
token!(/).to(BinaryOp::Divide),
|
||||||
))
|
))
|
||||||
.then(atom)
|
.then(atom)
|
||||||
.then_ignore(just(Token::NewLine).or_not())
|
.then_ignore(just(Token::NewLine).or_not())
|
||||||
|
|
@ -75,8 +78,8 @@ where
|
||||||
// Sum
|
// Sum
|
||||||
let add_sub = mul_div.clone().foldl(
|
let add_sub = mul_div.clone().foldl(
|
||||||
choice((
|
choice((
|
||||||
just(Token::Add).to(BinaryOp::Add),
|
token!(+).to(BinaryOp::Add),
|
||||||
just(Token::Substract).to(BinaryOp::Substract),
|
token!(-).to(BinaryOp::Substract),
|
||||||
))
|
))
|
||||||
.then(mul_div)
|
.then(mul_div)
|
||||||
.then_ignore(just(Token::NewLine).or_not())
|
.then_ignore(just(Token::NewLine).or_not())
|
||||||
|
|
@ -91,7 +94,7 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
let assign_expr = ident
|
let assign_expr = ident
|
||||||
.then_ignore(just(Token::Assign))
|
.then_ignore(token!(=))
|
||||||
.then(expr.clone())
|
.then(expr.clone())
|
||||||
.map(|(name, value)| {
|
.map(|(name, value)| {
|
||||||
Expr::AssignmentExpr(Assignment {
|
Expr::AssignmentExpr(Assignment {
|
||||||
|
|
@ -104,9 +107,9 @@ where
|
||||||
});
|
});
|
||||||
|
|
||||||
let decl = recursive(|decl| {
|
let decl = recursive(|decl| {
|
||||||
let var = just(Token::Var)
|
let var = token!(var)
|
||||||
.ignore_then(ident)
|
.ignore_then(ident)
|
||||||
.then_ignore(just(Token::Assign))
|
.then_ignore(token!(=))
|
||||||
.then(expr.clone())
|
.then(expr.clone())
|
||||||
.then_ignore(just(Token::NewLine).or_not())
|
.then_ignore(just(Token::NewLine).or_not())
|
||||||
.map(|(name, rhs)| {
|
.map(|(name, rhs)| {
|
||||||
|
|
@ -124,11 +127,9 @@ where
|
||||||
just(Token::StringType).to(Type::String),
|
just(Token::StringType).to(Type::String),
|
||||||
));
|
));
|
||||||
|
|
||||||
let return_type_parser = just(Token::Colon).ignore_then(type_parser.clone()).or_not();
|
let return_type_parser = token!(:).ignore_then(type_parser.clone()).or_not();
|
||||||
|
|
||||||
let return_expr = just(Token::Return)
|
let return_expr = token!(->).ignore_then(expr.clone()).map(|expr| expr);
|
||||||
.ignore_then(expr.clone())
|
|
||||||
.map(|expr| (expr));
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
// Function Parser
|
// Function Parser
|
||||||
|
|
@ -138,33 +139,33 @@ where
|
||||||
.then(
|
.then(
|
||||||
// arguments
|
// arguments
|
||||||
ident
|
ident
|
||||||
.then_ignore(just(Token::Colon))
|
.then_ignore(token!(:))
|
||||||
.then(type_parser.clone())
|
.then(type_parser.clone())
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(token!(,))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.delimited_by(just(Token::LParen), just(Token::RParen))
|
.delimited_by(token!(lp), token!(rp))
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.then(return_type_parser.clone()) // return type
|
.then(return_type_parser.clone()) // return type
|
||||||
.then_ignore(just(Token::LBrace)) // {
|
.then_ignore(token!(lbrace)) // {
|
||||||
.then_ignore(just(Token::NewLine).repeated().or_not())
|
.then_ignore(just(Token::NewLine).repeated().or_not())
|
||||||
.then_ignore(return_expr.or_not())
|
|
||||||
.then(
|
.then(
|
||||||
expr.clone()
|
expr.clone()
|
||||||
.then_ignore(just(Token::NewLine))
|
.then_ignore(just(Token::NewLine))
|
||||||
.repeated()
|
.repeated()
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<Expr>>()
|
||||||
|
.then(return_expr.or_not()),
|
||||||
)
|
)
|
||||||
.then_ignore(just(Token::NewLine).repeated().or_not())
|
.then_ignore(just(Token::NewLine).repeated().or_not())
|
||||||
.then_ignore(just(Token::RBrace)) // }
|
.then_ignore(token!(rbrace)) // }
|
||||||
.map(|(((name, params), return_ty), stmts)| {
|
.map(|(((name, params), return_ty), (stmts, return_value))| {
|
||||||
Expr::FunctionExpr(Function {
|
Expr::FunctionExpr(Function {
|
||||||
name: name,
|
name: name,
|
||||||
params,
|
params,
|
||||||
return_type: return_ty,
|
return_type: return_ty,
|
||||||
body: Some(stmts),
|
body: Some(stmts),
|
||||||
body_expr: None,
|
return_expr: Box::new(return_value),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -261,7 +262,7 @@ mod tests {
|
||||||
params: Some([].to_vec()),
|
params: Some([].to_vec()),
|
||||||
return_type: None,
|
return_type: None,
|
||||||
body: Some([].to_vec()),
|
body: Some([].to_vec()),
|
||||||
body_expr: None,
|
return_expr: Box::new(None),
|
||||||
})]
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -279,7 +280,7 @@ mod tests {
|
||||||
params: Some([].to_vec()),
|
params: Some([].to_vec()),
|
||||||
return_type: None,
|
return_type: None,
|
||||||
body: Some([].to_vec()),
|
body: Some([].to_vec()),
|
||||||
body_expr: None,
|
return_expr: Box::new(None),
|
||||||
})]
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -292,12 +293,32 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
fun_that_returns_int.clone().unwrap(),
|
fun_that_returns_int.clone().unwrap(),
|
||||||
|
vec![Expr::FunctionExpr(Function {
|
||||||
|
name: String::from("returnsInt"),
|
||||||
|
params: Some([].to_vec()),
|
||||||
|
return_type: Some(Type::Integer),
|
||||||
|
body: Some([].to_vec()),
|
||||||
|
return_expr: Box::new(Some(Expr::IntLiteral(12))),
|
||||||
|
})]
|
||||||
|
);
|
||||||
|
|
||||||
|
// tests for return expr with previous statements in functions
|
||||||
|
let fun_multi_line_return = parse(
|
||||||
|
r"fun returnsInt(): int {
|
||||||
|
var x = 12
|
||||||
|
x = x + 1
|
||||||
|
-> x
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
fun_multi_line_return.clone().unwrap(),
|
||||||
vec![Expr::FunctionExpr(Function {
|
vec![Expr::FunctionExpr(Function {
|
||||||
name: String::from("returnsInt"),
|
name: String::from("returnsInt"),
|
||||||
params: Some([].to_vec()),
|
params: Some([].to_vec()),
|
||||||
return_type: Some(Type::Integer),
|
return_type: Some(Type::Integer),
|
||||||
body: Some(vec![Expr::IntLiteral(12)]),
|
body: Some(vec![Expr::IntLiteral(12)]),
|
||||||
body_expr: Some(Box::new(Expr::ReturnExpr)),
|
return_expr: Box::new(Some(Expr::ReturnExpr)),
|
||||||
})]
|
})]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,4 +34,6 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
exec_engine,
|
exec_engine,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_expr(&mut self, expr: &Expr) {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue