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.
9d10030c47
...
79307db4fe
|
@ -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;
|
|
|
@ -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
|
||||||
|
|
|
@ -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 :("),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue