sylt_parser/
expression.rs

1use sylt_common::error::Error;
2
3use crate::statement::block_statement;
4
5use super::*;
6
7/// The different kinds of [Expression]s.
8///
9/// Expressions are recursive and evaluate to some kind of value.
10#[derive(Debug, Clone)]
11pub enum ExpressionKind {
12    /// Read from an [Assignable]. Variables, function calls, module accesses,
13    /// blob fields, list indexing, tuple indexing and dict indexing end up here.
14    Get(Assignable),
15
16    /// A type as a value
17    TypeConstant(Type),
18
19    /// `a + b`
20    Add(Box<Expression>, Box<Expression>),
21    /// `a - b`
22    Sub(Box<Expression>, Box<Expression>),
23    /// `a * b`
24    Mul(Box<Expression>, Box<Expression>),
25    /// `a / b`
26    Div(Box<Expression>, Box<Expression>),
27    /// `-a`
28    Neg(Box<Expression>),
29
30    /// `a is b`
31    Is(Box<Expression>, Box<Expression>),
32
33    /// `a == b`
34    Eq(Box<Expression>, Box<Expression>),
35    /// `a != b`
36    Neq(Box<Expression>, Box<Expression>),
37    /// `a > b`
38    Gt(Box<Expression>, Box<Expression>),
39    /// `a >= b`
40    Gteq(Box<Expression>, Box<Expression>),
41    /// `a < b`
42    Lt(Box<Expression>, Box<Expression>),
43    /// `a <= b`
44    Lteq(Box<Expression>, Box<Expression>),
45    /// `a <=> b`
46    AssertEq(Box<Expression>, Box<Expression>),
47
48    /// `a in b`
49    In(Box<Expression>, Box<Expression>),
50
51    /// `a && b`
52    And(Box<Expression>, Box<Expression>),
53    /// `a || b`
54    Or(Box<Expression>, Box<Expression>),
55    /// `!a`
56    Not(Box<Expression>),
57
58    /// Inline If-statements
59    IfExpression {
60        condition: Box<Expression>,
61        pass: Box<Expression>,
62        fail: Box<Expression>,
63    },
64
65    /// Copies a value - small hack to simplify shorthand implementation.
66    Duplicate(Box<Expression>),
67
68    /// Inline If-statements
69    IfShort {
70        condition: Box<Expression>,
71        fail: Box<Expression>,
72    },
73
74    /// Functions and closures.
75    Function {
76        name: String,
77        params: Vec<(Identifier, Type)>,
78        ret: Type,
79
80        body: Box<Statement>,
81    },
82    /// A new instance of a blob.
83    Instance {
84        blob: Assignable,
85        fields: Vec<(String, Expression)>, // Keep calling order
86    },
87    /// `(a, b, ..)`
88    Tuple(Vec<Expression>),
89    /// `[a, b, ..]`
90    List(Vec<Expression>),
91    /// `{a, b, ..}`
92    Set(Vec<Expression>),
93    /// `{ a: b, c: d, .. }`
94    // Has to have even length, listed { k1, v1, k2, v2 }
95    Dict(Vec<Expression>),
96
97    Float(f64),
98    Int(i64),
99    Str(String),
100    Bool(bool),
101    Nil,
102}
103
104/// Expressions evaluate to values. Contains any [ExpressionKind].
105#[derive(Debug, Clone)]
106pub struct Expression {
107    pub span: Span,
108    pub kind: ExpressionKind,
109}
110
111/// Parse an [ExpressionKind::Function]: `fn a: int, b: bool -> bool <statement>`
112fn function<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
113    use RuntimeType::Void;
114    use TypeKind::Resolved;
115
116    let span = ctx.span();
117    let mut ctx = expect!(ctx, T::Fn, "Expected 'fn' for function expression");
118    let mut params = Vec::new();
119    // Parameters
120    let ret = loop {
121        match ctx.token() {
122            T::Identifier(name) => {
123                // Parameter name
124                let ident = Identifier {
125                    span: ctx.span(),
126                    name: name.clone(),
127                };
128                ctx = expect!(ctx.skip(1), T::Colon, "Expected ':' after parameter name");
129                // Parameter type
130                let (_ctx, param) = parse_type(ctx)?;
131                ctx = _ctx; // assign to outer
132
133                params.push((ident, param));
134
135                ctx = if matches!(ctx.token(), T::Comma | T::Arrow | T::LeftBrace) {
136                    ctx.skip_if(T::Comma)
137                } else {
138                    raise_syntax_error!(ctx, "Expected ',' '{{' or '->' after type parameter")
139                };
140            }
141
142            // Parse return type
143            T::Arrow => {
144                ctx = ctx.skip(1);
145                break if let Ok((_ctx, ret)) = parse_type(ctx) {
146                    ctx = _ctx; // assign to outer
147                    ret
148                } else {
149                    Type {
150                        // If we couldn't parse the return type, we assume `-> Void`.
151                        span: ctx.span(),
152                        kind: Resolved(Void),
153                    }
154                };
155            }
156
157            T::LeftBrace => {
158                // No return type so we assume `-> Void`.
159                break Type {
160                    span: ctx.span(),
161                    kind: Resolved(Void),
162                };
163            }
164
165            t => {
166                raise_syntax_error!(ctx, "Didn't expect '{:?}' in function", t);
167            }
168        }
169    };
170
171    // Parse the function statement.
172    let (ctx, mut statement) = block_statement(ctx)?;
173
174    // If the return type isn't void, check for and apply implicit returns.
175
176    let statements = if let StatementKind::Block { statements } = &mut statement.kind {
177        statements
178    } else {
179        unreachable!("Function blocks should only be blocks");
180    };
181
182    if !matches!(ret.kind, Resolved(Void)) {
183        // If the last statement is an expression statement,
184        // replace it with a return statement.
185        let last_statement = statements.pop();
186        if let Some(Statement {
187            span,
188            kind: StatementKind::StatementExpression { value },
189        }) = last_statement
190        {
191            statements.push(Statement {
192                span,
193                kind: StatementKind::Ret { value },
194            });
195        } else if let Some(statement) = last_statement {
196            statements.push(statement);
197        }
198    }
199
200    use ExpressionKind::Function;
201    let function = Function {
202        name: "lambda".into(),
203        params,
204        ret,
205        body: Box::new(statement),
206    };
207
208    Ok((
209        ctx,
210        Expression {
211            span,
212            kind: function,
213        },
214    ))
215}
216
217/// Parse an expression until we reach a token with higher precedence.
218fn parse_precedence<'t>(ctx: Context<'t>, prec: Prec) -> ParseResult<'t, Expression> {
219    // Initial value, e.g. a number value, assignable, ...
220    let (mut ctx, mut expr) = prefix(ctx)?;
221    while prec <= precedence(ctx.token()) {
222        if let Ok((_ctx, _expr)) = infix(ctx, &expr) {
223            // assign to outer
224            ctx = _ctx;
225            expr = _expr;
226        } else {
227            break;
228        }
229    }
230    Ok((ctx, expr))
231}
232
233/// Return a [Token]'s precedence.
234///
235/// See the documentation on [Prec] for how to interpret and compare the
236/// variants.
237#[rustfmt::skip]
238fn precedence(token: &T) -> Prec {
239    use Prec;
240
241    match token {
242        T::LeftBracket => Prec::Index,
243
244        T::Star | T::Slash => Prec::Factor,
245
246        T::Minus | T::Plus => Prec::Term,
247
248        T::EqualEqual
249        | T::Greater
250        | T::GreaterEqual
251        | T::Less
252        | T::LessEqual
253        | T::NotEqual => Prec::Comp,
254
255        T::And => Prec::BoolAnd,
256        T::Or => Prec::BoolOr,
257
258        T::Is => Prec::Index,
259        T::In => Prec::Index,
260
261        T::AssertEqual => Prec::Assert,
262
263        T::Arrow => Prec::Arrow,
264
265        _ => Prec::No,
266    }
267}
268
269/// Parse a single (primitive) value.
270fn value<'t>(ctx: Context<'t>) -> Result<(Context<'t>, Expression), (Context<'t>, Vec<Error>)> {
271    use ExpressionKind::*;
272    let (token, span, ctx) = ctx.eat();
273    let kind = match token.clone() {
274        T::Float(f) => Float(f),
275        T::Int(i) => Int(i),
276        T::Bool(b) => Bool(b),
277        T::Nil => Nil,
278        T::String(s) => Str(s),
279        t => {
280            raise_syntax_error!(ctx, "Cannot parse value, '{:?}' is not a valid value", t);
281        }
282    };
283    Ok((ctx, Expression { span, kind }))
284}
285
286/// Parse something that begins at the start of an expression.
287fn prefix<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
288    use ExpressionKind::{Get, TypeConstant};
289
290    match ctx.token() {
291        T::LeftParen => grouping_or_tuple(ctx),
292        T::LeftBracket => list(ctx),
293        T::LeftBrace => set_or_dict(ctx),
294
295        T::Colon => {
296            let span = ctx.span();
297            let (ctx, ty) = parse_type(ctx.skip(1))?;
298            Ok((
299                ctx,
300                Expression {
301                    span,
302                    kind: TypeConstant(ty),
303                },
304            ))
305        }
306
307        T::Float(_) | T::Int(_) | T::Bool(_) | T::String(_) | T::Nil => value(ctx),
308        T::Minus | T::Bang => unary(ctx),
309
310        T::Identifier(_) => {
311            let span = ctx.span();
312            match (blob(ctx), assignable(ctx)) {
313                (Ok(result), _) => Ok(result),
314                (_, Ok((ctx, assign))) => Ok((
315                    ctx,
316                    Expression {
317                        span,
318                        kind: Get(assign),
319                    },
320                )),
321                (Err((ctx, _)), Err(_)) => {
322                    raise_syntax_error!(ctx, "Neither a blob instantiation or an identifier");
323                }
324            }
325        }
326
327        t => {
328            raise_syntax_error!(ctx, "No valid expression starts with '{:?}'", t);
329        }
330    }
331}
332
333/// Parse a unary operator followed by an expression, e.g. `-5`.
334fn unary<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
335    use ExpressionKind::{Neg, Not};
336
337    let (op, span, ctx) = ctx.eat();
338    let (ctx, expr) = parse_precedence(ctx, Prec::Factor)?;
339    let expr = Box::new(expr);
340
341    let kind = match op {
342        T::Minus => Neg(expr),
343        T::Bang => Not(expr),
344
345        _ => {
346            raise_syntax_error!(ctx, "Invalid unary operator");
347        }
348    };
349    Ok((ctx, Expression { span, kind }))
350}
351
352fn if_short<'t>(ctx: Context<'t>, lhs: &Expression) -> ParseResult<'t, Expression> {
353    use ExpressionKind::*;
354
355    let span = ctx.span();
356    let ctx = expect!(ctx, T::If, "Expected 'if' at start of if-expression");
357
358    let lhs = Expression {
359        span: lhs.span,
360        kind: Duplicate(Box::new(lhs.clone())),
361    };
362
363    let (ctx, condition) = infix(ctx, &lhs)?;
364    let ctx = expect!(
365        ctx,
366        T::Else,
367        "Expected 'else' after short if-expression condition"
368    );
369    let (ctx, rhs) = parse_precedence(ctx, Prec::No)?;
370
371    let condition = Box::new(condition.clone());
372    let fail = Box::new(rhs);
373    Ok((
374        ctx,
375        Expression {
376            span,
377            kind: IfShort {
378                condition,
379                fail,
380            },
381        },
382    ))
383}
384
385
386fn if_expression<'t>(ctx: Context<'t>, lhs: &Expression) -> ParseResult<'t, Expression> {
387    let span = ctx.span();
388    let ctx = expect!(ctx, T::If, "Expected 'if' at start of if-expression");
389
390    use ExpressionKind::*;
391    let (ctx, condition) = parse_precedence(ctx, Prec::No)?;
392
393    let ctx = expect!(
394        ctx,
395        T::Else,
396        "Expected 'else' after if-expression condition"
397    );
398    let (ctx, rhs) = parse_precedence(ctx, Prec::No)?;
399    let condition = Box::new(condition.clone());
400    let pass = Box::new(lhs.clone());
401    let fail = Box::new(rhs);
402    Ok((
403        ctx,
404        Expression {
405            span,
406            kind: IfExpression {
407                condition,
408                pass,
409                fail,
410            },
411        },
412    ))
413}
414
415fn arrow_call<'t>(ctx: Context<'t>, lhs: &Expression) -> ParseResult<'t, Expression> {
416    let ctx = expect!(ctx, T::Arrow, "Expected '->' in arrow function call");
417    let (ctx, rhs) = expression(ctx)?;
418
419    use ExpressionKind::*;
420    use AssignableKind::{Call, ArrowCall};
421
422    fn prepend_expresion<'t>(ctx: Context<'t>, lhs: Expression, rhs: Expression) -> ParseResult<'t, Expression> {
423        let span = ctx.span();
424        let kind = match rhs.kind {
425            Get(Assignable {
426                kind: Call(callee, args),
427                ..
428            }) => Get(Assignable {
429                kind: ArrowCall(Box::new(lhs), callee, args),
430                span: rhs.span,
431            }),
432
433            Get(Assignable {
434                kind: ArrowCall(pre, callee, args),
435                ..
436            }) => {
437                let (_, pre) = prepend_expresion(ctx, lhs, *pre)?;
438                Get(Assignable {
439                    kind: ArrowCall(Box::new(pre), callee, args),
440                    span: rhs.span,
441                })
442            }
443
444            _ => { raise_syntax_error!(ctx, "Expected a call-expression after '->'"); }
445        };
446        Ok((ctx, Expression { span, kind }))
447    }
448
449    prepend_expresion(ctx, lhs.clone(), rhs)
450}
451
452/// Parse an expression starting from an infix operator. Called by `parse_precedence`.
453fn infix<'t>(ctx: Context<'t>, lhs: &Expression) -> ParseResult<'t, Expression> {
454    use ExpressionKind::*;
455
456    // If there is no precedence - it's the start of an expression.
457    // All valid operators have a precedence value that is differnt
458    // from `Prec::no`.
459    match (ctx.token(), precedence(ctx.skip(1).token())) {
460        (T::If, Prec::No) => {
461            return if_expression(ctx, lhs);
462        }
463        (T::If, _) => {
464            return if_short(ctx, lhs);
465        }
466        // The cool arrow syntax. For example: `a->b(2)` compiles to `b(a, 2)`.
467        // #NotLikeOtherOperators
468        (T::Arrow, _) => {
469            return arrow_call(ctx, lhs);
470        }
471        _ => {}
472    }
473
474    // Parse an operator and a following expression
475    // until we reach a token with higher precedence.
476    //
477    // The operator has to be checked before - this
478    // removes an O(x^n).
479    let (op, span, ctx) = ctx.eat();
480
481    match op {
482        T::Plus
483        | T::Minus
484        | T::Star
485        | T::Slash
486        | T::EqualEqual
487        | T::NotEqual
488        | T::Greater
489        | T::GreaterEqual
490        | T::Less
491        | T::LessEqual
492        | T::Is
493
494        | T::And
495        | T::Or
496
497        | T::AssertEqual
498
499        | T::In
500        => {}
501
502        // Unknown infix operator.
503        _ => {
504            return Err((ctx, Vec::new()));
505        }
506    };
507
508
509    let (ctx, rhs) = parse_precedence(ctx, precedence(op).next())?;
510
511    // Left and right of the operator.
512    let lhs = Box::new(lhs.clone());
513    let rhs = Box::new(rhs);
514
515    // Which expression kind to omit depends on the token.
516    let kind = match op {
517        // Simple arithmetic.
518        T::Plus => Add(lhs, rhs),
519        T::Minus => Sub(lhs, rhs),
520        T::Star => Mul(lhs, rhs),
521        T::Slash => Div(lhs, rhs),
522        T::EqualEqual => Eq(lhs, rhs),
523        T::NotEqual => Neq(lhs, rhs),
524        T::Greater => Gt(lhs, rhs),
525        T::GreaterEqual => Gteq(lhs, rhs),
526        T::Less => Lt(lhs, rhs),
527        T::LessEqual => Lteq(lhs, rhs),
528        T::Is => Is(lhs, rhs),
529
530        // Boolean operators.
531        T::And => And(lhs, rhs),
532        T::Or => Or(lhs, rhs),
533
534        T::AssertEqual => AssertEq(lhs, rhs),
535
536        T::In => In(lhs, rhs),
537
538        // Unknown infix operator.
539        _ => {
540            unreachable!();
541        }
542    };
543
544    Ok((ctx, Expression { span, kind }))
545}
546
547/// Parse either a grouping parenthesis or a tuple.
548///
549/// Essentially, one-element tuples are groupings unless they end with a
550/// comma. So `(1)` is parsed as the value `1` while `(1,)` is parsed as the
551/// one-sized tuple containing `1`.
552///
553/// `()` as well as `(,)` are parsed as zero-sized tuples.
554fn grouping_or_tuple<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
555    let span = ctx.span();
556    let ctx = expect!(ctx, T::LeftParen, "Expected '('");
557    let (mut ctx, skip_newlines) = ctx.push_skip_newlines(true);
558
559    // The expressions contained in the parenthesis.
560    let mut exprs = Vec::new();
561
562    let mut is_tuple = matches!(ctx.token(), T::Comma | T::RightParen);
563    loop {
564        // Any initial comma is skipped since we checked it before entering the loop.
565        ctx = ctx.skip_if(T::Comma);
566        match ctx.token() {
567            // Done.
568            T::EOF | T::RightParen => {
569                break;
570            }
571
572            // Another inner expression.
573            _ => {
574                let (_ctx, expr) = expression(ctx)?;
575                exprs.push(expr);
576                ctx = _ctx; // assign to outer
577
578                // Not a tuple, until it is.
579                is_tuple |= matches!(ctx.token(), T::Comma);
580            }
581        }
582    }
583
584    let ctx = ctx.pop_skip_newlines(skip_newlines);
585    let ctx = expect!(ctx, T::RightParen, "Expected ')'");
586
587    use ExpressionKind::Tuple;
588    let result = if is_tuple {
589        Expression {
590            span,
591            kind: Tuple(exprs),
592        }
593    } else {
594        exprs.remove(0)
595    };
596    Ok((ctx, result))
597}
598
599/// Parse a blob instantiation, e.g. `A { b: 55 }`.
600fn blob<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
601    let span = ctx.span();
602    let (ctx, blob) = assignable(ctx)?;
603    let ctx = expect!(ctx, T::LeftBrace, "Expected '{{' after blob name");
604    let (mut ctx, skip_newlines) = ctx.push_skip_newlines(true);
605
606    // The blob's fields.
607    let mut fields = Vec::new();
608    loop {
609        match ctx.token() {
610            // Done with fields.
611            T::RightBrace | T::EOF => {
612                break;
613            }
614
615            // Another field, e.g. `b: 55`.
616            T::Identifier(name) => {
617                // Get the field name.
618                let name = name.clone();
619
620                ctx = expect!(ctx.skip(1), T::Colon, "Expected ':' after field name");
621                // Get the value; `55` in the example above.
622                let (_ctx, expr) = expression(ctx)?;
623                ctx = _ctx; // assign to outer
624
625                if !matches!(ctx.token(), T::Comma | T::RightBrace) {
626                    raise_syntax_error!(
627                        ctx,
628                        "Expected a field delimiter ',' - but got {:?}",
629                        ctx.token()
630                    );
631                }
632                ctx = ctx.skip_if(T::Comma);
633
634                fields.push((name, expr));
635            }
636
637            t => {
638                raise_syntax_error!(ctx, "Unexpected token ('{:?}') in blob initalizer", t);
639            }
640        }
641    }
642
643    let ctx = ctx.pop_skip_newlines(skip_newlines);
644    let ctx = expect!(ctx, T::RightBrace, "Expected '}}' after blob initalizer");
645
646    if matches!(ctx.token(), T::Else) {
647        raise_syntax_error!(ctx, "Parsed a blob instance not an if-statement");
648    }
649
650    use ExpressionKind::Instance;
651    Ok((
652        ctx,
653        Expression {
654            span,
655            kind: Instance { blob, fields },
656        },
657    ))
658}
659
660// Parse a list expression, e.g. `[1, 2, a(3)]`
661fn list<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
662    let span = ctx.span();
663    let ctx = expect!(ctx, T::LeftBracket, "Expected '['");
664    let (mut ctx, skip_newlines) = ctx.push_skip_newlines(true);
665
666    // Inner experssions.
667    let mut exprs = Vec::new();
668    loop {
669        match ctx.token() {
670            // Done with inner expressions.
671            T::EOF | T::RightBracket => {
672                break;
673            }
674
675            // Another one.
676            _ => {
677                let (_ctx, expr) = expression(ctx)?;
678                exprs.push(expr);
679                ctx = _ctx; // assign to outer
680                ctx = ctx.skip_if(T::Comma);
681            }
682        }
683    }
684
685    let ctx = ctx.pop_skip_newlines(skip_newlines);
686    let ctx = expect!(ctx, T::RightBracket, "Expected ']'");
687    use ExpressionKind::List;
688    Ok((
689        ctx,
690        Expression {
691            span,
692            kind: List(exprs),
693        },
694    ))
695}
696
697/// Parse either a set or dict expression.
698///
699/// `{:}` is parsed as the empty dict and {} is parsed as the empty set.
700fn set_or_dict<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
701    let span = ctx.span();
702    let ctx = expect!(ctx, T::LeftBrace, "Expected '{{'");
703    let (mut ctx, skip_newlines) = ctx.push_skip_newlines(true);
704
705    // The inner values of the set or dict.
706    let mut exprs = Vec::new();
707    // None => we don't know. Some(b) => we know b.
708    let mut is_dict = None;
709    loop {
710        match ctx.token() {
711            // Done.
712            T::EOF | T::RightBrace => {
713                break;
714            }
715
716            // Free-standing colon, i.e. "empty dict pair".
717            T::Colon => {
718                // Only valid if we don't know yet.
719                if let Some(is_dict) = is_dict {
720                    raise_syntax_error!(
721                        ctx,
722                        "Empty dict pair is invalid in a {}",
723                        if is_dict { "dict" } else { "set" }
724                    );
725                }
726                is_dict = Some(true);
727                ctx = ctx.skip(1);
728            }
729
730            // Something that's part of an inner expression.
731            _ => {
732                // Parse the expression.
733                let (_ctx, expr) = expression(ctx)?;
734                ctx = _ctx; // assign to outer
735                exprs.push(expr);
736
737                // If a) we know we're a dict or b) the next token is a colon, parse the value of the dict.
738                // Also, if we didn't know previously, store whether we're a dict or not.
739                if *is_dict.get_or_insert_with(|| matches!(ctx.token(), T::Colon)) {
740                    ctx = expect!(ctx, T::Colon, "Expected ':' for dict pair");
741                    // Parse value expression.
742                    let (_ctx, expr) = expression(ctx)?;
743                    ctx = _ctx; // assign to outer
744                    exprs.push(expr);
745                }
746
747                ctx = ctx.skip_if(T::Comma);
748            }
749        }
750    }
751
752    let ctx = ctx.pop_skip_newlines(skip_newlines);
753    let ctx = expect!(ctx, T::RightBrace, "Expected '}}'");
754
755    use ExpressionKind::{Dict, Set};
756    // If we still don't know, assume we're a set.
757    let kind = if is_dict.unwrap_or(false) {
758        Dict(exprs)
759    } else {
760        Set(exprs)
761    };
762
763    Ok((ctx, Expression { span, kind }))
764}
765
766/// Parse a single expression.
767///
768/// An expression is either a function expression or a "normal"
769/// expression that follows precedence rules.
770
771pub fn expression<'t>(ctx: Context<'t>) -> ParseResult<'t, Expression> {
772    match ctx.token() {
773        T::Fn => function(ctx),
774        _ => parse_precedence(ctx, Prec::No),
775    }
776}
777
778// NOTE(ed): It's really hard to write good tests, Rust refuses to deref the boxes
779// automatically.
780//
781// Faulty syntax should be tested in the small language tests.
782#[cfg(test)]
783mod test {
784    use super::ExpressionKind::*;
785    use crate::expression;
786    use crate::test;
787    use crate::Assignable;
788    use crate::AssignableKind::*;
789
790    test!(expression, value: "0" => Int(0));
791    test!(expression, add: "0 + 1.0" => Add(_, _));
792    test!(expression, mul: "\"abc\" * \"abc\"" => Mul(_, _));
793    test!(expression, ident: "a" => Get(Assignable { kind: Read(_), .. }));
794    test!(expression, access: "a.b" => Get(Assignable { kind: Access(_, _), .. }));
795    test!(expression, index_ident: "a[a]" => Get(Assignable { kind: Index(_, _), .. }));
796    test!(expression, index_expr: "a[1 + 2 + 3]" => Get(Assignable { kind: Index(_, _), .. }));
797    test!(expression, grouping: "(0 * 0) + 1" => Add(_, _));
798    test!(expression, grouping_one: "(0)" => Int(0));
799    test!(expression, tuple: "(0, 0)" => Tuple(_));
800    test!(expression, tuple_one: "(0,)" => Tuple(_));
801    test!(expression, tuple_empty: "()" => Tuple(_));
802    test!(expression, list: "[0, 0]" => List(_));
803    test!(expression, set: "{1, 1}" => Set(_));
804    test!(expression, dict: "{1: 1}" => Dict(_));
805    test!(expression, zero_set: "{}" => Set(_));
806    test!(expression, zero_dict: "{:}" => Dict(_));
807
808    test!(expression, in_list: "a in [1, 2, 3]" => In(_, _));
809    test!(expression, in_set: "2 in {1, 1, 2}" => In(_, _));
810    test!(expression, in_grouping: "1 + 2 in b" => Add(_, _));
811    test!(expression, in_grouping_paren: "(1 + 2) in b" => In(_, _));
812
813    test!(expression, call_simple_paren: "a()" => Get(_));
814    test!(expression, call_call: "a()()" => Get(_));
815    test!(expression, call_simple_bang: "a'" => Get(_));
816    test!(expression, call_chaining_paren: "a().b" => Get(_));
817    test!(expression, call_chaining_bang: "a'.b" => Get(_));
818    test!(expression, call_args_paren: "a(1, 2, 3)" => Get(_));
819    test!(expression, call_args_bang: "a' 1, 2, 3" => Get(_));
820    test!(expression, call_args_chaining_paren: "a(1, 2, 3).b" => Get(_));
821    test!(expression, call_args_chaining_paren_trailing: "a(1, 2, 3,).b" => Get(_));
822    test!(expression, assignable_index: "a[0]" => Get(_));
823    test!(expression, assignable_index_twice: "a[0][1]" => Get(_));
824    test!(expression, assignable_mixed: "a[0]()" => Get(_));
825    test!(expression, assignable_mixed_many: "a()[0]()[1]()()()[2][3]" => Get(_));
826
827    // TODO(ed): This is controverisal
828    test!(expression, call_args_chaining_bang: "a' 1, 2, 3 .b" => Get(_));
829    test!(expression, call_args_chaining_bang_trailing: "a' 1, 2, 3, .b" => Get(_));
830
831    test!(expression, call_arrow: "1 + 0 -> a' 2, 3" => Add(_, _));
832    test!(expression, call_arrow_grouping: "(1 + 0) -> a' 2, 3" => Get(_));
833
834    test!(expression, instance: "A { a: 1 + 1, b: nil }" => Instance { .. });
835    test!(expression, instance_more: "A { a: 2, \n c: 2 }" => Instance { .. });
836    test!(expression, instance_empty: "A {}" => Instance { .. });
837
838    test!(expression, simple: "fn -> {}" => _);
839    test!(expression, argument: "fn a: int -> int { ret a + 1 }" => _);
840
841    test!(expression, booleans: "true && false || !false" => _);
842    test!(expression, bool_and: "true && a" => _);
843    test!(expression, bool_or: "a || false" => _);
844    test!(expression, bool_neg: "!a" => _);
845    test!(expression, bool_neg_multiple: "!a && b" => _);
846    test!(expression, bool_neg_multiple_rev: "a && !b" => _);
847
848    test!(expression, cmp_is: "a is B" => _);
849    test!(expression, cmp_eq: "a == b" => _);
850    test!(expression, cmp_neq: "a != b" => _);
851    test!(expression, cmp_leq: "a <= b" => _);
852    test!(expression, cmp_geq: "a >= b" => _);
853    test!(expression, cmp_gt: "a > b" => _);
854    test!(expression, cmp_lt: "a < b" => _);
855    test!(expression, neg: "-a" => _);
856
857    test!(expression, expr: "-a + b < 3 * true && false / 2" => _);
858
859    test!(expression, type_expr_int: ":int" => _);
860    test!(expression, type_expr_void: ":void" => _);
861    test!(expression, type_expr_float: ":float" => _);
862    test!(expression, type_expr_str: ":str" => _);
863    test!(expression, type_expr_custom: ":A" => _);
864    test!(expression, type_expr_custom_chaining: ":A.b.C" => _);
865
866    test!(expression, void_simple: "fn {}" => _);
867    test!(expression, void_argument: "fn a: int { ret a + 1 }" => _);
868
869    test!(expression, if_expr: "a if b else c" => IfExpression { .. });
870    test!(expression, if_expr_more: "1 + 1 + 1 if b else 2 + 2 + 2" => IfExpression { .. });
871}