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