| ... | @@ -75,9 +75,12 @@ pub fn parse(allocator: *Allocator, source: []const u8, options: Options) !*Tree | ... | @@ -75,9 +75,12 @@ pub fn parse(allocator: *Allocator, source: []const u8, options: Options) !*Tree |
| 75 | } | 75 | } |
| 76 | } | 76 | } |
| 77 | | 77 | |
| | 78 | var parse_arena = std.heap.ArenaAllocator.init(allocator); |
| | 79 | defer parse_arena.deinit(); |
| | 80 | |
| 78 | var parser = Parser{ | 81 | var parser = Parser{ |
| 79 | .symbols = Parser.SymbolList.init(allocator), | 82 | .scopes = Parser.SymbolList.init(allocator), |
| 80 | .arena = arena, | 83 | .arena = &parse_arena.allocator, |
| 81 | .it = &it, | 84 | .it = &it, |
| 82 | .tree = tree, | 85 | .tree = tree, |
| 83 | .options = options, | 86 | .options = options, |
| ... | @@ -93,11 +96,17 @@ const Parser = struct { | ... | @@ -93,11 +96,17 @@ const Parser = struct { |
| 93 | it: *TokenIterator, | 96 | it: *TokenIterator, |
| 94 | tree: *Tree, | 97 | tree: *Tree, |
| 95 | | 98 | |
| 96 | /// only used for scopes | 99 | arena: *Allocator, |
| 97 | symbols: SymbolList, | 100 | scopes: ScopeList, |
| 98 | options: Options, | 101 | options: Options, |
| 99 | | 102 | |
| 100 | const SymbolList = std.ArrayList(Symbol); | 103 | const ScopeList = std.SegmentedLists(Scope); |
| | 104 | const SymbolList = std.SegmentedLists(Symbol); |
| | 105 | |
| | 106 | const Scope = struct { |
| | 107 | kind: ScopeKind, |
| | 108 | syms: SymbolList, |
| | 109 | }; |
| 101 | | 110 | |
| 102 | const Symbol = struct { | 111 | const Symbol = struct { |
| 103 | name: []const u8, | 112 | name: []const u8, |
| ... | @@ -111,21 +120,27 @@ const Parser = struct { | ... | @@ -111,21 +120,27 @@ const Parser = struct { |
| 111 | Switch, | 120 | Switch, |
| 112 | }; | 121 | }; |
| 113 | | 122 | |
| 114 | fn pushScope(parser: *Parser, kind: ScopeKind) usize { | 123 | fn pushScope(parser: *Parser, kind: ScopeKind) !void { |
| 115 | return parser.symbols.len; | 124 | const new = try parser.scopes.addOne(); |
| | 125 | new.* = .{ |
| | 126 | .kind = kind, |
| | 127 | .syms = SymbolList.init(parser.arena), |
| | 128 | }; |
| 116 | } | 129 | } |
| 117 | | 130 | |
| 118 | fn popScope(parser: *Parser, len: usize) void { | 131 | fn popScope(parser: *Parser, len: usize) void { |
| 119 | parser.symbols.resize(len) catch unreachable; | 132 | _ = parser.scopes.pop(); |
| 120 | } | 133 | } |
| 121 | | 134 | |
| 122 | fn getSymbol(parser: *Parser, tok: TokenIndex) ?*Type { | 135 | fn getSymbol(parser: *Parser, tok: TokenIndex) ?*Symbol { |
| 123 | const name = parser.tree.tokenSlice(tok); | 136 | const name = parser.tree.tokenSlice(tok); |
| 124 | const syms = parser.symbols.toSliceConst(); | 137 | var scope_it = parser.scopes.iterator(parser.scopes.len); |
| 125 | var i = syms.len; | 138 | while (scope_it.prev()) |scope| { |
| 126 | while (i > 0) : (i -= 1) { | 139 | var sym_it = scope.syms.iterator(scope.syms.len); |
| 127 | if (mem.eql(u8, name, syms[i].name)) { | 140 | while (sym_it.prev()) |sym| { |
| 128 | return syms[i].ty; | 141 | if (mem.eql(u8, sym.name, name)) { |
| | 142 | return sym; |
| | 143 | } |
| 129 | } | 144 | } |
| 130 | } | 145 | } |
| 131 | return null; | 146 | return null; |
| ... | @@ -137,8 +152,8 @@ const Parser = struct { | ... | @@ -137,8 +152,8 @@ const Parser = struct { |
| 137 | | 152 | |
| 138 | /// Root <- ExternalDeclaration* eof | 153 | /// Root <- ExternalDeclaration* eof |
| 139 | fn root(parser: *Parser) Allocator.Error!*Node.Root { | 154 | fn root(parser: *Parser) Allocator.Error!*Node.Root { |
| 140 | const scope = parser.pushScope(.Root); | 155 | try parser.pushScope(.Root); |
| 141 | defer parser.popScope(scope); | 156 | defer parser.popScope(); |
| 142 | const node = try parser.arena.create(Node.Root); | 157 | const node = try parser.arena.create(Node.Root); |
| 143 | node.* = .{ | 158 | node.* = .{ |
| 144 | .decls = Node.Root.DeclList.init(parser.arena), | 159 | .decls = Node.Root.DeclList.init(parser.arena), |
| ... | @@ -782,8 +797,8 @@ const Parser = struct { | ... | @@ -782,8 +797,8 @@ const Parser = struct { |
| 782 | .ty = ty, | 797 | .ty = ty, |
| 783 | }); | 798 | }); |
| 784 | if (parser.eatToken(.LBrace)) |lbrace| { | 799 | if (parser.eatToken(.LBrace)) |lbrace| { |
| 785 | const scope = parser.pushScope(.Block); | 800 | try parser.pushScope(.Block); |
| 786 | defer parser.popScope(scope); | 801 | defer parser.popScope(); |
| 787 | var fields = Node.RecordType.FieldList.init(parser.arena); | 802 | var fields = Node.RecordType.FieldList.init(parser.arena); |
| 788 | while (true) { | 803 | while (true) { |
| 789 | if (parser.eatToken(.RBrace)) |rbrace| { | 804 | if (parser.eatToken(.RBrace)) |rbrace| { |
| ... | @@ -996,15 +1011,14 @@ const Parser = struct { | ... | @@ -996,15 +1011,14 @@ const Parser = struct { |
| 996 | fn assignmentExpr(parser: *Parser) !*Node {} | 1011 | fn assignmentExpr(parser: *Parser) !*Node {} |
| 997 | | 1012 | |
| 998 | /// ConstExpr <- ConditionalExpr | 1013 | /// ConstExpr <- ConditionalExpr |
| 999 | fn constExpr(parser: *Parser) Error!*Node { | 1014 | fn constExpr(parser: *Parser) Error!?*Expr { |
| 1000 | const start = parser.it.index; | 1015 | const start = parser.it.index; |
| 1001 | const expression = try parser.conditionalExpr(); | 1016 | const expression = try parser.conditionalExpr(); |
| 1002 | // TODO | 1017 | if (expression != null and expression.?.value == .None) |
| 1003 | // if (expression == nullor expression.?.value == null) | 1018 | return parser.err(.{ |
| 1004 | // return parser.err(.{ | 1019 | .ConsExpr = start, |
| 1005 | // .ConsExpr = start, | 1020 | }); |
| 1006 | // }); | 1021 | return expression; |
| 1007 | return expression.?; | | |
| 1008 | } | 1022 | } |
| 1009 | | 1023 | |
| 1010 | /// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)? | 1024 | /// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)? |
| ... | @@ -1085,8 +1099,8 @@ const Parser = struct { | ... | @@ -1085,8 +1099,8 @@ const Parser = struct { |
| 1085 | /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE | 1099 | /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE |
| 1086 | fn compoundStmt(parser: *Parser) Error!?*Node { | 1100 | fn compoundStmt(parser: *Parser) Error!?*Node { |
| 1087 | const lbrace = parser.eatToken(.LBrace) orelse return null; | 1101 | const lbrace = parser.eatToken(.LBrace) orelse return null; |
| 1088 | const scope = parser.pushScope(.Block); | 1102 | try parser.pushScope(.Block); |
| 1089 | defer parser.popScope(scope); | 1103 | defer parser.popScope(); |
| 1090 | const body_node = try parser.arena.create(Node.CompoundStmt); | 1104 | const body_node = try parser.arena.create(Node.CompoundStmt); |
| 1091 | body_node.* = .{ | 1105 | body_node.* = .{ |
| 1092 | .lbrace = lbrace, | 1106 | .lbrace = lbrace, |
| ... | @@ -1142,8 +1156,8 @@ const Parser = struct { | ... | @@ -1142,8 +1156,8 @@ const Parser = struct { |
| 1142 | return &node.base; | 1156 | return &node.base; |
| 1143 | } | 1157 | } |
| 1144 | if (parser.eatToken(.Keyword_while)) |tok| { | 1158 | if (parser.eatToken(.Keyword_while)) |tok| { |
| 1145 | const scope = parser.pushScope(.Loop); | 1159 | try parser.pushScope(.Loop); |
| 1146 | defer parser.popScope(scope); | 1160 | defer parser.popScope(); |
| 1147 | _ = try parser.expectToken(.LParen); | 1161 | _ = try parser.expectToken(.LParen); |
| 1148 | const cond = (try parser.expr()) orelse return parser.err(.{ | 1162 | const cond = (try parser.expr()) orelse return parser.err(.{ |
| 1149 | .ExpectedExpr = .{ .token = parser.it.index }, | 1163 | .ExpectedExpr = .{ .token = parser.it.index }, |
| ... | @@ -1160,8 +1174,8 @@ const Parser = struct { | ... | @@ -1160,8 +1174,8 @@ const Parser = struct { |
| 1160 | return &node.base; | 1174 | return &node.base; |
| 1161 | } | 1175 | } |
| 1162 | if (parser.eatToken(.Keyword_do)) |tok| { | 1176 | if (parser.eatToken(.Keyword_do)) |tok| { |
| 1163 | const scope = parser.pushScope(.Loop); | 1177 | try parser.pushScope(.Loop); |
| 1164 | defer parser.popScope(scope); | 1178 | defer parser.popScope(); |
| 1165 | const body = try parser.stmt(); | 1179 | const body = try parser.stmt(); |
| 1166 | _ = try parser.expectToken(.LParen); | 1180 | _ = try parser.expectToken(.LParen); |
| 1167 | const cond = (try parser.expr()) orelse return parser.err(.{ | 1181 | const cond = (try parser.expr()) orelse return parser.err(.{ |
| ... | @@ -1179,8 +1193,8 @@ const Parser = struct { | ... | @@ -1179,8 +1193,8 @@ const Parser = struct { |
| 1179 | return &node.base; | 1193 | return &node.base; |
| 1180 | } | 1194 | } |
| 1181 | if (parser.eatToken(.Keyword_for)) |tok| { | 1195 | if (parser.eatToken(.Keyword_for)) |tok| { |
| 1182 | const scope = parser.pushScope(.Loop); | 1196 | try parser.pushScope(.Loop); |
| 1183 | defer parser.popScope(scope); | 1197 | defer parser.popScope(); |
| 1184 | _ = try parser.expectToken(.LParen); | 1198 | _ = try parser.expectToken(.LParen); |
| 1185 | const init = if (try parser.declaration()) |decl| blk:{ | 1199 | const init = if (try parser.declaration()) |decl| blk:{ |
| 1186 | // TODO disallow storage class other than auto and register | 1200 | // TODO disallow storage class other than auto and register |
| ... | @@ -1203,8 +1217,8 @@ const Parser = struct { | ... | @@ -1203,8 +1217,8 @@ const Parser = struct { |
| 1203 | return &node.base; | 1217 | return &node.base; |
| 1204 | } | 1218 | } |
| 1205 | if (parser.eatToken(.Keyword_switch)) |tok| { | 1219 | if (parser.eatToken(.Keyword_switch)) |tok| { |
| 1206 | const scope = parser.pushScope(.Switch); | 1220 | try parser.pushScope(.Switch); |
| 1207 | defer parser.popScope(scope); | 1221 | defer parser.popScope(); |
| 1208 | _ = try parser.expectToken(.LParen); | 1222 | _ = try parser.expectToken(.LParen); |
| 1209 | const switch_expr = try parser.exprStmt(); | 1223 | const switch_expr = try parser.exprStmt(); |
| 1210 | const rparen = try parser.expectToken(.RParen); | 1224 | const rparen = try parser.expectToken(.RParen); |