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}