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#[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>), 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>, 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#[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#[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#[derive(Debug)]
601pub struct Ellipsis {
602 pub pos: position::Pos,
603 pub elt: Option<Expr>, }
605
606#[derive(Debug)]
608pub struct BasicLit {
609 pub pos: position::Pos,
610 pub token: token::Token,
611}
612
613#[derive(Debug)]
615pub struct FuncLit {
616 pub typ: FuncTypeKey,
617 pub body: Rc<BlockStmt>,
618}
619
620#[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#[derive(Debug)]
632pub struct ParenExpr {
633 pub l_paren: position::Pos,
634 pub expr: Expr,
635 pub r_paren: position::Pos,
636}
637#[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#[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#[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#[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#[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#[derive(Debug)]
700pub struct StarExpr {
701 pub star: position::Pos,
702 pub expr: Expr,
703}
704
705#[derive(Debug)]
708pub struct UnaryExpr {
709 pub op_pos: position::Pos,
710 pub op: token::Token,
711 pub expr: Expr,
712}
713
714#[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#[derive(Debug)]
726pub struct KeyValueExpr {
727 pub key: Expr,
728 pub colon: position::Pos,
729 pub val: Expr,
730}
731
732#[derive(Debug)]
734pub struct ArrayType {
735 pub l_brack: position::Pos,
736 pub len: Option<Expr>, pub elt: Expr,
738}
739
740#[derive(Debug)]
742pub struct StructType {
743 pub struct_pos: position::Pos,
744 pub fields: FieldList,
745 pub incomplete: bool,
746}
747
748#[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#[derive(Clone, Debug)]
796pub struct InterfaceType {
797 pub interface: position::Pos,
798 pub methods: FieldList,
799 pub incomplete: bool,
800}
801
802#[derive(Debug)]
804pub struct MapType {
805 pub map: position::Pos,
806 pub key: Expr,
807 pub val: Expr,
808}
809
810#[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#[derive(Debug)]
828pub struct ImportSpec {
829 pub name: Option<IdentKey>,
830 pub path: BasicLit,
831 pub end_pos: Option<position::Pos>,
832}
833
834#[derive(Debug)]
837pub struct ValueSpec {
838 pub names: Vec<IdentKey>,
839 pub typ: Option<Expr>,
840 pub values: Vec<Expr>,
841}
842
843#[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#[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#[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#[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#[derive(Debug)]
933pub struct SendStmt {
934 pub chan: Expr,
935 pub arrow: position::Pos,
936 pub val: Expr,
937}
938
939#[derive(Debug)]
941pub struct IncDecStmt {
942 pub expr: Expr,
943 pub token_pos: position::Pos,
944 pub token: token::Token,
945}
946
947#[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#[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#[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#[derive(Debug)]
1066pub struct CommClause {
1067 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}