goscript_parser/
ast.rs

1use super::objects::*;
2use super::position;
3use super::scope;
4use super::token;
5use std::collections::HashMap;
6use std::hash::Hash;
7use std::rc::Rc;
8
9/// NodeId can be used as key of HashMaps
10#[derive(PartialEq, Eq, Hash, Clone, Debug)]
11pub enum NodeId {
12    Address(usize),
13    IdentExpr(IdentKey),
14    FuncTypeExpr(FuncTypeKey),
15    LabeledStmt(LabeledStmtKey),
16    AssignStmt(AssignStmtKey),
17    FuncDecl(FuncDeclKey),
18    FuncType(FuncTypeKey),
19    Field(FieldKey),
20    File(IdentKey),
21}
22
23pub trait Node {
24    fn pos(&self, arena: &Objects) -> position::Pos;
25
26    fn end(&self, arena: &Objects) -> position::Pos;
27
28    fn id(&self) -> NodeId;
29}
30
31#[derive(Clone, Debug)]
32pub enum Expr {
33    Bad(Rc<BadExpr>),
34    Ident(IdentKey),
35    Ellipsis(Rc<Ellipsis>),
36    BasicLit(Rc<BasicLit>),
37    FuncLit(Rc<FuncLit>),
38    CompositeLit(Rc<CompositeLit>),
39    Paren(Rc<ParenExpr>),
40    Selector(Rc<SelectorExpr>),
41    Index(Rc<IndexExpr>),
42    Slice(Rc<SliceExpr>),
43    TypeAssert(Rc<TypeAssertExpr>),
44    Call(Rc<CallExpr>),
45    Star(Rc<StarExpr>),
46    Unary(Rc<UnaryExpr>),
47    Binary(Rc<BinaryExpr>),
48    KeyValue(Rc<KeyValueExpr>),
49    Array(Rc<ArrayType>),
50    Struct(Rc<StructType>),
51    Func(FuncTypeKey),
52    Interface(Rc<InterfaceType>),
53    Map(Rc<MapType>),
54    Chan(Rc<ChanType>),
55}
56
57#[derive(Debug, Clone)]
58pub enum Stmt {
59    Bad(Rc<BadStmt>),
60    Decl(Rc<Decl>),
61    Empty(Rc<EmptyStmt>),
62    Labeled(LabeledStmtKey),
63    Expr(Box<Expr>), // Doesn't need to be Rc since Expr is Rc
64    Send(Rc<SendStmt>),
65    IncDec(Rc<IncDecStmt>),
66    Assign(AssignStmtKey),
67    Go(Rc<GoStmt>),
68    Defer(Rc<DeferStmt>),
69    Return(Rc<ReturnStmt>),
70    Branch(Rc<BranchStmt>),
71    Block(Rc<BlockStmt>),
72    If(Rc<IfStmt>),
73    Case(Rc<CaseClause>),
74    Switch(Rc<SwitchStmt>),
75    TypeSwitch(Rc<TypeSwitchStmt>),
76    Comm(Rc<CommClause>),
77    Select(Rc<SelectStmt>),
78    For(Rc<ForStmt>),
79    Range(Rc<RangeStmt>),
80}
81
82#[derive(Clone, Debug)]
83pub enum Spec {
84    Import(Rc<ImportSpec>),
85    Value(Rc<ValueSpec>),
86    Type(Rc<TypeSpec>),
87}
88
89#[derive(Clone, Debug)]
90pub enum Decl {
91    Bad(Rc<BadDecl>),
92    Gen(Rc<GenDecl>),
93    Func(FuncDeclKey),
94}
95
96impl Expr {
97    pub fn new_bad(from: position::Pos, to: position::Pos) -> Expr {
98        Expr::Bad(Rc::new(BadExpr { from: from, to: to }))
99    }
100
101    pub fn new_selector(x: Expr, sel: IdentKey) -> Expr {
102        Expr::Selector(Rc::new(SelectorExpr { expr: x, sel: sel }))
103    }
104
105    pub fn new_ellipsis(pos: position::Pos, x: Option<Expr>) -> Expr {
106        Expr::Ellipsis(Rc::new(Ellipsis { pos: pos, elt: x }))
107    }
108
109    pub fn new_basic_lit(pos: position::Pos, token: token::Token) -> Expr {
110        Expr::BasicLit(Rc::new(BasicLit {
111            pos: pos,
112            token: token,
113        }))
114    }
115
116    pub fn new_unary_expr(pos: position::Pos, op: token::Token, expr: Expr) -> Expr {
117        Expr::Unary(Rc::new(UnaryExpr {
118            op_pos: pos,
119            op: op,
120            expr: expr,
121        }))
122    }
123
124    pub fn box_func_type(ft: FuncType, objs: &mut Objects) -> Expr {
125        Expr::Func(objs.ftypes.insert(ft))
126    }
127
128    pub fn clone_ident(&self) -> Option<Expr> {
129        if let Expr::Ident(i) = self {
130            Some(Expr::Ident(i.clone()))
131        } else {
132            None
133        }
134    }
135
136    pub fn try_as_ident(&self) -> Option<&IdentKey> {
137        if let Expr::Ident(ident) = self {
138            Some(ident)
139        } else {
140            None
141        }
142    }
143
144    pub fn is_bad(&self) -> bool {
145        if let Expr::Bad(_) = self {
146            true
147        } else {
148            false
149        }
150    }
151
152    pub fn is_type_switch_assert(&self) -> bool {
153        if let Expr::TypeAssert(t) = self {
154            t.typ.is_none()
155        } else {
156            false
157        }
158    }
159}
160
161impl Node for Expr {
162    fn pos(&self, arena: &Objects) -> position::Pos {
163        match &self {
164            Expr::Bad(e) => e.from,
165            Expr::Ident(e) => arena.idents[*e].pos,
166            Expr::Ellipsis(e) => e.pos,
167            Expr::BasicLit(e) => e.pos,
168            Expr::FuncLit(e) => {
169                let typ = &arena.ftypes[e.typ];
170                match typ.func {
171                    Some(p) => p,
172                    None => typ.params.pos(arena),
173                }
174            }
175            Expr::CompositeLit(e) => match &e.typ {
176                Some(expr) => expr.pos(arena),
177                None => e.l_brace,
178            },
179            Expr::Paren(e) => e.l_paren,
180            Expr::Selector(e) => e.expr.pos(arena),
181            Expr::Index(e) => e.expr.pos(arena),
182            Expr::Slice(e) => e.expr.pos(arena),
183            Expr::TypeAssert(e) => e.expr.pos(arena),
184            Expr::Call(e) => e.func.pos(arena),
185            Expr::Star(e) => e.star,
186            Expr::Unary(e) => e.op_pos,
187            Expr::Binary(e) => e.expr_a.pos(arena),
188            Expr::KeyValue(e) => e.key.pos(arena),
189            Expr::Array(e) => e.l_brack,
190            Expr::Struct(e) => e.struct_pos,
191            Expr::Func(e) => e.pos(arena),
192            Expr::Interface(e) => e.interface,
193            Expr::Map(e) => e.map,
194            Expr::Chan(e) => e.begin,
195        }
196    }
197
198    fn end(&self, arena: &Objects) -> position::Pos {
199        match &self {
200            Expr::Bad(e) => e.to,
201            Expr::Ident(e) => arena.idents[*e].end(),
202            Expr::Ellipsis(e) => match &e.elt {
203                Some(expr) => expr.end(arena),
204                None => e.pos + 3,
205            },
206            Expr::BasicLit(e) => e.pos + e.token.get_literal().len(),
207            Expr::FuncLit(e) => e.body.end(),
208            Expr::CompositeLit(e) => e.r_brace + 1,
209            Expr::Paren(e) => e.r_paren + 1,
210            Expr::Selector(e) => arena.idents[e.sel].end(),
211            Expr::Index(e) => e.r_brack + 1,
212            Expr::Slice(e) => e.r_brack + 1,
213            Expr::TypeAssert(e) => e.r_paren + 1,
214            Expr::Call(e) => e.r_paren + 1,
215            Expr::Star(e) => e.expr.end(arena),
216            Expr::Unary(e) => e.expr.end(arena),
217            Expr::Binary(e) => e.expr_b.end(arena),
218            Expr::KeyValue(e) => e.val.end(arena),
219            Expr::Array(e) => e.elt.end(arena),
220            Expr::Struct(e) => e.fields.end(arena),
221            Expr::Func(e) => e.end(arena),
222            Expr::Interface(e) => e.methods.end(arena),
223            Expr::Map(e) => e.val.end(arena),
224            Expr::Chan(e) => e.val.end(arena),
225        }
226    }
227
228    fn id(&self) -> NodeId {
229        match &self {
230            Expr::Bad(e) => NodeId::Address(&**e as *const BadExpr as usize),
231            Expr::Ident(e) => NodeId::IdentExpr(*e),
232            Expr::Ellipsis(e) => NodeId::Address(&**e as *const Ellipsis as usize),
233            Expr::BasicLit(e) => NodeId::Address(&**e as *const BasicLit as usize),
234            Expr::FuncLit(e) => NodeId::Address(&**e as *const FuncLit as usize),
235            Expr::CompositeLit(e) => NodeId::Address(&**e as *const CompositeLit as usize),
236            Expr::Paren(e) => NodeId::Address(&**e as *const ParenExpr as usize),
237            Expr::Selector(e) => e.id(),
238            Expr::Index(e) => NodeId::Address(&**e as *const IndexExpr as usize),
239            Expr::Slice(e) => NodeId::Address(&**e as *const SliceExpr as usize),
240            Expr::TypeAssert(e) => NodeId::Address(&**e as *const TypeAssertExpr as usize),
241            Expr::Call(e) => e.id(),
242            Expr::Star(e) => NodeId::Address(&**e as *const StarExpr as usize),
243            Expr::Unary(e) => NodeId::Address(&**e as *const UnaryExpr as usize),
244            Expr::Binary(e) => NodeId::Address(&**e as *const BinaryExpr as usize),
245            Expr::KeyValue(e) => NodeId::Address(&**e as *const KeyValueExpr as usize),
246            Expr::Array(e) => NodeId::Address(&**e as *const ArrayType as usize),
247            Expr::Struct(e) => NodeId::Address(&**e as *const StructType as usize),
248            Expr::Func(e) => NodeId::FuncTypeExpr(*e),
249            Expr::Interface(e) => NodeId::Address(&**e as *const InterfaceType as usize),
250            Expr::Map(e) => NodeId::Address(&**e as *const MapType as usize),
251            Expr::Chan(e) => NodeId::Address(&**e as *const ChanType as usize),
252        }
253    }
254}
255
256impl Stmt {
257    pub fn new_bad(from: position::Pos, to: position::Pos) -> Stmt {
258        Stmt::Bad(Rc::new(BadStmt { from: from, to: to }))
259    }
260
261    pub fn new_assign(
262        arena: &mut Objects,
263        lhs: Vec<Expr>,
264        tpos: position::Pos,
265        tok: token::Token,
266        rhs: Vec<Expr>,
267    ) -> Stmt {
268        Stmt::Assign(AssignStmt::arena_new(arena, lhs, tpos, tok, rhs))
269    }
270
271    pub fn box_block(block: BlockStmt) -> Stmt {
272        Stmt::Block(Rc::new(block))
273    }
274}
275
276impl Node for Stmt {
277    fn pos(&self, arena: &Objects) -> position::Pos {
278        match &self {
279            Stmt::Bad(s) => s.from,
280            Stmt::Decl(d) => d.pos(arena),
281            Stmt::Empty(s) => s.semi,
282            Stmt::Labeled(s) => {
283                let label = arena.l_stmts[*s].label;
284                arena.idents[label].pos
285            }
286            Stmt::Expr(e) => e.pos(arena),
287            Stmt::Send(s) => s.chan.pos(arena),
288            Stmt::IncDec(s) => s.expr.pos(arena),
289            Stmt::Assign(s) => {
290                let assign = &arena.a_stmts[*s];
291                assign.pos(arena)
292            }
293            Stmt::Go(s) => s.go,
294            Stmt::Defer(s) => s.defer,
295            Stmt::Return(s) => s.ret,
296            Stmt::Branch(s) => s.token_pos,
297            Stmt::Block(s) => s.pos(),
298            Stmt::If(s) => s.if_pos,
299            Stmt::Case(s) => s.case,
300            Stmt::Switch(s) => s.switch,
301            Stmt::TypeSwitch(s) => s.switch,
302            Stmt::Comm(s) => s.case,
303            Stmt::Select(s) => s.select,
304            Stmt::For(s) => s.for_pos,
305            Stmt::Range(s) => s.for_pos,
306        }
307    }
308    fn end(&self, arena: &Objects) -> position::Pos {
309        match &self {
310            Stmt::Bad(s) => s.to,
311            Stmt::Decl(d) => d.end(arena),
312            Stmt::Empty(s) => {
313                if s.implicit {
314                    s.semi
315                } else {
316                    s.semi + 1
317                }
318            }
319            Stmt::Labeled(s) => {
320                let ls = &arena.l_stmts[*s];
321                ls.stmt.end(arena)
322            }
323            Stmt::Expr(e) => e.end(arena),
324            Stmt::Send(s) => s.val.end(arena),
325            Stmt::IncDec(s) => s.token_pos + 2,
326            Stmt::Assign(s) => {
327                let assign = &arena.a_stmts[*s];
328                assign.rhs[assign.rhs.len() - 1].end(arena)
329            }
330            Stmt::Go(s) => s.call.end(arena),
331            Stmt::Defer(s) => s.call.end(arena),
332            Stmt::Return(s) => {
333                let n = s.results.len();
334                if n > 0 {
335                    s.results[n - 1].end(arena)
336                } else {
337                    s.ret + 6
338                }
339            }
340            Stmt::Branch(s) => match &s.label {
341                Some(l) => arena.idents[*l].end(),
342                None => s.token_pos + s.token.text().len(),
343            },
344            Stmt::Block(s) => s.end(),
345            Stmt::If(s) => match &s.els {
346                Some(e) => e.end(arena),
347                None => s.body.end(),
348            },
349            Stmt::Case(s) => {
350                let n = s.body.len();
351                if n > 0 {
352                    s.body[n - 1].end(arena)
353                } else {
354                    s.colon + 1
355                }
356            }
357            Stmt::Switch(s) => s.body.end(),
358            Stmt::TypeSwitch(s) => s.body.end(),
359            Stmt::Comm(s) => {
360                let n = s.body.len();
361                if n > 0 {
362                    s.body[n - 1].end(arena)
363                } else {
364                    s.colon + 1
365                }
366            }
367            Stmt::Select(s) => s.body.end(),
368            Stmt::For(s) => s.body.end(),
369            Stmt::Range(s) => s.body.end(),
370        }
371    }
372
373    fn id(&self) -> NodeId {
374        match &self {
375            Stmt::Bad(s) => NodeId::Address(&**s as *const BadStmt as usize),
376            Stmt::Decl(d) => NodeId::Address(&**d as *const Decl as usize),
377            Stmt::Empty(e) => NodeId::Address(&**e as *const EmptyStmt as usize),
378            Stmt::Labeled(s) => NodeId::LabeledStmt(*s),
379            Stmt::Expr(e) => NodeId::Address(&**e as *const Expr as usize),
380            Stmt::Send(s) => NodeId::Address(&**s as *const SendStmt as usize),
381            Stmt::IncDec(s) => NodeId::Address(&**s as *const IncDecStmt as usize),
382            Stmt::Assign(s) => NodeId::AssignStmt(*s),
383            Stmt::Go(s) => NodeId::Address(&**s as *const GoStmt as usize),
384            Stmt::Defer(s) => NodeId::Address(&**s as *const DeferStmt as usize),
385            Stmt::Return(s) => NodeId::Address(&**s as *const ReturnStmt as usize),
386            Stmt::Branch(s) => NodeId::Address(&**s as *const BranchStmt as usize),
387            Stmt::Block(s) => NodeId::Address(&**s as *const BlockStmt as usize),
388            Stmt::If(s) => NodeId::Address(&**s as *const IfStmt as usize),
389            Stmt::Case(s) => NodeId::Address(&**s as *const CaseClause as usize),
390            Stmt::Switch(s) => NodeId::Address(&**s as *const SwitchStmt as usize),
391            Stmt::TypeSwitch(s) => NodeId::Address(&**s as *const TypeSwitchStmt as usize),
392            Stmt::Comm(s) => NodeId::Address(&**s as *const CommClause as usize),
393            Stmt::Select(s) => NodeId::Address(&**s as *const SelectStmt as usize),
394            Stmt::For(s) => NodeId::Address(&**s as *const ForStmt as usize),
395            Stmt::Range(s) => NodeId::Address(&**s as *const RangeStmt as usize),
396        }
397    }
398}
399
400impl Node for Spec {
401    fn pos(&self, arena: &Objects) -> position::Pos {
402        match &self {
403            Spec::Import(s) => match &s.name {
404                Some(i) => arena.idents[*i].pos,
405                None => s.path.pos,
406            },
407            Spec::Value(s) => arena.idents[s.names[0]].pos,
408            Spec::Type(s) => arena.idents[s.name].pos,
409        }
410    }
411
412    fn end(&self, arena: &Objects) -> position::Pos {
413        match &self {
414            Spec::Import(s) => match s.end_pos {
415                Some(p) => p,
416                None => s.path.pos,
417            },
418            Spec::Value(s) => {
419                let n = s.values.len();
420                if n > 0 {
421                    s.values[n - 1].end(arena)
422                } else {
423                    match &s.typ {
424                        Some(t) => t.end(arena),
425                        None => arena.idents[s.names[s.names.len() - 1]].end(),
426                    }
427                }
428            }
429            Spec::Type(t) => t.typ.end(arena),
430        }
431    }
432
433    fn id(&self) -> NodeId {
434        match &self {
435            Spec::Import(s) => NodeId::Address(&**s as *const ImportSpec as usize),
436            Spec::Value(s) => NodeId::Address(&**s as *const ValueSpec as usize),
437            Spec::Type(s) => NodeId::Address(&**s as *const TypeSpec as usize),
438        }
439    }
440}
441
442impl Node for Decl {
443    fn pos(&self, arena: &Objects) -> position::Pos {
444        match &self {
445            Decl::Bad(d) => d.from,
446            Decl::Gen(d) => d.token_pos,
447            Decl::Func(d) => arena.fdecls[*d].pos(arena),
448        }
449    }
450
451    fn end(&self, arena: &Objects) -> position::Pos {
452        match &self {
453            Decl::Bad(d) => d.to,
454            Decl::Gen(d) => match &d.r_paren {
455                Some(p) => p + 1,
456                None => arena.specs[d.specs[0]].end(arena),
457            },
458            Decl::Func(d) => {
459                let fd = &arena.fdecls[*d];
460                match &fd.body {
461                    Some(b) => b.end(),
462                    None => fd.typ.end(arena),
463                }
464            }
465        }
466    }
467
468    fn id(&self) -> NodeId {
469        match self {
470            Decl::Bad(d) => NodeId::Address(&**d as *const BadDecl as usize),
471            Decl::Gen(d) => NodeId::Address(&**d as *const GenDecl as usize),
472            Decl::Func(d) => NodeId::FuncDecl(*d),
473        }
474    }
475}
476
477#[derive(Debug)]
478pub struct File {
479    pub package: position::Pos,
480    pub name: IdentKey,
481    pub decls: Vec<Decl>,
482    pub scope: ScopeKey,
483    pub imports: Vec<SpecKey>, //ImportSpec
484    pub unresolved: Vec<IdentKey>,
485}
486
487impl Node for File {
488    fn pos(&self, _arena: &Objects) -> position::Pos {
489        self.package
490    }
491
492    fn end(&self, arena: &Objects) -> position::Pos {
493        let n = self.decls.len();
494        if n > 0 {
495            self.decls[n - 1].end(arena)
496        } else {
497            arena.idents[self.name].end()
498        }
499    }
500
501    fn id(&self) -> NodeId {
502        NodeId::File(self.name)
503    }
504}
505
506pub struct Package {
507    name: String,
508    scope: ScopeKey,
509    imports: HashMap<String, EntityKey>,
510    files: HashMap<String, Box<File>>,
511}
512
513// A BadExpr node is a placeholder for expressions containing
514// syntax errors for which no correct expression nodes can be
515// created.
516#[derive(Debug)]
517pub struct BadExpr {
518    pub from: position::Pos,
519    pub to: position::Pos,
520}
521
522#[derive(Debug, Clone)]
523pub enum IdentEntity {
524    NoEntity,
525    Sentinel,
526    Entity(EntityKey),
527}
528
529impl IdentEntity {
530    pub fn is_none(&self) -> bool {
531        match self {
532            IdentEntity::NoEntity => true,
533            _ => false,
534        }
535    }
536
537    pub fn into_key(self) -> Option<EntityKey> {
538        match self {
539            IdentEntity::Entity(key) => Some(key),
540            _ => None,
541        }
542    }
543}
544
545pub fn is_exported(s: &str) -> bool {
546    s.chars().next().unwrap().is_uppercase()
547}
548
549// An Ident node represents an identifier.
550#[derive(Debug, Clone)]
551pub struct Ident {
552    pub pos: position::Pos,
553    pub name: String,
554    pub entity: IdentEntity,
555}
556
557impl Ident {
558    pub fn blank(pos: position::Pos) -> Ident {
559        Ident::with_str(pos, "_")
560    }
561
562    pub fn true_(pos: position::Pos) -> Ident {
563        Ident::with_str(pos, "true")
564    }
565
566    pub fn with_str(pos: position::Pos, s: &str) -> Ident {
567        Ident {
568            pos: pos,
569            name: s.to_owned(),
570            entity: IdentEntity::NoEntity,
571        }
572    }
573
574    pub fn end(&self) -> position::Pos {
575        self.pos + self.name.len()
576    }
577
578    pub fn entity_key(&self) -> Option<EntityKey> {
579        self.entity.clone().into_key()
580    }
581
582    pub fn entity_obj<'a>(&self, arena: &'a Objects) -> Option<&'a scope::Entity> {
583        match self.entity {
584            IdentEntity::Entity(i) => Some(&arena.entities[i]),
585            _ => None,
586        }
587    }
588
589    pub fn is_blank(&self) -> bool {
590        &self.name == "_"
591    }
592
593    pub fn is_exported(&self) -> bool {
594        is_exported(&self.name)
595    }
596}
597
598// An Ellipsis node stands for the "..." type in a
599// parameter list or the "..." length in an array type.
600#[derive(Debug)]
601pub struct Ellipsis {
602    pub pos: position::Pos,
603    pub elt: Option<Expr>, // ellipsis element type (parameter lists only)
604}
605
606// A BasicLit node represents a literal of basic type.
607#[derive(Debug)]
608pub struct BasicLit {
609    pub pos: position::Pos,
610    pub token: token::Token,
611}
612
613// A FuncLit node represents a function literal.
614#[derive(Debug)]
615pub struct FuncLit {
616    pub typ: FuncTypeKey,
617    pub body: Rc<BlockStmt>,
618}
619
620// A CompositeLit node represents a composite literal.
621#[derive(Debug)]
622pub struct CompositeLit {
623    pub typ: Option<Expr>,
624    pub l_brace: position::Pos,
625    pub elts: Vec<Expr>,
626    pub r_brace: position::Pos,
627    pub incomplete: bool,
628}
629
630// A ParenExpr node represents a parenthesized expression.
631#[derive(Debug)]
632pub struct ParenExpr {
633    pub l_paren: position::Pos,
634    pub expr: Expr,
635    pub r_paren: position::Pos,
636}
637// A SelectorExpr node represents an expression followed by a selector.
638#[derive(Debug)]
639pub struct SelectorExpr {
640    pub expr: Expr,
641    pub sel: IdentKey,
642}
643
644impl SelectorExpr {
645    pub fn id(&self) -> NodeId {
646        NodeId::Address(self as *const SelectorExpr as usize)
647    }
648}
649
650// An IndexExpr node represents an expression followed by an index.
651#[derive(Debug)]
652pub struct IndexExpr {
653    pub expr: Expr,
654    pub l_brack: position::Pos,
655    pub index: Expr,
656    pub r_brack: position::Pos,
657}
658
659// An SliceExpr node represents an expression followed by slice indices.
660#[derive(Debug)]
661pub struct SliceExpr {
662    pub expr: Expr,
663    pub l_brack: position::Pos,
664    pub low: Option<Expr>,
665    pub high: Option<Expr>,
666    pub max: Option<Expr>,
667    pub slice3: bool,
668    pub r_brack: position::Pos,
669}
670
671// A TypeAssertExpr node represents an expression followed by a
672// type assertion.
673#[derive(Debug)]
674pub struct TypeAssertExpr {
675    pub expr: Expr,
676    pub l_paren: position::Pos,
677    pub typ: Option<Expr>,
678    pub r_paren: position::Pos,
679}
680
681// A CallExpr node represents an expression followed by an argument list.
682#[derive(Debug)]
683pub struct CallExpr {
684    pub func: Expr,
685    pub l_paren: position::Pos,
686    pub args: Vec<Expr>,
687    pub ellipsis: Option<position::Pos>,
688    pub r_paren: position::Pos,
689}
690
691impl CallExpr {
692    pub fn id(&self) -> NodeId {
693        NodeId::Address(self as *const CallExpr as usize)
694    }
695}
696
697// A StarExpr node represents an expression of the form "*" Expression.
698// Semantically it could be a unary "*" expression, or a pointer type.
699#[derive(Debug)]
700pub struct StarExpr {
701    pub star: position::Pos,
702    pub expr: Expr,
703}
704
705// A UnaryExpr node represents a unary expression.
706// Unary "*" expressions are represented via StarExpr nodes.
707#[derive(Debug)]
708pub struct UnaryExpr {
709    pub op_pos: position::Pos,
710    pub op: token::Token,
711    pub expr: Expr,
712}
713
714// A BinaryExpr node represents a binary expression.
715#[derive(Debug)]
716pub struct BinaryExpr {
717    pub expr_a: Expr,
718    pub op_pos: position::Pos,
719    pub op: token::Token,
720    pub expr_b: Expr,
721}
722
723// A KeyValueExpr node represents (key : value) pairs
724// in composite literals.
725#[derive(Debug)]
726pub struct KeyValueExpr {
727    pub key: Expr,
728    pub colon: position::Pos,
729    pub val: Expr,
730}
731
732// An ArrayType node represents an array or slice type.
733#[derive(Debug)]
734pub struct ArrayType {
735    pub l_brack: position::Pos,
736    pub len: Option<Expr>, // Ellipsis node for [...]T array types, None for slice types
737    pub elt: Expr,
738}
739
740// A StructType node represents a struct type.
741#[derive(Debug)]
742pub struct StructType {
743    pub struct_pos: position::Pos,
744    pub fields: FieldList,
745    pub incomplete: bool,
746}
747
748// Pointer types are represented via StarExpr nodes.
749
750// A FuncType node represents a function type.
751#[derive(Clone, Debug)]
752pub struct FuncType {
753    pub func: Option<position::Pos>,
754    pub params: FieldList,
755    pub results: Option<FieldList>,
756}
757
758impl FuncType {
759    pub fn new(
760        func: Option<position::Pos>,
761        params: FieldList,
762        results: Option<FieldList>,
763    ) -> FuncType {
764        FuncType {
765            func: func,
766            params: params,
767            results: results,
768        }
769    }
770}
771
772impl Node for FuncTypeKey {
773    fn pos(&self, arena: &Objects) -> position::Pos {
774        let self_ = &arena.ftypes[*self];
775        match self_.func {
776            Some(p) => p,
777            None => self_.params.pos(arena),
778        }
779    }
780
781    fn end(&self, arena: &Objects) -> position::Pos {
782        let self_ = &arena.ftypes[*self];
783        match &self_.results {
784            Some(r) => (*r).end(arena),
785            None => self_.params.end(arena),
786        }
787    }
788
789    fn id(&self) -> NodeId {
790        NodeId::FuncType(*self)
791    }
792}
793
794// An InterfaceType node represents an interface type.
795#[derive(Clone, Debug)]
796pub struct InterfaceType {
797    pub interface: position::Pos,
798    pub methods: FieldList,
799    pub incomplete: bool,
800}
801
802// A MapType node represents a map type.
803#[derive(Debug)]
804pub struct MapType {
805    pub map: position::Pos,
806    pub key: Expr,
807    pub val: Expr,
808}
809
810// A ChanType node represents a channel type.
811#[derive(Hash, Eq, PartialEq, Clone, Debug)]
812pub enum ChanDir {
813    Send = 1,
814    Recv = 2,
815    SendRecv = 3,
816}
817
818#[derive(Clone, Debug)]
819pub struct ChanType {
820    pub begin: position::Pos,
821    pub arrow: position::Pos,
822    pub dir: ChanDir,
823    pub val: Expr,
824}
825
826// An ImportSpec node represents a single package import.
827#[derive(Debug)]
828pub struct ImportSpec {
829    pub name: Option<IdentKey>,
830    pub path: BasicLit,
831    pub end_pos: Option<position::Pos>,
832}
833
834// A ValueSpec node represents a constant or variable declaration
835// (ConstSpec or VarSpec production).
836#[derive(Debug)]
837pub struct ValueSpec {
838    pub names: Vec<IdentKey>,
839    pub typ: Option<Expr>,
840    pub values: Vec<Expr>,
841}
842
843// A TypeSpec node represents a type declaration (TypeSpec production).
844#[derive(Debug)]
845pub struct TypeSpec {
846    pub name: IdentKey,
847    pub assign: position::Pos,
848    pub typ: Expr,
849}
850
851#[derive(Debug)]
852pub struct BadDecl {
853    pub from: position::Pos,
854    pub to: position::Pos,
855}
856
857// A GenDecl node (generic declaration node) represents an import,
858// constant, type or variable declaration. A valid Lparen position
859// (Lparen.IsValid()) indicates a parenthesized declaration.
860//
861// Relationship between Tok value and Specs element type:
862//
863//	Token::IMPORT  ImportSpec
864//	Token::CONST   ValueSpec
865//	Token::TYPE    TypeSpec
866//	Token::VAR     ValueSpec
867#[derive(Debug)]
868pub struct GenDecl {
869    pub token_pos: position::Pos,
870    pub token: token::Token,
871    pub l_paran: Option<position::Pos>,
872    pub specs: Vec<SpecKey>,
873    pub r_paren: Option<position::Pos>,
874}
875
876// A FuncDecl node represents a function declaration.
877#[derive(Debug)]
878pub struct FuncDecl {
879    pub recv: Option<FieldList>,
880    pub name: IdentKey,
881    pub typ: FuncTypeKey,
882    pub body: Option<Rc<BlockStmt>>,
883}
884
885impl FuncDecl {
886    pub fn pos(&self, arena: &Objects) -> position::Pos {
887        self.typ.pos(arena)
888    }
889}
890
891#[derive(Debug)]
892pub struct BadStmt {
893    pub from: position::Pos,
894    pub to: position::Pos,
895}
896
897#[derive(Debug)]
898pub struct EmptyStmt {
899    pub semi: position::Pos,
900    pub implicit: bool,
901}
902
903// A LabeledStmt node represents a labeled statement.
904#[derive(Debug)]
905pub struct LabeledStmt {
906    pub label: IdentKey,
907    pub colon: position::Pos,
908    pub stmt: Stmt,
909}
910
911impl LabeledStmt {
912    pub fn arena_new(
913        arena: &mut Objects,
914        label: IdentKey,
915        colon: position::Pos,
916        stmt: Stmt,
917    ) -> LabeledStmtKey {
918        let l = LabeledStmt {
919            label: label,
920            colon: colon,
921            stmt: stmt,
922        };
923        arena.l_stmts.insert(l)
924    }
925
926    pub fn pos(&self, arena: &Objects) -> position::Pos {
927        arena.idents[self.label].pos
928    }
929}
930
931// A SendStmt node represents a send statement.
932#[derive(Debug)]
933pub struct SendStmt {
934    pub chan: Expr,
935    pub arrow: position::Pos,
936    pub val: Expr,
937}
938
939// An IncDecStmt node represents an increment or decrement statement.
940#[derive(Debug)]
941pub struct IncDecStmt {
942    pub expr: Expr,
943    pub token_pos: position::Pos,
944    pub token: token::Token,
945}
946
947// An AssignStmt node represents an assignment or
948// a short variable declaration.
949#[derive(Debug)]
950pub struct AssignStmt {
951    pub lhs: Vec<Expr>,
952    pub token_pos: position::Pos,
953    pub token: token::Token,
954    pub rhs: Vec<Expr>,
955}
956
957impl AssignStmt {
958    pub fn arena_new(
959        arena: &mut Objects,
960        lhs: Vec<Expr>,
961        tpos: position::Pos,
962        tok: token::Token,
963        rhs: Vec<Expr>,
964    ) -> AssignStmtKey {
965        let ass = AssignStmt {
966            lhs: lhs,
967            token_pos: tpos,
968            token: tok,
969            rhs: rhs,
970        };
971        arena.a_stmts.insert(ass)
972    }
973
974    pub fn pos(&self, arena: &Objects) -> position::Pos {
975        self.lhs[0].pos(arena)
976    }
977}
978
979#[derive(Debug)]
980pub struct GoStmt {
981    pub go: position::Pos,
982    pub call: Expr,
983}
984#[derive(Debug)]
985pub struct DeferStmt {
986    pub defer: position::Pos,
987    pub call: Expr,
988}
989
990#[derive(Debug)]
991pub struct ReturnStmt {
992    pub ret: position::Pos,
993    pub results: Vec<Expr>,
994}
995
996// A BranchStmt node represents a break, continue, goto,
997// or fallthrough statement.
998#[derive(Debug)]
999pub struct BranchStmt {
1000    pub token_pos: position::Pos,
1001    pub token: token::Token,
1002    pub label: Option<IdentKey>,
1003}
1004
1005#[derive(Debug)]
1006pub struct BlockStmt {
1007    pub l_brace: position::Pos,
1008    pub list: Vec<Stmt>,
1009    pub r_brace: position::Pos,
1010}
1011
1012impl BlockStmt {
1013    pub fn new(l: position::Pos, list: Vec<Stmt>, r: position::Pos) -> BlockStmt {
1014        BlockStmt {
1015            l_brace: l,
1016            list: list,
1017            r_brace: r,
1018        }
1019    }
1020
1021    pub fn pos(&self) -> position::Pos {
1022        self.l_brace
1023    }
1024
1025    pub fn end(&self) -> position::Pos {
1026        self.r_brace + 1
1027    }
1028}
1029
1030#[derive(Debug)]
1031pub struct IfStmt {
1032    pub if_pos: position::Pos,
1033    pub init: Option<Stmt>,
1034    pub cond: Expr,
1035    pub body: Rc<BlockStmt>,
1036    pub els: Option<Stmt>,
1037}
1038
1039// A CaseClause represents a case of an expression or type switch statement.
1040#[derive(Debug)]
1041pub struct CaseClause {
1042    pub case: position::Pos,
1043    pub list: Option<Vec<Expr>>,
1044    pub colon: position::Pos,
1045    pub body: Vec<Stmt>,
1046}
1047
1048#[derive(Debug)]
1049pub struct SwitchStmt {
1050    pub switch: position::Pos,
1051    pub init: Option<Stmt>,
1052    pub tag: Option<Expr>,
1053    pub body: Rc<BlockStmt>,
1054}
1055
1056#[derive(Debug)]
1057pub struct TypeSwitchStmt {
1058    pub switch: position::Pos,
1059    pub init: Option<Stmt>,
1060    pub assign: Stmt,
1061    pub body: Rc<BlockStmt>,
1062}
1063
1064// A CommClause node represents a case of a select statement.
1065#[derive(Debug)]
1066pub struct CommClause {
1067    //communication
1068    pub case: position::Pos,
1069    pub comm: Option<Stmt>,
1070    pub colon: position::Pos,
1071    pub body: Vec<Stmt>,
1072}
1073
1074#[derive(Debug)]
1075pub struct SelectStmt {
1076    pub select: position::Pos,
1077    pub body: Rc<BlockStmt>,
1078}
1079
1080#[derive(Debug)]
1081pub struct ForStmt {
1082    pub for_pos: position::Pos,
1083    pub init: Option<Stmt>,
1084    pub cond: Option<Expr>,
1085    pub post: Option<Stmt>,
1086    pub body: Rc<BlockStmt>,
1087}
1088
1089#[derive(Debug)]
1090pub struct RangeStmt {
1091    pub for_pos: position::Pos,
1092    pub key: Option<Expr>,
1093    pub val: Option<Expr>,
1094    pub token_pos: position::Pos,
1095    pub token: token::Token,
1096    pub expr: Expr,
1097    pub body: Rc<BlockStmt>,
1098}
1099
1100#[derive(Debug)]
1101pub struct Field {
1102    pub names: Vec<IdentKey>,
1103    pub typ: Expr,
1104    pub tag: Option<Expr>,
1105}
1106
1107impl Node for FieldKey {
1108    fn pos(&self, arena: &Objects) -> position::Pos {
1109        let self_ = &arena.fields[*self];
1110        if self_.names.len() > 0 {
1111            arena.idents[self_.names[0]].pos
1112        } else {
1113            self_.typ.pos(arena)
1114        }
1115    }
1116
1117    fn end(&self, arena: &Objects) -> position::Pos {
1118        let self_ = &arena.fields[*self];
1119        match &self_.tag {
1120            Some(t) => t.end(arena),
1121            None => self_.typ.end(arena),
1122        }
1123    }
1124
1125    fn id(&self) -> NodeId {
1126        NodeId::Field(*self)
1127    }
1128}
1129
1130#[derive(Clone, Debug)]
1131pub struct FieldList {
1132    pub openning: Option<position::Pos>,
1133    pub list: Vec<FieldKey>,
1134    pub closing: Option<position::Pos>,
1135}
1136
1137impl FieldList {
1138    pub fn new(
1139        openning: Option<position::Pos>,
1140        list: Vec<FieldKey>,
1141        closing: Option<position::Pos>,
1142    ) -> FieldList {
1143        FieldList {
1144            openning: openning,
1145            list: list,
1146            closing: closing,
1147        }
1148    }
1149
1150    pub fn pos(&self, arena: &Objects) -> position::Pos {
1151        match self.openning {
1152            Some(o) => o,
1153            None => self.list[0].pos(arena),
1154        }
1155    }
1156
1157    pub fn end(&self, arena: &Objects) -> position::Pos {
1158        match self.closing {
1159            Some(c) => c,
1160            None => self.list[self.list.len() - 1].pos(arena),
1161        }
1162    }
1163}