go_parser/
ast.rs

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