1use super::objects::*;
13use super::position;
14use super::scope;
15use super::token;
16use std::hash::Hash;
17use std::rc::Rc;
18
19#[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>), 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>, 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#[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#[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#[derive(Debug)]
600pub struct Ellipsis {
601 pub pos: position::Pos,
602 pub elt: Option<Expr>, }
604
605#[derive(Debug)]
607pub struct BasicLit {
608 pub pos: position::Pos,
609 pub token: token::Token,
610}
611
612#[derive(Debug)]
614pub struct FuncLit {
615 pub typ: FuncTypeKey,
616 pub body: Rc<BlockStmt>,
617}
618
619#[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#[derive(Debug)]
631pub struct ParenExpr {
632 pub l_paren: position::Pos,
633 pub expr: Expr,
634 pub r_paren: position::Pos,
635}
636#[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#[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#[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#[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#[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#[derive(Debug)]
699pub struct StarExpr {
700 pub star: position::Pos,
701 pub expr: Expr,
702}
703
704#[derive(Debug)]
707pub struct UnaryExpr {
708 pub op_pos: position::Pos,
709 pub op: token::Token,
710 pub expr: Expr,
711}
712
713#[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#[derive(Debug)]
725pub struct KeyValueExpr {
726 pub key: Expr,
727 pub colon: position::Pos,
728 pub val: Expr,
729}
730
731#[derive(Debug)]
733pub struct ArrayType {
734 pub l_brack: position::Pos,
735 pub len: Option<Expr>, pub elt: Expr,
737}
738
739#[derive(Debug)]
741pub struct StructType {
742 pub struct_pos: position::Pos,
743 pub fields: FieldList,
744 pub incomplete: bool,
745}
746
747#[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#[derive(Clone, Debug)]
795pub struct InterfaceType {
796 pub interface: position::Pos,
797 pub methods: FieldList,
798 pub incomplete: bool,
799}
800
801#[derive(Debug)]
803pub struct MapType {
804 pub map: position::Pos,
805 pub key: Expr,
806 pub val: Expr,
807}
808
809#[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#[derive(Debug)]
827pub struct ImportSpec {
828 pub name: Option<IdentKey>,
829 pub path: BasicLit,
830 pub end_pos: Option<position::Pos>,
831}
832
833#[derive(Debug)]
836pub struct ValueSpec {
837 pub names: Vec<IdentKey>,
838 pub typ: Option<Expr>,
839 pub values: Vec<Expr>,
840}
841
842#[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#[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#[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#[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#[derive(Debug)]
932pub struct SendStmt {
933 pub chan: Expr,
934 pub arrow: position::Pos,
935 pub val: Expr,
936}
937
938#[derive(Debug)]
940pub struct IncDecStmt {
941 pub expr: Expr,
942 pub token_pos: position::Pos,
943 pub token: token::Token,
944}
945
946#[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#[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#[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#[derive(Debug)]
1065pub struct CommClause {
1066 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}