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

Compare commits

..

No commits in common. "9d10030c4704c5c51e2a5903c8c9c478d5747daa" and "79307db4fed6efaf26afee7c254b01840685441f" have entirely different histories.

3 changed files with 28 additions and 32 deletions

View file

@ -1,9 +1 @@
let foo = 1 + 1; let foo = 1 + 1 in 2 + foo;
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, Fun, Let, In, Fun,
If, Then, Else, End, If, Then, Else, End,
Do, Do,
} }
@ -74,6 +74,7 @@ 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,
@ -116,6 +117,7 @@ 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,
@ -139,15 +141,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 literal = filter_map(|span, token| match token {
Token::Int(i) => Ok(Expr::Int(i)),
Token::Float(f) => Ok(Expr::Float(f.parse().unwrap())),
Token::Boolean(b) => Ok(Expr::Boolean(b)),
Token::String(s) => Ok(Expr::String(s)),
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))),
}).labelled("literal");
let expr = recursive(|expr| { let expr = recursive(|expr| {
let literal = filter_map(|span, token| match token {
Token::Int(i) => Ok(Expr::Int(i)),
Token::Float(f) => Ok(Expr::Float(f.parse().unwrap())),
Token::Boolean(b) => Ok(Expr::Boolean(b)),
Token::String(s) => Ok(Expr::String(s)),
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))),
}).labelled("literal");
let args = expr.clone() let args = expr.clone()
.repeated() .repeated()
.or_not() .or_not()
@ -244,9 +246,15 @@ fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
do_block.clone() do_block.clone()
.or(decl.clone()) .or(decl.clone())
) )
.map(|(name, value)| Expr::Let { .then(just(Token::In)
.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)
@ -319,20 +327,16 @@ 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 } => out.push_str( Self::Let{ name, value, then } => {
&format!("(let\n {}\n {})", name, value.clone().to_sexpr())), let then = match *then.clone() {
Self::Fun{ name, args, body } => out.push_str( Some(v) => format!("\n (do {})", v.to_sexpr()),
&format!("(fun\n ({})\n {}\n {})", name, args.join(" "), body.to_sexpr())), None => "".to_string(),
};
Self::If { cond, then, else_ } => out.push_str( out.push_str(&format!("(let\n {}\n {}{})", name, value.clone().to_sexpr(), then))
&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: finish the rest of the Expr, I'm going to sleep, goodnight.
_ => 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::<Vec<String>>().join("\n\n")); println!("{}", ast.iter().map(|e| e.to_sexpr()).collect::<String>())
}, },
None => println!("no ast :("), None => println!("no ast :("),
}; };