Implement tuples, remove unary operators

Removed unary `-` in favor of a special function called `~` because
I'm lazy and will probably do it the other way later
This commit is contained in:
Alex Bethel 2022-08-08 21:33:24 -05:00
parent b4fb2deb55
commit 12446bf85e
3 changed files with 62 additions and 35 deletions

View file

@ -1,13 +1,4 @@
// Need tuples, f x is broken // AlexScript
def a (x: String) = 2 + a::b["xyz"] // foo def double x = x * 2;
+ fn x y -> x + y + {a : b}; def tuple = (atan2 x y + z, thing);
def negatives = 2 + ~3;
def b = let (x, y) = 20 in x + y;
def c = match x + 1 {
a => {c: d, e: f},
};
class Cat a {
def meow (cat: a);
}

View file

@ -320,20 +320,34 @@ fn parse_class_def<'a>(
.map(|((name, var), decls)| Statement::ClassDefinition { name, var, decls }) .map(|((name, var), decls)| Statement::ClassDefinition { name, var, decls })
} }
fn parse_expression<'a>(m: &'a ParserMeta) -> impl Parser<char, Expr, Error = Simple<char>> + 'a { fn parse_expression<'a>(
m: &'a ParserMeta,
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone + 'a {
recursive(|full_expr| { recursive(|full_expr| {
let lambda = parse_lambda_expr(m, full_expr.clone()); let lambda = parse_lambda_expr(m, full_expr.clone());
let let_ = parse_let_expr(m, full_expr.clone()); let let_ = parse_let_expr(m, full_expr.clone());
let match_ = parse_match_expr(m, full_expr.clone()); let match_ = parse_match_expr(m, full_expr.clone());
let record = parse_record_expr(m, full_expr.clone()); let record = parse_record_expr(m, full_expr.clone());
let tuple = parse_tuple_expr(m, full_expr.clone());
let base = choice((parse_literal(m), parse_var_ref_expr(m))); let base = choice((parse_literal(m), parse_var_ref_expr(m)));
let subscript = parse_subscript_expr(m, base); let subscript = parse_subscript_expr(m, base);
let term = choice((lambda, let_, match_, record, subscript)); let term = choice((lambda, let_, match_, record, subscript, tuple));
let unary = parse_unary(m, term); // let unary = parse_unary(m, term);
let unary = term;
let binary = (0..=10).rev().fold(unary.boxed(), |p, precedence| { let application = unary.repeated().at_least(1).map(|exprs| {
exprs
.into_iter()
.reduce(|l, r| Expr::Application {
func: Box::new(l),
argument: Box::new(r),
})
.unwrap()
});
let binary = (0..=10).rev().fold(application.boxed(), |p, precedence| {
parse_binary(m, precedence, p).boxed() parse_binary(m, precedence, p).boxed()
}); });
@ -341,20 +355,20 @@ fn parse_expression<'a>(m: &'a ParserMeta) -> impl Parser<char, Expr, Error = Si
}) })
} }
fn parse_unary( // fn parse_unary(
_m: &ParserMeta, // _m: &ParserMeta,
base: impl Parser<char, Expr, Error = Simple<char>> + Clone, // base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone { // ) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
pad(choice((just("-").to("-"), just("+").to("+")))) // pad(just("-").to("-"))
.repeated() // .repeated()
.then(base.clone()) // .then(base.clone())
.map(|(ops, exp)| { // .map(|(ops, exp)| {
ops.into_iter().fold(exp, |exp, op| Expr::UnaryOp { // ops.into_iter().fold(exp, |exp, op| Expr::UnaryOp {
kind: op.to_string(), // kind: op.to_string(),
val: Box::new(exp), // val: Box::new(exp),
}) // })
}) // })
} // }
fn parse_binary<'a>( fn parse_binary<'a>(
m: &'a ParserMeta, m: &'a ParserMeta,
@ -535,10 +549,29 @@ fn parse_subscript_expr(
}) })
} }
fn parse_tuple_expr(
_m: &ParserMeta,
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
base.separated_by(pad(just(',')))
.delimited_by(pad(just('(')), pad(just(')')))
.map(|exprs| {
if exprs.len() == 1 {
exprs.into_iter().next().unwrap()
} else {
Expr::Tuple(exprs)
}
})
}
fn parse_var_ref_expr(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char>> + Clone { fn parse_var_ref_expr(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
choice((
pad(just("~")).to(Expr::VariableReference(vec!["~".to_string()])),
pad(ident()) pad(ident())
.separated_by(pad(just("::"))) .separated_by(pad(just("::")))
.map(Expr::VariableReference) .at_least(1)
.map(Expr::VariableReference),
))
} }
fn parse_literal(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char>> + Clone { fn parse_literal(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
@ -722,7 +755,7 @@ fn whitespace_cmt() -> impl Parser<char, (), Error = Simple<char>> + Clone {
whitespace().then_ignore( whitespace().then_ignore(
just("//") just("//")
.then(none_of("\n").repeated()) .then(none_of("\n").repeated())
.then(just('\n')) .then(just('\n').to(()).or(end()))
.then(whitespace()) .then(whitespace())
.repeated(), .repeated(),
) )

View file

@ -173,6 +173,9 @@ pub enum Expr {
subscript: Box<Expr>, subscript: Box<Expr>,
}, },
/// Tuple expressions, e.g., `(2, 3)`.
Tuple(Vec<Expr>),
/// Variable references, possibly namespaced, e.g., `foo::bar::baz`. /// Variable references, possibly namespaced, e.g., `foo::bar::baz`.
VariableReference(Vec<String>), VariableReference(Vec<String>),