| ... | ... | @@ -53,6 +53,7 @@ pub const Parser = struct { |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | const TopLevelDeclCtx = struct { |
| 56 | decls: &ArrayList(&ast.Node), |
| 56 | 57 | visib_token: ?Token, |
| 57 | 58 | extern_token: ?Token, |
| 58 | 59 | lib_name: ?&ast.Node, |
| ... | ... | @@ -75,7 +76,6 @@ pub const Parser = struct { |
| 75 | 76 | const ExpectTokenSave = struct { |
| 76 | 77 | id: Token.Id, |
| 77 | 78 | ptr: &Token, |
| 78 | | |
| 79 | 79 | }; |
| 80 | 80 | |
| 81 | 81 | fn ListState(comptime T: type) type { |
| ... | ... | @@ -88,7 +88,7 @@ pub const Parser = struct { |
| 88 | 88 | |
| 89 | 89 | const State = union(enum) { |
| 90 | 90 | TopLevel, |
| 91 | | TopLevelExtern: ?Token, |
| 91 | TopLevelExtern: TopLevelDeclCtx, |
| 92 | 92 | TopLevelDecl: TopLevelDeclCtx, |
| 93 | 93 | Expression: DestPtr, |
| 94 | 94 | ExpectOperand, |
| ... | ... | @@ -182,7 +182,14 @@ pub const Parser = struct { |
| 182 | 182 | const token = self.getNextToken(); |
| 183 | 183 | switch (token.id) { |
| 184 | 184 | Token.Id.Keyword_pub, Token.Id.Keyword_export => { |
| 185 | | stack.append(State { .TopLevelExtern = token }) catch unreachable; |
| 185 | stack.append(State { |
| 186 | .TopLevelExtern = TopLevelDeclCtx { |
| 187 | .decls = &root_node.decls, |
| 188 | .visib_token = token, |
| 189 | .extern_token = null, |
| 190 | .lib_name = null, |
| 191 | } |
| 192 | }) catch unreachable; |
| 186 | 193 | continue; |
| 187 | 194 | }, |
| 188 | 195 | Token.Id.Keyword_test => { |
| ... | ... | @@ -208,12 +215,19 @@ pub const Parser = struct { |
| 208 | 215 | }, |
| 209 | 216 | else => { |
| 210 | 217 | self.putBackToken(token); |
| 211 | | stack.append(State { .TopLevelExtern = null }) catch unreachable; |
| 218 | stack.append(State { |
| 219 | .TopLevelExtern = TopLevelDeclCtx { |
| 220 | .decls = &root_node.decls, |
| 221 | .visib_token = null, |
| 222 | .extern_token = null, |
| 223 | .lib_name = null, |
| 224 | } |
| 225 | }) catch unreachable; |
| 212 | 226 | continue; |
| 213 | 227 | }, |
| 214 | 228 | } |
| 215 | 229 | }, |
| 216 | | State.TopLevelExtern => |visib_token| { |
| 230 | State.TopLevelExtern => |ctx| { |
| 217 | 231 | const token = self.getNextToken(); |
| 218 | 232 | if (token.id == Token.Id.Keyword_extern) { |
| 219 | 233 | const lib_name_token = self.getNextToken(); |
| ... | ... | @@ -229,7 +243,8 @@ pub const Parser = struct { |
| 229 | 243 | |
| 230 | 244 | stack.append(State { |
| 231 | 245 | .TopLevelDecl = TopLevelDeclCtx { |
| 232 | | .visib_token = visib_token, |
| 246 | .decls = ctx.decls, |
| 247 | .visib_token = ctx.visib_token, |
| 233 | 248 | .extern_token = token, |
| 234 | 249 | .lib_name = lib_name, |
| 235 | 250 | }, |
| ... | ... | @@ -237,13 +252,7 @@ pub const Parser = struct { |
| 237 | 252 | continue; |
| 238 | 253 | } |
| 239 | 254 | self.putBackToken(token); |
| 240 | | stack.append(State { |
| 241 | | .TopLevelDecl = TopLevelDeclCtx { |
| 242 | | .visib_token = visib_token, |
| 243 | | .extern_token = null, |
| 244 | | .lib_name = null, |
| 245 | | }, |
| 246 | | }) catch unreachable; |
| 255 | stack.append(State { .TopLevelDecl = ctx }) catch unreachable; |
| 247 | 256 | continue; |
| 248 | 257 | }, |
| 249 | 258 | State.TopLevelDecl => |ctx| { |
| ... | ... | @@ -252,7 +261,7 @@ pub const Parser = struct { |
| 252 | 261 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 253 | 262 | stack.append(State.TopLevel) catch unreachable; |
| 254 | 263 | // TODO shouldn't need these casts |
| 255 | | const var_decl_node = try self.createAttachVarDecl(arena, &root_node.decls, ctx.visib_token, |
| 264 | const var_decl_node = try self.createAttachVarDecl(arena, ctx.decls, ctx.visib_token, |
| 256 | 265 | token, (?Token)(null), ctx.extern_token, ctx.lib_name); |
| 257 | 266 | try stack.append(State { .VarDecl = var_decl_node }); |
| 258 | 267 | continue; |
| ... | ... | @@ -260,7 +269,7 @@ pub const Parser = struct { |
| 260 | 269 | Token.Id.Keyword_fn => { |
| 261 | 270 | stack.append(State.TopLevel) catch unreachable; |
| 262 | 271 | // TODO shouldn't need these casts |
| 263 | | const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, token, |
| 272 | const fn_proto = try self.createAttachFnProto(arena, ctx.decls, token, |
| 264 | 273 | ctx.extern_token, ctx.lib_name, (?Token)(null), ctx.visib_token, (?Token)(null)); |
| 265 | 274 | try stack.append(State { .FnDef = fn_proto }); |
| 266 | 275 | try stack.append(State { .FnProto = fn_proto }); |
| ... | ... | @@ -270,7 +279,7 @@ pub const Parser = struct { |
| 270 | 279 | stack.append(State.TopLevel) catch unreachable; |
| 271 | 280 | const fn_token = try self.eatToken(Token.Id.Keyword_fn); |
| 272 | 281 | // TODO shouldn't need this cast |
| 273 | | const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, fn_token, |
| 282 | const fn_proto = try self.createAttachFnProto(arena, ctx.decls, fn_token, |
| 274 | 283 | ctx.extern_token, ctx.lib_name, (?Token)(token), (?Token)(null), (?Token)(null)); |
| 275 | 284 | try stack.append(State { .FnDef = fn_proto }); |
| 276 | 285 | try stack.append(State { .FnProto = fn_proto }); |