Skip to main content

luau_syntax/ast/
expression.rs

1use super::*;
2use crate::allocator::AstArena;
3use crate::location::Position;
4use std::fmt;
5use std::marker::PhantomData;
6use std::ptr::NonNull;
7
8#[repr(u8)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum ExpressionTag {
11    Boolean,
12    Call,
13    FunctionLiteral,
14    Grouped,
15    Integer,
16    Nil,
17    Number,
18    String,
19    InterpString,
20    Table,
21    If,
22    Varargs,
23    IndexExpr,
24    IndexName,
25    TypeAssertion,
26    Instantiate,
27    Unary,
28    Local,
29    Global,
30    Binary,
31    Error,
32}
33
34#[repr(C)]
35#[derive(Debug, PartialEq)]
36pub struct ExpressionHeader<'ast> {
37    pub tag: ExpressionTag,
38    pub location: Location,
39    _marker: PhantomData<&'ast ()>,
40}
41
42#[derive(Clone, Copy)]
43pub struct Expression<'ast> {
44    ptr: NonNull<ExpressionHeader<'ast>>,
45    _marker: PhantomData<&'ast ExpressionHeader<'ast>>,
46}
47
48impl fmt::Debug for Expression<'_> {
49    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
50        formatter
51            .debug_struct("Expression")
52            .field("location", &self.location())
53            .field("kind", &self.kind())
54            .finish()
55    }
56}
57
58impl PartialEq for Expression<'_> {
59    fn eq(&self, other: &Self) -> bool {
60        self.location() == other.location() && self.kind() == other.kind()
61    }
62}
63
64impl<'ast> std::ops::Deref for Expression<'ast> {
65    type Target = ExpressionHeader<'ast>;
66
67    fn deref(&self) -> &Self::Target {
68        self.header()
69    }
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
73pub enum ConstantNumberParseResult {
74    Ok,
75    Imprecise,
76    Malformed,
77    BinOverflow,
78    HexOverflow,
79    IntOverflow,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83pub enum StringQuoteStyle {
84    QuotedSimple,
85    QuotedSingle,
86    QuotedRaw,
87    Unquoted,
88}
89
90impl From<LexerQuoteStyle> for StringQuoteStyle {
91    fn from(_: LexerQuoteStyle) -> Self {
92        Self::QuotedSimple
93    }
94}
95
96#[derive(Debug, Clone, Copy, PartialEq)]
97pub enum ExpressionKind<'ast> {
98    Boolean(bool),
99    Call {
100        func: Expression<'ast>,
101        type_args: &'ast [TypeOrPack<'ast>],
102        args: &'ast [Expression<'ast>],
103        self_call: bool,
104        arg_location: Location,
105    },
106    FunctionLiteral(&'ast Function<'ast>),
107    Grouped(Expression<'ast>),
108    Integer {
109        value: i64,
110        parse_result: ConstantNumberParseResult,
111    },
112    Nil,
113    Number {
114        value: f64,
115        parse_result: ConstantNumberParseResult,
116    },
117    String {
118        value: AstString<'ast>,
119        quote_style: StringQuoteStyle,
120    },
121    InterpString {
122        strings: &'ast [AstString<'ast>],
123        expressions: &'ast [Expression<'ast>],
124    },
125    Table {
126        items: &'ast [TableItem<'ast>],
127    },
128    If {
129        condition: Expression<'ast>,
130        has_then: bool,
131        then_expression: Expression<'ast>,
132        has_else: bool,
133        else_expression: Expression<'ast>,
134    },
135    Varargs,
136    IndexExpr {
137        expr: Expression<'ast>,
138        index: Expression<'ast>,
139    },
140    IndexName {
141        expr: Expression<'ast>,
142        index: AstName<'ast>,
143        index_location: Location,
144        op_position: Position,
145        op: IndexNameOp,
146    },
147    TypeAssertion {
148        expr: Expression<'ast>,
149        annotation: Type<'ast>,
150    },
151    Instantiate {
152        expr: Expression<'ast>,
153        type_args: &'ast [TypeOrPack<'ast>],
154    },
155    Unary {
156        op: UnaryOp,
157        rhs: Expression<'ast>,
158    },
159    Local {
160        local: &'ast Local<'ast>,
161        upvalue: bool,
162    },
163    Global(AstName<'ast>),
164    Binary {
165        lhs: Expression<'ast>,
166        op: BinaryOp,
167        rhs: Expression<'ast>,
168    },
169    Error {
170        expressions: &'ast [Expression<'ast>],
171        message_index: usize,
172    },
173}
174
175#[derive(Debug, Clone, Copy, PartialEq)]
176pub struct ExpressionInit<'ast> {
177    pub location: Location,
178    pub kind: ExpressionKind<'ast>,
179}
180
181impl<'ast> ExpressionInit<'ast> {
182    pub fn new(location: Location, kind: ExpressionKind<'ast>) -> Self {
183        Self { location, kind }
184    }
185
186    pub fn location(&self) -> Location {
187        self.location
188    }
189}
190
191macro_rules! expr_node {
192    ($name:ident { $($field:ident : $ty:ty),* $(,)? }, $tag:ident) => {
193        #[repr(C)]
194        #[derive(Debug, PartialEq)]
195        pub struct $name<'ast> {
196            pub base: ExpressionHeader<'ast>,
197            $(pub $field: $ty),*
198        }
199
200        impl<'ast> $name<'ast> {
201            pub fn new(location: Location, $($field: $ty),*) -> Self {
202                Self {
203                    base: Expression::new_header(ExpressionTag::$tag, location),
204                    $($field),*
205                }
206            }
207        }
208    };
209}
210
211#[repr(C)]
212#[derive(Debug, PartialEq)]
213pub struct ExpressionUnit<'ast> {
214    pub base: ExpressionHeader<'ast>,
215}
216
217impl<'ast> ExpressionUnit<'ast> {
218    pub fn new(tag: ExpressionTag, location: Location) -> Self {
219        Self {
220            base: Expression::new_header(tag, location),
221        }
222    }
223}
224
225expr_node!(ExpressionBoolean { value: bool }, Boolean);
226expr_node!(
227    ExpressionCall {
228        func: Expression<'ast>,
229        type_args: &'ast [TypeOrPack<'ast>],
230        args: &'ast [Expression<'ast>],
231        self_call: bool,
232        arg_location: Location
233    },
234    Call
235);
236expr_node!(
237    ExpressionFunctionLiteral {
238        function: &'ast Function<'ast>
239    },
240    FunctionLiteral
241);
242expr_node!(ExpressionGrouped { expression: Expression<'ast> }, Grouped);
243expr_node!(
244    ExpressionInteger {
245        value: i64,
246        parse_result: ConstantNumberParseResult
247    },
248    Integer
249);
250expr_node!(
251    ExpressionNumber {
252        value: f64,
253        parse_result: ConstantNumberParseResult
254    },
255    Number
256);
257expr_node!(
258    ExpressionString {
259        value: AstString<'ast>,
260        quote_style: StringQuoteStyle
261    },
262    String
263);
264expr_node!(
265    ExpressionInterpString {
266        strings: &'ast [AstString<'ast>],
267        expressions: &'ast [Expression<'ast>]
268    },
269    InterpString
270);
271expr_node!(ExpressionTable { items: &'ast [TableItem<'ast>] }, Table);
272expr_node!(
273    ExpressionIf {
274        condition: Expression<'ast>,
275        has_then: bool,
276        then_expression: Expression<'ast>,
277        has_else: bool,
278        else_expression: Expression<'ast>
279    },
280    If
281);
282expr_node!(
283    ExpressionIndexExpr {
284        expr: Expression<'ast>,
285        index: Expression<'ast>
286    },
287    IndexExpr
288);
289expr_node!(
290    ExpressionIndexName {
291        expr: Expression<'ast>,
292        index: AstName<'ast>,
293        index_location: Location,
294        op_position: Position,
295        op: IndexNameOp
296    },
297    IndexName
298);
299expr_node!(
300    ExpressionTypeAssertion {
301        expr: Expression<'ast>,
302        annotation: Type<'ast>
303    },
304    TypeAssertion
305);
306expr_node!(
307    ExpressionInstantiate {
308        expr: Expression<'ast>,
309        type_args: &'ast [TypeOrPack<'ast>]
310    },
311    Instantiate
312);
313expr_node!(ExpressionUnary { op: UnaryOp, rhs: Expression<'ast> }, Unary);
314expr_node!(
315    ExpressionLocal {
316        local: &'ast Local<'ast>,
317        upvalue: bool
318    },
319    Local
320);
321expr_node!(ExpressionGlobal { name: AstName<'ast> }, Global);
322expr_node!(
323    ExpressionBinary {
324        lhs: Expression<'ast>,
325        op: BinaryOp,
326        rhs: Expression<'ast>
327    },
328    Binary
329);
330expr_node!(
331    ExpressionError {
332        expressions: &'ast [Expression<'ast>],
333        message_index: usize
334    },
335    Error
336);
337
338impl<'ast> Expression<'ast> {
339    pub const fn new_header(tag: ExpressionTag, location: Location) -> ExpressionHeader<'ast> {
340        ExpressionHeader {
341            tag,
342            location,
343            _marker: PhantomData,
344        }
345    }
346
347    pub(crate) fn from_node<T>(node: &'ast mut T) -> Self {
348        Self {
349            ptr: NonNull::from(node).cast(),
350            _marker: PhantomData,
351        }
352    }
353
354    pub fn as_ptr(self) -> *const () {
355        self.ptr.as_ptr().cast()
356    }
357
358    #[inline(always)]
359    fn header(&self) -> &ExpressionHeader<'ast> {
360        unsafe { self.ptr.as_ref() }
361    }
362
363    #[inline(always)]
364    pub fn location(self) -> Location {
365        self.header().location
366    }
367
368    #[inline(always)]
369    pub fn kind(&self) -> ExpressionKind<'ast> {
370        match self.tag {
371            ExpressionTag::Boolean => {
372                ExpressionKind::Boolean(self.cast_ref::<ExpressionBoolean>().value)
373            }
374            ExpressionTag::Call => {
375                let node = self.cast_ref::<ExpressionCall>();
376                ExpressionKind::Call {
377                    func: node.func,
378                    type_args: node.type_args,
379                    args: node.args,
380                    self_call: node.self_call,
381                    arg_location: node.arg_location,
382                }
383            }
384            ExpressionTag::FunctionLiteral => ExpressionKind::FunctionLiteral(
385                self.cast_ref::<ExpressionFunctionLiteral>().function,
386            ),
387            ExpressionTag::Grouped => {
388                ExpressionKind::Grouped(self.cast_ref::<ExpressionGrouped>().expression)
389            }
390            ExpressionTag::Integer => {
391                let node = self.cast_ref::<ExpressionInteger>();
392                ExpressionKind::Integer {
393                    value: node.value,
394                    parse_result: node.parse_result,
395                }
396            }
397            ExpressionTag::Nil => ExpressionKind::Nil,
398            ExpressionTag::Number => {
399                let node = self.cast_ref::<ExpressionNumber>();
400                ExpressionKind::Number {
401                    value: node.value,
402                    parse_result: node.parse_result,
403                }
404            }
405            ExpressionTag::String => {
406                let node = self.cast_ref::<ExpressionString>();
407                ExpressionKind::String {
408                    value: node.value,
409                    quote_style: node.quote_style,
410                }
411            }
412            ExpressionTag::InterpString => {
413                let node = self.cast_ref::<ExpressionInterpString>();
414                ExpressionKind::InterpString {
415                    strings: node.strings,
416                    expressions: node.expressions,
417                }
418            }
419            ExpressionTag::Table => ExpressionKind::Table {
420                items: self.cast_ref::<ExpressionTable>().items,
421            },
422            ExpressionTag::If => {
423                let node = self.cast_ref::<ExpressionIf>();
424                ExpressionKind::If {
425                    condition: node.condition,
426                    has_then: node.has_then,
427                    then_expression: node.then_expression,
428                    has_else: node.has_else,
429                    else_expression: node.else_expression,
430                }
431            }
432            ExpressionTag::Varargs => ExpressionKind::Varargs,
433            ExpressionTag::IndexExpr => {
434                let node = self.cast_ref::<ExpressionIndexExpr>();
435                ExpressionKind::IndexExpr {
436                    expr: node.expr,
437                    index: node.index,
438                }
439            }
440            ExpressionTag::IndexName => {
441                let node = self.cast_ref::<ExpressionIndexName>();
442                ExpressionKind::IndexName {
443                    expr: node.expr,
444                    index: node.index,
445                    index_location: node.index_location,
446                    op_position: node.op_position,
447                    op: node.op,
448                }
449            }
450            ExpressionTag::TypeAssertion => {
451                let node = self.cast_ref::<ExpressionTypeAssertion>();
452                ExpressionKind::TypeAssertion {
453                    expr: node.expr,
454                    annotation: node.annotation,
455                }
456            }
457            ExpressionTag::Instantiate => {
458                let node = self.cast_ref::<ExpressionInstantiate>();
459                ExpressionKind::Instantiate {
460                    expr: node.expr,
461                    type_args: node.type_args,
462                }
463            }
464            ExpressionTag::Unary => {
465                let node = self.cast_ref::<ExpressionUnary>();
466                ExpressionKind::Unary {
467                    op: node.op,
468                    rhs: node.rhs,
469                }
470            }
471            ExpressionTag::Local => {
472                let node = self.cast_ref::<ExpressionLocal>();
473                ExpressionKind::Local {
474                    local: node.local,
475                    upvalue: node.upvalue,
476                }
477            }
478            ExpressionTag::Global => {
479                ExpressionKind::Global(self.cast_ref::<ExpressionGlobal>().name)
480            }
481            ExpressionTag::Binary => {
482                let node = self.cast_ref::<ExpressionBinary>();
483                ExpressionKind::Binary {
484                    lhs: node.lhs,
485                    op: node.op,
486                    rhs: node.rhs,
487                }
488            }
489            ExpressionTag::Error => {
490                let node = self.cast_ref::<ExpressionError>();
491                ExpressionKind::Error {
492                    expressions: node.expressions,
493                    message_index: node.message_index,
494                }
495            }
496        }
497    }
498
499    pub fn visit<V: AstVisitor>(self, visitor: &mut V) {
500        let should_visit = match self.kind() {
501            ExpressionKind::Boolean(_) => visitor.visit_boolean_expression(self),
502            ExpressionKind::Call { .. } => visitor.visit_call_expression(self),
503            ExpressionKind::FunctionLiteral(_) => visitor.visit_function_literal_expression(self),
504            ExpressionKind::Grouped(_) => visitor.visit_grouped_expression(self),
505            ExpressionKind::Integer { .. } => visitor.visit_integer_expression(self),
506            ExpressionKind::Nil => visitor.visit_nil_expression(self),
507            ExpressionKind::Number { .. } => visitor.visit_number_expression(self),
508            ExpressionKind::String { .. } => visitor.visit_string_expression(self),
509            ExpressionKind::InterpString { .. } => visitor.visit_interp_string_expression(self),
510            ExpressionKind::Table { .. } => visitor.visit_table_expression(self),
511            ExpressionKind::If { .. } => visitor.visit_if_expression(self),
512            ExpressionKind::Varargs => visitor.visit_varargs_expression(self),
513            ExpressionKind::IndexExpr { .. } => visitor.visit_index_expression(self),
514            ExpressionKind::IndexName { .. } => visitor.visit_index_name_expression(self),
515            ExpressionKind::TypeAssertion { .. } => visitor.visit_type_assertion_expression(self),
516            ExpressionKind::Instantiate { .. } => visitor.visit_instantiate_expression(self),
517            ExpressionKind::Unary { .. } => visitor.visit_unary_expression(self),
518            ExpressionKind::Local { .. } => visitor.visit_local_expression(self),
519            ExpressionKind::Global(_) => visitor.visit_global_expression(self),
520            ExpressionKind::Binary { .. } => visitor.visit_binary_expression(self),
521            ExpressionKind::Error { .. } => visitor.visit_error_expression(self),
522        };
523
524        if !should_visit {
525            return;
526        }
527
528        match self.kind() {
529            ExpressionKind::Boolean(_)
530            | ExpressionKind::Integer { .. }
531            | ExpressionKind::Nil
532            | ExpressionKind::Number { .. }
533            | ExpressionKind::String { .. }
534            | ExpressionKind::Varargs
535            | ExpressionKind::Local { .. }
536            | ExpressionKind::Global(_) => {}
537            ExpressionKind::InterpString { expressions, .. } => {
538                visit_expressions(expressions, visitor);
539            }
540            ExpressionKind::Call { func, args, .. } => {
541                func.visit(visitor);
542                visit_expressions(args, visitor);
543            }
544            ExpressionKind::FunctionLiteral(function) => function.visit(visitor),
545            ExpressionKind::Grouped(expression) => expression.visit(visitor),
546            ExpressionKind::Table { items, .. } => {
547                for item in items {
548                    item.visit(visitor);
549                }
550            }
551            ExpressionKind::If {
552                condition,
553                then_expression,
554                else_expression,
555                ..
556            } => {
557                condition.visit(visitor);
558                then_expression.visit(visitor);
559                else_expression.visit(visitor);
560            }
561            ExpressionKind::IndexExpr { expr, index, .. } => {
562                expr.visit(visitor);
563                index.visit(visitor);
564            }
565            ExpressionKind::IndexName { expr, .. } => expr.visit(visitor),
566            ExpressionKind::TypeAssertion {
567                expr, annotation, ..
568            } => {
569                expr.visit(visitor);
570                annotation.visit(visitor);
571            }
572            ExpressionKind::Instantiate {
573                expr, type_args, ..
574            } => {
575                expr.visit(visitor);
576                for argument in type_args {
577                    match argument {
578                        TypeOrPack::Type(annotation) => annotation.visit(visitor),
579                        TypeOrPack::Pack(pack) => pack.visit(visitor),
580                    }
581                }
582            }
583            ExpressionKind::Unary { rhs, .. } => rhs.visit(visitor),
584            ExpressionKind::Binary { lhs, rhs, .. } => {
585                lhs.visit(visitor);
586                rhs.visit(visitor);
587            }
588            ExpressionKind::Error { expressions, .. } => visit_expressions(expressions, visitor),
589        }
590    }
591
592    #[inline(always)]
593    fn cast_ref<T>(self) -> &'ast T {
594        unsafe { self.ptr.cast::<T>().as_ref() }
595    }
596
597    #[inline(always)]
598    fn cast_if_tag<T>(self, tag: ExpressionTag) -> Option<&'ast T> {
599        (self.tag == tag).then(|| self.cast_ref())
600    }
601
602    #[inline(always)]
603    pub fn as_boolean(self) -> Option<&'ast ExpressionBoolean<'ast>> {
604        self.cast_if_tag(ExpressionTag::Boolean)
605    }
606
607    #[inline(always)]
608    pub fn as_call(self) -> Option<&'ast ExpressionCall<'ast>> {
609        self.cast_if_tag(ExpressionTag::Call)
610    }
611
612    #[inline(always)]
613    pub fn as_function_literal(self) -> Option<&'ast ExpressionFunctionLiteral<'ast>> {
614        self.cast_if_tag(ExpressionTag::FunctionLiteral)
615    }
616
617    #[inline(always)]
618    pub fn as_grouped(self) -> Option<&'ast ExpressionGrouped<'ast>> {
619        self.cast_if_tag(ExpressionTag::Grouped)
620    }
621
622    #[inline(always)]
623    pub fn as_integer(self) -> Option<&'ast ExpressionInteger<'ast>> {
624        self.cast_if_tag(ExpressionTag::Integer)
625    }
626
627    #[inline(always)]
628    pub fn as_number(self) -> Option<&'ast ExpressionNumber<'ast>> {
629        self.cast_if_tag(ExpressionTag::Number)
630    }
631
632    #[inline(always)]
633    pub fn as_string(self) -> Option<&'ast ExpressionString<'ast>> {
634        self.cast_if_tag(ExpressionTag::String)
635    }
636
637    #[inline(always)]
638    pub fn as_interp_string(self) -> Option<&'ast ExpressionInterpString<'ast>> {
639        self.cast_if_tag(ExpressionTag::InterpString)
640    }
641
642    #[inline(always)]
643    pub fn as_table(self) -> Option<&'ast ExpressionTable<'ast>> {
644        self.cast_if_tag(ExpressionTag::Table)
645    }
646
647    #[inline(always)]
648    pub fn as_if(self) -> Option<&'ast ExpressionIf<'ast>> {
649        self.cast_if_tag(ExpressionTag::If)
650    }
651
652    #[inline(always)]
653    pub fn as_index_expr(self) -> Option<&'ast ExpressionIndexExpr<'ast>> {
654        self.cast_if_tag(ExpressionTag::IndexExpr)
655    }
656
657    #[inline(always)]
658    pub fn as_index_name(self) -> Option<&'ast ExpressionIndexName<'ast>> {
659        self.cast_if_tag(ExpressionTag::IndexName)
660    }
661
662    #[inline(always)]
663    pub fn as_type_assertion(self) -> Option<&'ast ExpressionTypeAssertion<'ast>> {
664        self.cast_if_tag(ExpressionTag::TypeAssertion)
665    }
666
667    #[inline(always)]
668    pub fn as_instantiate(self) -> Option<&'ast ExpressionInstantiate<'ast>> {
669        self.cast_if_tag(ExpressionTag::Instantiate)
670    }
671
672    #[inline(always)]
673    pub fn as_unary(self) -> Option<&'ast ExpressionUnary<'ast>> {
674        self.cast_if_tag(ExpressionTag::Unary)
675    }
676
677    #[inline(always)]
678    pub fn as_local(self) -> Option<&'ast ExpressionLocal<'ast>> {
679        self.cast_if_tag(ExpressionTag::Local)
680    }
681
682    #[inline(always)]
683    pub fn as_global(self) -> Option<&'ast ExpressionGlobal<'ast>> {
684        self.cast_if_tag(ExpressionTag::Global)
685    }
686
687    #[inline(always)]
688    pub fn as_binary(self) -> Option<&'ast ExpressionBinary<'ast>> {
689        self.cast_if_tag(ExpressionTag::Binary)
690    }
691
692    #[inline(always)]
693    pub fn as_error(self) -> Option<&'ast ExpressionError<'ast>> {
694        self.cast_if_tag(ExpressionTag::Error)
695    }
696}
697
698#[derive(Debug, Clone, Copy, PartialEq)]
699pub enum TableItem<'ast> {
700    List {
701        value: Expression<'ast>,
702    },
703    Record {
704        key: Expression<'ast>,
705        value: Expression<'ast>,
706    },
707    General {
708        key: Expression<'ast>,
709        value: Expression<'ast>,
710    },
711}
712
713impl TableItem<'_> {
714    pub fn visit<V: AstVisitor>(&self, visitor: &mut V) {
715        match self {
716            Self::List { value } => value.visit(visitor),
717            Self::Record { key, value } | Self::General { key, value } => {
718                key.visit(visitor);
719                value.visit(visitor);
720            }
721        }
722    }
723}
724
725#[derive(Debug, Clone, Copy, PartialEq, Eq)]
726pub enum IndexNameOp {
727    Dot,
728    Colon,
729}
730
731impl IndexNameOp {
732    pub fn symbol(self) -> &'static str {
733        match self {
734            Self::Dot => ".",
735            Self::Colon => ":",
736        }
737    }
738}
739
740#[derive(Debug, PartialEq)]
741pub struct Function<'ast> {
742    pub location: Location,
743    pub attributes: &'ast [&'ast Attribute<'ast>],
744    pub generics: &'ast [&'ast GenericType<'ast>],
745    pub generic_packs: &'ast [&'ast GenericTypePack<'ast>],
746    pub self_parameter: Option<&'ast Local<'ast>>,
747    pub args: &'ast [&'ast Local<'ast>],
748    pub vararg: bool,
749    pub vararg_location: Location,
750    pub body: Block<'ast>,
751    pub function_depth: usize,
752    pub debug_name: Option<AstName<'ast>>,
753    pub return_annotation: Option<TypePack<'ast>>,
754    pub vararg_annotation: Option<TypePack<'ast>>,
755    pub arg_location: Option<Location>,
756}
757
758impl<'ast> Function<'ast> {
759    pub fn has_native_attribute(&self) -> bool {
760        self.has_attribute(AttributeKind::Native)
761    }
762
763    pub fn has_attribute(&self, kind: AttributeKind) -> bool {
764        self.get_attribute(kind).is_some()
765    }
766
767    pub fn get_attribute(&self, kind: AttributeKind) -> Option<&'ast Attribute<'ast>> {
768        find_attribute(self.attributes, kind)
769    }
770
771    pub fn visit<V: AstVisitor>(&self, visitor: &mut V) {
772        for arg in self.args {
773            arg.visit(visitor);
774        }
775        if let Some(annotation) = &self.vararg_annotation {
776            annotation.visit(visitor);
777        }
778        if let Some(annotation) = &self.return_annotation {
779            annotation.visit(visitor);
780        }
781        self.body.visit(visitor);
782    }
783}
784
785#[derive(Debug, Clone, Copy, PartialEq, Eq)]
786pub enum UnaryOp {
787    Length,
788    Negate,
789    Not,
790}
791
792impl UnaryOp {
793    pub fn symbol(self) -> &'static str {
794        match self {
795            Self::Length => "#",
796            Self::Negate => "-",
797            Self::Not => "not",
798        }
799    }
800}
801
802#[derive(Debug, Clone, Copy, PartialEq, Eq)]
803pub enum BinaryOp {
804    Add,
805    And,
806    Concat,
807    Equal,
808    FloorDivide,
809    Greater,
810    GreaterEqual,
811    Less,
812    LessEqual,
813    NotEqual,
814    Or,
815    Subtract,
816    Multiply,
817    Divide,
818    Modulo,
819    Power,
820}
821
822impl BinaryOp {
823    pub fn symbol(self) -> &'static str {
824        match self {
825            Self::Add => "+",
826            Self::And => "and",
827            Self::Concat => "..",
828            Self::Equal => "==",
829            Self::FloorDivide => "//",
830            Self::Greater => ">",
831            Self::GreaterEqual => ">=",
832            Self::Less => "<",
833            Self::LessEqual => "<=",
834            Self::NotEqual => "~=",
835            Self::Or => "or",
836            Self::Subtract => "-",
837            Self::Multiply => "*",
838            Self::Divide => "/",
839            Self::Modulo => "%",
840            Self::Power => "^",
841        }
842    }
843}
844
845impl AstArena {
846    fn alloc_expression_node<'ast, T: 'ast>(&'ast self, node: T) -> Expression<'ast> {
847        Expression::from_node(self.alloc(node))
848    }
849
850    pub(crate) fn alloc_expression_boolean_direct<'ast>(
851        &'ast self,
852        location: Location,
853        value: bool,
854    ) -> Expression<'ast> {
855        self.alloc_expression_node(ExpressionBoolean::new(location, value))
856    }
857
858    pub(crate) fn alloc_expression_grouped_direct<'ast>(
859        &'ast self,
860        location: Location,
861        expression: Expression<'ast>,
862    ) -> Expression<'ast> {
863        self.alloc_expression_node(ExpressionGrouped::new(location, expression))
864    }
865
866    pub(crate) fn alloc_expression_integer_direct<'ast>(
867        &'ast self,
868        location: Location,
869        value: i64,
870        parse_result: ConstantNumberParseResult,
871    ) -> Expression<'ast> {
872        self.alloc_expression_node(ExpressionInteger::new(location, value, parse_result))
873    }
874
875    pub(crate) fn alloc_expression_number_direct<'ast>(
876        &'ast self,
877        location: Location,
878        value: f64,
879        parse_result: ConstantNumberParseResult,
880    ) -> Expression<'ast> {
881        self.alloc_expression_node(ExpressionNumber::new(location, value, parse_result))
882    }
883
884    pub(crate) fn alloc_expression_string_direct<'ast>(
885        &'ast self,
886        location: Location,
887        value: AstString<'ast>,
888        quote_style: StringQuoteStyle,
889    ) -> Expression<'ast> {
890        self.alloc_expression_node(ExpressionString::new(location, value, quote_style))
891    }
892
893    pub(crate) fn alloc_expression_unary_direct<'ast>(
894        &'ast self,
895        location: Location,
896        op: UnaryOp,
897        rhs: Expression<'ast>,
898    ) -> Expression<'ast> {
899        self.alloc_expression_node(ExpressionUnary::new(location, op, rhs))
900    }
901
902    pub(crate) fn alloc_expression_local_direct<'ast>(
903        &'ast self,
904        location: Location,
905        local: &'ast Local<'ast>,
906        upvalue: bool,
907    ) -> Expression<'ast> {
908        self.alloc_expression_node(ExpressionLocal::new(location, local, upvalue))
909    }
910
911    pub(crate) fn alloc_expression_global_direct<'ast>(
912        &'ast self,
913        location: Location,
914        name: AstName<'ast>,
915    ) -> Expression<'ast> {
916        self.alloc_expression_node(ExpressionGlobal::new(location, name))
917    }
918
919    pub(crate) fn alloc_expression_function_literal_direct<'ast>(
920        &'ast self,
921        location: Location,
922        function: &'ast mut Function<'ast>,
923    ) -> Expression<'ast> {
924        self.alloc_expression_node(ExpressionFunctionLiteral::new(location, function))
925    }
926
927    pub(crate) fn alloc_expression_binary_direct<'ast>(
928        &'ast self,
929        location: Location,
930        lhs: Expression<'ast>,
931        op: BinaryOp,
932        rhs: Expression<'ast>,
933    ) -> Expression<'ast> {
934        self.alloc_expression_node(ExpressionBinary::new(location, lhs, op, rhs))
935    }
936
937    pub(crate) fn alloc_expression_nil_direct<'ast>(
938        &'ast self,
939        location: Location,
940    ) -> Expression<'ast> {
941        self.alloc_expression_node(ExpressionUnit::new(ExpressionTag::Nil, location))
942    }
943
944    pub(crate) fn alloc_expression_index_name_direct<'ast>(
945        &'ast self,
946        location: Location,
947        expr: Expression<'ast>,
948        index: AstName<'ast>,
949        index_location: Location,
950        op_position: Position,
951        op: IndexNameOp,
952    ) -> Expression<'ast> {
953        self.alloc_expression_node(ExpressionIndexName::new(
954            location,
955            expr,
956            index,
957            index_location,
958            op_position,
959            op,
960        ))
961    }
962
963    pub(crate) fn alloc_expression_error_direct<'ast>(
964        &'ast self,
965        location: Location,
966        expressions: &'ast [Expression<'ast>],
967        message_index: usize,
968    ) -> Expression<'ast> {
969        self.alloc_expression_node(ExpressionError::new(location, expressions, message_index))
970    }
971
972    pub(crate) fn alloc_expression_kind<'ast>(
973        &'ast self,
974        location: Location,
975        kind: ExpressionKind<'ast>,
976    ) -> Expression<'ast> {
977        match kind {
978            ExpressionKind::Boolean(value) => {
979                self.alloc_expression_node(ExpressionBoolean::new(location, value))
980            }
981            ExpressionKind::Call {
982                func,
983                type_args,
984                args,
985                self_call,
986                arg_location,
987            } => self.alloc_expression_node(ExpressionCall::new(
988                location,
989                func,
990                type_args,
991                args,
992                self_call,
993                arg_location,
994            )),
995            ExpressionKind::FunctionLiteral(function) => {
996                self.alloc_expression_node(ExpressionFunctionLiteral::new(location, function))
997            }
998            ExpressionKind::Grouped(expression) => {
999                self.alloc_expression_node(ExpressionGrouped::new(location, expression))
1000            }
1001            ExpressionKind::Integer {
1002                value,
1003                parse_result,
1004            } => self.alloc_expression_node(ExpressionInteger::new(location, value, parse_result)),
1005            ExpressionKind::Nil => {
1006                self.alloc_expression_node(ExpressionUnit::new(ExpressionTag::Nil, location))
1007            }
1008            ExpressionKind::Number {
1009                value,
1010                parse_result,
1011            } => self.alloc_expression_node(ExpressionNumber::new(location, value, parse_result)),
1012            ExpressionKind::String { value, quote_style } => {
1013                self.alloc_expression_node(ExpressionString::new(location, value, quote_style))
1014            }
1015            ExpressionKind::InterpString {
1016                strings,
1017                expressions,
1018            } => self.alloc_expression_node(ExpressionInterpString::new(
1019                location,
1020                strings,
1021                expressions,
1022            )),
1023            ExpressionKind::Table { items } => {
1024                self.alloc_expression_node(ExpressionTable::new(location, items))
1025            }
1026            ExpressionKind::If {
1027                condition,
1028                has_then,
1029                then_expression,
1030                has_else,
1031                else_expression,
1032            } => self.alloc_expression_node(ExpressionIf::new(
1033                location,
1034                condition,
1035                has_then,
1036                then_expression,
1037                has_else,
1038                else_expression,
1039            )),
1040            ExpressionKind::Varargs => {
1041                self.alloc_expression_node(ExpressionUnit::new(ExpressionTag::Varargs, location))
1042            }
1043            ExpressionKind::IndexExpr { expr, index } => {
1044                self.alloc_expression_node(ExpressionIndexExpr::new(location, expr, index))
1045            }
1046            ExpressionKind::IndexName {
1047                expr,
1048                index,
1049                index_location,
1050                op_position,
1051                op,
1052            } => self.alloc_expression_node(ExpressionIndexName::new(
1053                location,
1054                expr,
1055                index,
1056                index_location,
1057                op_position,
1058                op,
1059            )),
1060            ExpressionKind::TypeAssertion { expr, annotation } => {
1061                self.alloc_expression_node(ExpressionTypeAssertion::new(location, expr, annotation))
1062            }
1063            ExpressionKind::Instantiate { expr, type_args } => {
1064                self.alloc_expression_node(ExpressionInstantiate::new(location, expr, type_args))
1065            }
1066            ExpressionKind::Unary { op, rhs } => {
1067                self.alloc_expression_node(ExpressionUnary::new(location, op, rhs))
1068            }
1069            ExpressionKind::Local { local, upvalue } => {
1070                self.alloc_expression_node(ExpressionLocal::new(location, local, upvalue))
1071            }
1072            ExpressionKind::Global(name) => {
1073                self.alloc_expression_node(ExpressionGlobal::new(location, name))
1074            }
1075            ExpressionKind::Binary { lhs, op, rhs } => {
1076                self.alloc_expression_node(ExpressionBinary::new(location, lhs, op, rhs))
1077            }
1078            ExpressionKind::Error {
1079                expressions,
1080                message_index,
1081            } => self.alloc_expression_node(ExpressionError::new(
1082                location,
1083                expressions,
1084                message_index,
1085            )),
1086        }
1087    }
1088}