1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

if do block

This commit is contained in:
Natapat Samutpong 2022-02-17 20:44:36 +07:00
parent db773bf735
commit 63fb726e6e
3 changed files with 75 additions and 19 deletions

View file

@ -1,5 +1,6 @@
# Hycron
Programming language
Note: The syntax can still be changed, if you have an idea, feel free to make an issues about it.
# TODO
- Compliation

View file

@ -1,5 +1,11 @@
fun foo a b = a == b;
fun bar a b = { a == b };
let res = foo(34, 35);
let res = { foo(34, 35) };
/* comment */
fun foo a b = a * b;
let bar = foo(3, 3);
if bar == 9 then
do
print(bar);
print(":)");
end
else
print(":(");
end;

View file

@ -15,7 +15,10 @@ pub enum Token {
Comma,
// Keywords
Import,
Let, Fun,
If, Then, Else, End,
Do,
}
pub type Span = std::ops::Range<usize>;
@ -69,8 +72,14 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
"true" => Token::Boolean(true),
"false" => Token::Boolean(false),
"import" => Token::Import,
"let" => Token::Let,
"fun" => Token::Fun,
"if" => Token::If,
"then" => Token::Then,
"else" => Token::Else,
"end" => Token::End,
"do" => Token::Do,
_ => Token::Ident(s),
});
@ -102,6 +111,7 @@ pub enum Expr {
Unary { op: String, expr: Box<Self> },
Binary { op: String, left: Box<Self>, right: Box<Self> },
Call { name: Box<Self>, args: Vec<Self> },
Let {
name: String,
@ -112,10 +122,15 @@ pub enum Expr {
args: Vec<String>,
body: Vec<Self>,
},
Call {
name: Box<Self>,
args: Vec<Self>,
If {
cond: Box<Self>,
then: Vec<Self>,
else_: Vec<Self>,
},
Do { body: Vec<Self> },
Import(String),
}
fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
@ -216,49 +231,83 @@ fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
}).labelled("expression");
let declare = recursive(|decl| {
let decl_block = decl.clone()
.or(expr.clone())
.repeated()
.delimited_by(just(Token::Delimiter('{')), just(Token::Delimiter('}')));
let do_block = just(Token::Do)
.ignore_then(
expr.clone()
.then_ignore(just(Token::Semicolon))
.repeated())
.then_ignore(just(Token::End));
let declare_var = just(Token::Let)
.ignore_then(ident)
.then_ignore(just(Token::Assign))
.then(
decl_block.clone()
do_block.clone()
.or(decl.clone().repeated().at_most(1))
)
.then_ignore(just(Token::Semicolon))
.map(|(name, value)| Expr::Let {
name,
value,
});
}).labelled("variable");
let declare_fun = just(Token::Fun)
.ignore_then(ident)
.then(ident.repeated())
.then_ignore(just(Token::Assign))
.then(
decl_block.clone()
do_block.clone()
.or(decl.clone().repeated().at_most(1))
)
.then_ignore(just(Token::Semicolon))
.map(|((name, args), body)| Expr::Fun {
name,
args,
body,
});
}).labelled("function");
let declare_import = just(Token::Import)
.ignore_then(ident.clone())
.map(Expr::Import);
let if_cond = just(Token::If)
.ignore_then(expr.clone())
.then_ignore(just(Token::Then))
.then(
do_block.clone()
.or(decl.clone()
.repeated()
.at_most(1)
.then_ignore(just(Token::Semicolon)))
)
.then_ignore(just(Token::Else))
.then(
do_block.clone()
.or(decl.clone()
.repeated()
.at_most(1)
.then_ignore(just(Token::Semicolon)))
)
.then_ignore(just(Token::End))
.map(|((cond, then), else_)| Expr::If {
cond: Box::new(cond),
then,
else_,
}).labelled("if");
declare_var
.or(declare_fun)
.or(declare_import)
.or(if_cond)
.or(do_block.map(|body| Expr::Do { body }))
.or(expr)
});
}).labelled("declare");
declare
}
pub fn parser() -> impl Parser<Token, Vec<Expr>, Error = Simple<Token>> + Clone {
expr_parser()
.then_ignore(just(Token::Semicolon))
.repeated()
.then_ignore(end())
}