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:
parent
db773bf735
commit
63fb726e6e
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
@ -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())
|
||||||
}
|
}
|
Loading…
Reference in a new issue