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 # Hycron
Programming language Programming language
Note: The syntax can still be changed, if you have an idea, feel free to make an issues about it.
# TODO # TODO
- Compliation - Compliation

View file

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

View file

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