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 return_type: Option<Type>,
|
||||
pub body: Option<BlockExpression>,
|
||||
pub body_expr: Option<Box<Expr>>, // ' -> (return)'
|
||||
pub return_expr: Box<Option<Expr>>, // ' -> (return)'
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,52 @@
|
|||
pub mod ast;
|
||||
pub mod definitions;
|
||||
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::{
|
||||
Boxed, ConfigIterParser, IterParser, ParseResult, Parser,
|
||||
combinator::Or,
|
||||
container::Seq,
|
||||
error::{Rich, Simple},
|
||||
extra,
|
||||
input::{Input, Stream, ValueInput},
|
||||
|
|
@ -14,11 +15,15 @@ use chumsky::{
|
|||
newline, whitespace,
|
||||
},
|
||||
};
|
||||
use inkwell::Either;
|
||||
use logos::{Logos, source};
|
||||
|
||||
use crate::language_frontend::{
|
||||
abstract_syntax_tree::{ast::Expr, definitions::*},
|
||||
lexer::tokens::Token,
|
||||
use crate::{
|
||||
language_frontend::{
|
||||
abstract_syntax_tree::{ast::Expr, definitions::*},
|
||||
lexer::tokens::Token,
|
||||
},
|
||||
token,
|
||||
};
|
||||
|
||||
// goal of parsing is to construct an abstract syntax tree
|
||||
|
|
@ -50,15 +55,13 @@ where
|
|||
Token::StringLiteral(s) => Expr::StringLiteral(s),
|
||||
}
|
||||
.labelled("value")
|
||||
.or(expr
|
||||
.clone()
|
||||
.delimited_by(just(Token::LParen), just(Token::RParen)));
|
||||
.or(expr.clone().delimited_by(token!(lp), token!(rp)));
|
||||
|
||||
// Product
|
||||
let mul_div = atom.clone().foldl(
|
||||
choice((
|
||||
just(Token::Multiply).to(BinaryOp::Multiply),
|
||||
just(Token::Divide).to(BinaryOp::Divide),
|
||||
token!(*).to(BinaryOp::Multiply),
|
||||
token!(/).to(BinaryOp::Divide),
|
||||
))
|
||||
.then(atom)
|
||||
.then_ignore(just(Token::NewLine).or_not())
|
||||
|
|
@ -75,8 +78,8 @@ where
|
|||
// Sum
|
||||
let add_sub = mul_div.clone().foldl(
|
||||
choice((
|
||||
just(Token::Add).to(BinaryOp::Add),
|
||||
just(Token::Substract).to(BinaryOp::Substract),
|
||||
token!(+).to(BinaryOp::Add),
|
||||
token!(-).to(BinaryOp::Substract),
|
||||
))
|
||||
.then(mul_div)
|
||||
.then_ignore(just(Token::NewLine).or_not())
|
||||
|
|
@ -91,7 +94,7 @@ where
|
|||
);
|
||||
|
||||
let assign_expr = ident
|
||||
.then_ignore(just(Token::Assign))
|
||||
.then_ignore(token!(=))
|
||||
.then(expr.clone())
|
||||
.map(|(name, value)| {
|
||||
Expr::AssignmentExpr(Assignment {
|
||||
|
|
@ -104,9 +107,9 @@ where
|
|||
});
|
||||
|
||||
let decl = recursive(|decl| {
|
||||
let var = just(Token::Var)
|
||||
let var = token!(var)
|
||||
.ignore_then(ident)
|
||||
.then_ignore(just(Token::Assign))
|
||||
.then_ignore(token!(=))
|
||||
.then(expr.clone())
|
||||
.then_ignore(just(Token::NewLine).or_not())
|
||||
.map(|(name, rhs)| {
|
||||
|
|
@ -124,11 +127,9 @@ where
|
|||
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)
|
||||
.ignore_then(expr.clone())
|
||||
.map(|expr| (expr));
|
||||
let return_expr = token!(->).ignore_then(expr.clone()).map(|expr| expr);
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// Function Parser
|
||||
|
|
@ -138,33 +139,33 @@ where
|
|||
.then(
|
||||
// arguments
|
||||
ident
|
||||
.then_ignore(just(Token::Colon))
|
||||
.then_ignore(token!(:))
|
||||
.then(type_parser.clone())
|
||||
.separated_by(just(Token::Comma))
|
||||
.separated_by(token!(,))
|
||||
.allow_trailing()
|
||||
.collect::<Vec<_>>()
|
||||
.delimited_by(just(Token::LParen), just(Token::RParen))
|
||||
.delimited_by(token!(lp), token!(rp))
|
||||
.or_not(),
|
||||
)
|
||||
.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(return_expr.or_not())
|
||||
.then(
|
||||
expr.clone()
|
||||
.then_ignore(just(Token::NewLine))
|
||||
.repeated()
|
||||
.collect::<Vec<_>>(),
|
||||
.collect::<Vec<Expr>>()
|
||||
.then(return_expr.or_not()),
|
||||
)
|
||||
.then_ignore(just(Token::NewLine).repeated().or_not())
|
||||
.then_ignore(just(Token::RBrace)) // }
|
||||
.map(|(((name, params), return_ty), stmts)| {
|
||||
.then_ignore(token!(rbrace)) // }
|
||||
.map(|(((name, params), return_ty), (stmts, return_value))| {
|
||||
Expr::FunctionExpr(Function {
|
||||
name: name,
|
||||
params,
|
||||
return_type: return_ty,
|
||||
body: Some(stmts),
|
||||
body_expr: None,
|
||||
return_expr: Box::new(return_value),
|
||||
})
|
||||
});
|
||||
|
||||
|
|
@ -261,7 +262,7 @@ mod tests {
|
|||
params: Some([].to_vec()),
|
||||
return_type: None,
|
||||
body: Some([].to_vec()),
|
||||
body_expr: None,
|
||||
return_expr: Box::new(None),
|
||||
})]
|
||||
);
|
||||
|
||||
|
|
@ -279,7 +280,7 @@ mod tests {
|
|||
params: Some([].to_vec()),
|
||||
return_type: None,
|
||||
body: Some([].to_vec()),
|
||||
body_expr: None,
|
||||
return_expr: Box::new(None),
|
||||
})]
|
||||
);
|
||||
|
||||
|
|
@ -292,12 +293,32 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
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 {
|
||||
name: String::from("returnsInt"),
|
||||
params: Some([].to_vec()),
|
||||
return_type: Some(Type::Integer),
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_expr(&mut self, expr: &Expr) {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue