| ... | ... | @@ -11,6 +11,7 @@ pub const Node = struct { |
| 11 | 11 | pub const Id = enum { |
| 12 | 12 | Root, |
| 13 | 13 | VarDecl, |
| 14 | ContainerDecl, |
| 14 | 15 | Identifier, |
| 15 | 16 | FnProto, |
| 16 | 17 | ParamDecl, |
| ... | ... | @@ -40,6 +41,7 @@ pub const Node = struct { |
| 40 | 41 | return switch (base.id) { |
| 41 | 42 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index), |
| 42 | 43 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index), |
| 44 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index), |
| 43 | 45 | Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index), |
| 44 | 46 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index), |
| 45 | 47 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index), |
| ... | ... | @@ -70,6 +72,7 @@ pub const Node = struct { |
| 70 | 72 | return switch (base.id) { |
| 71 | 73 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(), |
| 72 | 74 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(), |
| 75 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(), |
| 73 | 76 | Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(), |
| 74 | 77 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(), |
| 75 | 78 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(), |
| ... | ... | @@ -100,6 +103,7 @@ pub const Node = struct { |
| 100 | 103 | return switch (base.id) { |
| 101 | 104 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(), |
| 102 | 105 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(), |
| 106 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(), |
| 103 | 107 | Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(), |
| 104 | 108 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(), |
| 105 | 109 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(), |
| ... | ... | @@ -196,6 +200,69 @@ pub const NodeVarDecl = struct { |
| 196 | 200 | } |
| 197 | 201 | }; |
| 198 | 202 | |
| 203 | pub const NodeContainerDecl = struct { |
| 204 | base: Node, |
| 205 | kind_token: Token, |
| 206 | init_arg_expr: InitArg, |
| 207 | kind: Kind, |
| 208 | decls: ArrayList(&Node), |
| 209 | rbrace_token: Token, |
| 210 | |
| 211 | // TODO: Different array lists for each kind. |
| 212 | const Kind = union(enum) { |
| 213 | Struct: ArrayList(&Node), |
| 214 | Enum: ArrayList(&Node), |
| 215 | Union: ArrayList(&Node), |
| 216 | }; |
| 217 | |
| 218 | const InitArg = union(enum) { |
| 219 | None, |
| 220 | Enum, |
| 221 | Type: &Node, |
| 222 | }; |
| 223 | |
| 224 | pub fn iterate(self: &NodeContainerDecl, index: usize) ?&Node { |
| 225 | var i = index; |
| 226 | |
| 227 | switch (self.init_arg_expr) { |
| 228 | InitArg.Type => |t| { |
| 229 | if (i < 1) return t; |
| 230 | i -= 1; |
| 231 | }, |
| 232 | InitArg.None, |
| 233 | InitArg.Enum => { } |
| 234 | } |
| 235 | |
| 236 | if (i < self.decls.len) return self.decls.at(i); |
| 237 | i -= self.decls.len; |
| 238 | |
| 239 | switch (self.kind) { |
| 240 | Kind.Struct => |fields| { |
| 241 | if (i < fields.len) return fields.at(i); |
| 242 | i -= fields.len; |
| 243 | }, |
| 244 | Kind.Enum => |tags| { |
| 245 | if (i < tags.len) return tags.at(i); |
| 246 | i -= tags.len; |
| 247 | }, |
| 248 | Kind.Union => |tags| { |
| 249 | if (i < tags.len) return tags.at(i); |
| 250 | i -= tags.len; |
| 251 | }, |
| 252 | } |
| 253 | |
| 254 | return null; |
| 255 | } |
| 256 | |
| 257 | pub fn firstToken(self: &NodeContainerDecl) Token { |
| 258 | return self.kind_token; |
| 259 | } |
| 260 | |
| 261 | pub fn lastToken(self: &NodeContainerDecl) Token { |
| 262 | return self.rbrace_token; |
| 263 | } |
| 264 | }; |
| 265 | |
| 199 | 266 | pub const NodeIdentifier = struct { |
| 200 | 267 | base: Node, |
| 201 | 268 | name_token: Token, |
| ... | ... | @@ -611,7 +678,7 @@ pub const NodeSuffixOp = struct { |
| 611 | 678 | i -= exprs.len; |
| 612 | 679 | }, |
| 613 | 680 | SuffixOp.StructInitializer => |fields| { |
| 614 | | if (i < fields.len) return fields.at(i); |
| 681 | if (i < fields.len) return &fields.at(i).base; |
| 615 | 682 | i -= fields.len; |
| 616 | 683 | }, |
| 617 | 684 | } |