parse trainride as well

This commit is contained in:
2021-10-31 20:49:46 +01:00
parent 52e8210e09
commit 421eefb494

View File

@@ -17,6 +17,7 @@ enum Token {
BranchIf, BranchIf,
Defer, Defer,
As, As,
Select,
Ident(String), Ident(String),
Str(String), Str(String),
Int(i32), Int(i32),
@@ -39,6 +40,7 @@ impl fmt::Display for Token {
Token::BranchIf => write!(f, "branch_if"), Token::BranchIf => write!(f, "branch_if"),
Token::Defer => write!(f, "defer"), Token::Defer => write!(f, "defer"),
Token::As => write!(f, "as"), Token::As => write!(f, "as"),
Token::Select => write!(f, "select"),
Token::Ident(s) => write!(f, "{}", s), Token::Ident(s) => write!(f, "{}", s),
Token::Str(s) => write!(f, "{:?}", s), Token::Str(s) => write!(f, "{:?}", s),
Token::Int(v) => write!(f, "{}", v), Token::Int(v) => write!(f, "{}", v),
@@ -189,6 +191,7 @@ fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
"branch_if" => Token::BranchIf, "branch_if" => Token::BranchIf,
"defer" => Token::Defer, "defer" => Token::Defer,
"as" => Token::As, "as" => Token::As,
"select" => Token::Select,
_ => Token::Ident(ident), _ => Token::Ident(ident),
}); });
@@ -326,6 +329,10 @@ mod ast {
condition: Box<Expression>, condition: Box<Expression>,
label: String, label: String,
}, },
UnaryOp {
op: UnaryOp,
value: Box<Expression>,
},
BinOp { BinOp {
op: BinOp, op: BinOp,
left: Box<Expression>, left: Box<Expression>,
@@ -361,6 +368,11 @@ mod ast {
} }
} }
#[derive(Debug, Clone, Copy)]
pub enum UnaryOp {
Negate,
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum BinOp { pub enum BinOp {
Add, Add,
@@ -481,13 +493,41 @@ fn block_parser() -> impl Parser<Token, ast::Block, Error = Simple<Token>> + Clo
value: Box::new(value), value: Box::new(value),
}); });
let select = just(Token::Select)
.ignore_then(
expression
.clone()
.then_ignore(just(Token::Ctrl(',')))
.then(expression.clone())
.then_ignore(just(Token::Ctrl(',')))
.then(expression.clone())
.delimited_by(Token::Ctrl('('), Token::Ctrl(')')),
)
.map(|((condition, if_true), if_false)| ast::Expr::Select {
condition: Box::new(condition),
if_true: Box::new(if_true),
if_false: Box::new(if_false),
});
let function_call = ident
.clone()
.then(
expression
.clone()
.separated_by(just(Token::Ctrl(',')))
.delimited_by(Token::Ctrl('('), Token::Ctrl(')')),
)
.map(|(name, params)| ast::Expr::FuncCall { name, params });
let atom = val let atom = val
.or(tee) .or(tee)
.or(function_call)
.or(variable) .or(variable)
.or(local_tee) .or(local_tee)
.or(loop_expr) .or(loop_expr)
.or(branch_if) .or(branch_if)
.or(let_) .or(let_)
.or(select)
.map_with_span(|expr, span| expr.with_span(span)) .map_with_span(|expr, span| expr.with_span(span))
.or(expression .or(expression
.clone() .clone()
@@ -499,7 +539,23 @@ fn block_parser() -> impl Parser<Token, ast::Block, Error = Simple<Token>> + Clo
|span| ast::Expr::Error.with_span(span), |span| ast::Expr::Error.with_span(span),
)); ));
let op_cast = atom let unary_op = just(Token::Op("-".to_string()))
.to(ast::UnaryOp::Negate)
.map_with_span(|op, span| (op, span))
.repeated()
.then(atom)
.map(|(ops, value)| {
ops.into_iter().rev().fold(value, |acc, (op, span)| {
let span = span.start..acc.span.end;
ast::Expr::UnaryOp {
op,
value: Box::new(acc),
}
.with_span(span)
})
});
let op_cast = unary_op
.clone() .clone()
.then( .then(
just(Token::As) just(Token::As)
@@ -709,7 +765,7 @@ fn top_level_item_parser() -> impl Parser<Token, ast::TopLevelItem, Error = Simp
let function = just(Token::Export) let function = just(Token::Export)
.or_not() .or_not()
.then_ignore(just(Token::Fn)) .then_ignore(just(Token::Fn))
.then(identifier) .then(identifier.clone())
.then( .then(
parameter parameter
.separated_by(just(Token::Ctrl(','))) .separated_by(just(Token::Ctrl(',')))
@@ -732,7 +788,16 @@ fn top_level_item_parser() -> impl Parser<Token, ast::TopLevelItem, Error = Simp
}) })
}); });
import.or(function) let global = just(Token::Global)
.ignore_then(identifier.clone())
.then_ignore(just(Token::Ctrl(':')))
.then(type_parser())
.then_ignore(just(Token::Ctrl(';')))
.map_with_span(|(name, type_), span| {
ast::TopLevelItem::GlobalVar(ast::GlobalVar { name, type_, span })
});
import.or(function).or(global)
} }
fn script_parser() -> impl Parser<Token, ast::Script, Error = Simple<Token>> + Clone { fn script_parser() -> impl Parser<Token, ast::Script, Error = Simple<Token>> + Clone {