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

Compare commits

...

2 commits

Author SHA1 Message Date
Natapat Samutpong 9d10030c47 remove in 2022-02-18 09:06:39 +07:00
Natapat Samutpong 43ed1ac1f5 finished sexpr conversion 2022-02-18 08:41:05 +07:00
3 changed files with 32 additions and 28 deletions

View file

@ -1 +1,9 @@
let foo = 1 + 1 in 2 + foo; let foo = 1 + 1;
if foo == 2 then
do
foo + 1;
end
else
foo - 1;
end;

View file

@ -16,7 +16,7 @@ pub enum Token {
// Keywords // Keywords
Import, Import,
Let, In, Fun, Let, Fun,
If, Then, Else, End, If, Then, Else, End,
Do, Do,
} }
@ -74,7 +74,6 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
"import" => Token::Import, "import" => Token::Import,
"let" => Token::Let, "let" => Token::Let,
"in" => Token::In,
"fun" => Token::Fun, "fun" => Token::Fun,
"if" => Token::If, "if" => Token::If,
"then" => Token::Then, "then" => Token::Then,
@ -117,7 +116,6 @@ pub enum Expr {
Let { Let {
name: String, name: String,
value: Box<Self>, value: Box<Self>,
then: Box<Option<Self>>,
}, },
Fun { Fun {
name: String, name: String,
@ -141,15 +139,15 @@ fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))), _ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))),
}).labelled("identifier"); }).labelled("identifier");
let expr = recursive(|expr| { let literal = filter_map(|span, token| match token {
let literal = filter_map(|span, token| match token { Token::Int(i) => Ok(Expr::Int(i)),
Token::Int(i) => Ok(Expr::Int(i)), Token::Float(f) => Ok(Expr::Float(f.parse().unwrap())),
Token::Float(f) => Ok(Expr::Float(f.parse().unwrap())), Token::Boolean(b) => Ok(Expr::Boolean(b)),
Token::Boolean(b) => Ok(Expr::Boolean(b)), Token::String(s) => Ok(Expr::String(s)),
Token::String(s) => Ok(Expr::String(s)), _ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))),
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))), }).labelled("literal");
}).labelled("literal");
let expr = recursive(|expr| {
let args = expr.clone() let args = expr.clone()
.repeated() .repeated()
.or_not() .or_not()
@ -246,15 +244,9 @@ fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
do_block.clone() do_block.clone()
.or(decl.clone()) .or(decl.clone())
) )
.then(just(Token::In) .map(|(name, value)| Expr::Let {
.ignore_then(do_block.clone()
.or(decl.clone()))
.or_not()
)
.map(|((name, value), then)| Expr::Let {
name, name,
value: Box::new(value), value: Box::new(value),
then: Box::new(then),
}).labelled("variable"); }).labelled("variable");
let declare_fun = just(Token::Fun) let declare_fun = just(Token::Fun)
@ -327,16 +319,20 @@ impl Expr {
Self::Binary{ op, left, right } => out.push_str( Self::Binary{ op, left, right } => out.push_str(
&format!("({} {} {})", op, left.to_sexpr(), right.to_sexpr()) &format!("({} {} {})", op, left.to_sexpr(), right.to_sexpr())
), ),
Self::Call{ name, args } => out.push_str(
&format!("({} {})", name.to_sexpr(), args.iter().map(|x| x.to_sexpr()).collect::<Vec<_>>().join(" "))),
Self::Let{ name, value, then } => { Self::Let{ name, value } => out.push_str(
let then = match *then.clone() { &format!("(let\n {}\n {})", name, value.clone().to_sexpr())),
Some(v) => format!("\n (do {})", v.to_sexpr()), Self::Fun{ name, args, body } => out.push_str(
None => "".to_string(), &format!("(fun\n ({})\n {}\n {})", name, args.join(" "), body.to_sexpr())),
};
out.push_str(&format!("(let\n {}\n {}{})", name, value.clone().to_sexpr(), then))
},
// TODO: finish the rest of the Expr, I'm going to sleep, goodnight. Self::If { cond, then, else_ } => out.push_str(
&format!("(if {}\n {}\n {})", cond.to_sexpr(), then.to_sexpr(), else_.to_sexpr())),
Self::Do { body } => out.push_str(
&format!("(do {})", body.iter().map(|x| x.to_sexpr()).collect::<Vec<_>>().join(" "))),
_ => todo!(), _ => todo!(),
} }
out out

View file

@ -24,7 +24,7 @@ fn main() {
if parse_error.is_empty() { if parse_error.is_empty() {
match ast { match ast {
Some(ast) => { Some(ast) => {
println!("{}", ast.iter().map(|e| e.to_sexpr()).collect::<String>()) println!("{}", ast.iter().map(|e| e.to_sexpr()).collect::<Vec<String>>().join("\n\n"));
}, },
None => println!("no ast :("), None => println!("no ast :("),
}; };