authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-19 20:41:44+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-19 20:44:55+02:00
logad327fed05d2d809dfef612e3f4abbb5a9a5ed71
tree667f96f412aea8b77ddd294e1801710bf6d1afb7
parent28daddae81f354da89f917528dab2e5d87bca829
signature Commit is signed but in an unrecognized format.

std-c redo scoping, do string concatanation in parser


3 files changed, 69 insertions(+), 63 deletions(-)

lib/std/c/ast.zig+1-1
...@@ -576,7 +576,7 @@ pub const Node = struct {...@@ -576,7 +576,7 @@ pub const Node = struct {
576 asterisk: ?TokenIndex,576 asterisk: ?TokenIndex,
577 static: ?TokenIndex,577 static: ?TokenIndex,
578 qual: TypeQual,578 qual: TypeQual,
579 // expr: *Expr,579 expr: *Expr,
580 },580 },
581 },581 },
582 rbracket: TokenIndex,582 rbracket: TokenIndex,
lib/std/c/parse.zig+49-35
...@@ -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 }
7777
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,
9598
96 /// only used for scopes99 arena: *Allocator,
97 symbols: SymbolList,100 scopes: ScopeList,
98 options: Options,101 options: Options,
99102
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 };
101110
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 };
113122
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 }
117130
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 }
121134
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 {
137152
138 /// Root <- ExternalDeclaration* eof153 /// 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 {}
9971012
998 /// ConstExpr <- ConditionalExpr1013 /// 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 // TODO1017 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 }
10091023
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)* RBRACE1099 /// 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 register1200 // 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);
lib/std/c/tokenizer.zig+19-27
...@@ -401,7 +401,6 @@ pub const Tokenizer = struct {...@@ -401,7 +401,6 @@ pub const Tokenizer = struct {
401 U,401 U,
402 L,402 L,
403 StringLiteral,403 StringLiteral,
404 AfterStringLiteral,
405 CharLiteralStart,404 CharLiteralStart,
406 CharLiteral,405 CharLiteral,
407 EscapeSequence,406 EscapeSequence,
...@@ -617,7 +616,7 @@ pub const Tokenizer = struct {...@@ -617,7 +616,7 @@ pub const Tokenizer = struct {
617 },616 },
618 .BackSlash => switch (c) {617 .BackSlash => switch (c) {
619 '\n' => {618 '\n' => {
620 state = if (string) .AfterStringLiteral else .Start;619 state = .Start;
621 },620 },
622 '\r' => {621 '\r' => {
623 state = .BackSlashCr;622 state = .BackSlashCr;
...@@ -632,7 +631,7 @@ pub const Tokenizer = struct {...@@ -632,7 +631,7 @@ pub const Tokenizer = struct {
632 },631 },
633 .BackSlashCr => switch (c) {632 .BackSlashCr => switch (c) {
634 '\n' => {633 '\n' => {
635 state = if (string) .AfterStringLiteral else .Start;634 state = .Start;
636 },635 },
637 else => {636 else => {
638 result.id = .Invalid;637 result.id = .Invalid;
...@@ -696,7 +695,8 @@ pub const Tokenizer = struct {...@@ -696,7 +695,8 @@ pub const Tokenizer = struct {
696 state = .EscapeSequence;695 state = .EscapeSequence;
697 },696 },
698 '"' => {697 '"' => {
699 state = .AfterStringLiteral;698 self.index += 1;
699 break;
700 },700 },
701 '\n', '\r' => {701 '\n', '\r' => {
702 result.id = .Invalid;702 result.id = .Invalid;
...@@ -704,22 +704,6 @@ pub const Tokenizer = struct {...@@ -704,22 +704,6 @@ pub const Tokenizer = struct {
704 },704 },
705 else => {},705 else => {},
706 },706 },
707 .AfterStringLiteral => switch (c) {
708 '"' => {
709 state = .StringLiteral;
710 },
711 '\\' => {
712 state = .BackSlash;
713 },
714 '\n', '\r' => {
715 if (self.pp_directive)
716 break;
717 },
718 '\t', '\x0B', '\x0C', ' ' => {},
719 else => {
720 break;
721 },
722 },
723 .CharLiteralStart => switch (c) {707 .CharLiteralStart => switch (c) {
724 '\\' => {708 '\\' => {
725 string = false;709 string = false;
...@@ -1255,7 +1239,7 @@ pub const Tokenizer = struct {...@@ -1255,7 +1239,7 @@ pub const Tokenizer = struct {
1255 }1239 }
1256 } else if (self.index == self.source.buffer.len) {1240 } else if (self.index == self.source.buffer.len) {
1257 switch (state) {1241 switch (state) {
1258 .AfterStringLiteral, .Start => {},1242 .Start => {},
1259 .u, .u8, .U, .L, .Identifier => {1243 .u, .u8, .U, .L, .Identifier => {
1260 result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier;1244 result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier;
1261 },1245 },
...@@ -1322,7 +1306,7 @@ pub const Tokenizer = struct {...@@ -1322,7 +1306,7 @@ pub const Tokenizer = struct {
13221306
1323test "operators" {1307test "operators" {
1324 expectTokens(1308 expectTokens(
1325 \\ ! != | || |= = ==1309 \\ ! != | || |= = ==
1326 \\ ( ) { } [ ] . .. ...1310 \\ ( ) { } [ ] . .. ...
1327 \\ ^ ^= + ++ += - -- -=1311 \\ ^ ^= + ++ += - -- -=
1328 \\ * *= % %= -> : ; / /=1312 \\ * *= % %= -> : ; / /=
...@@ -1505,24 +1489,27 @@ test "line continuation" {...@@ -1505,24 +1489,27 @@ test "line continuation" {
1505 .Identifier,1489 .Identifier,
1506 .Nl,1490 .Nl,
1507 .{ .StringLiteral = .None },1491 .{ .StringLiteral = .None },
1492 .Nl,
1508 .Hash,1493 .Hash,
1509 .Keyword_define,1494 .Keyword_define,
1510 .{ .StringLiteral = .None },1495 .{ .StringLiteral = .None },
1511 .Nl,1496 .Nl,
1512 .{ .StringLiteral = .None },1497 .{ .StringLiteral = .None },
1498 .Nl,
1513 .Hash,1499 .Hash,
1514 .Keyword_define,1500 .Keyword_define,
1515 .{ .StringLiteral = .None },1501 .{ .StringLiteral = .None },
1502 .{ .StringLiteral = .None },
1516 });1503 });
1517}1504}
15181505
1519test "string prefix" {1506test "string prefix" {
1520 expectTokens(1507 expectTokens(
1521 \\"foo" "bar"1508 \\"foo"
1522 \\u"foo" "bar"1509 \\u"foo"
1523 \\u8"foo" "bar"1510 \\u8"foo"
1524 \\U"foo" "bar"1511 \\U"foo"
1525 \\L"foo" "bar"1512 \\L"foo"
1526 \\'foo'1513 \\'foo'
1527 \\u'foo'1514 \\u'foo'
1528 \\U'foo'1515 \\U'foo'
...@@ -1530,10 +1517,15 @@ test "string prefix" {...@@ -1530,10 +1517,15 @@ test "string prefix" {
1530 \\1517 \\
1531 , &[_]Token.Id{1518 , &[_]Token.Id{
1532 .{ .StringLiteral = .None },1519 .{ .StringLiteral = .None },
1520 .Nl,
1533 .{ .StringLiteral = .Utf16 },1521 .{ .StringLiteral = .Utf16 },
1522 .Nl,
1534 .{ .StringLiteral = .Utf8 },1523 .{ .StringLiteral = .Utf8 },
1524 .Nl,
1535 .{ .StringLiteral = .Utf32 },1525 .{ .StringLiteral = .Utf32 },
1526 .Nl,
1536 .{ .StringLiteral = .Wide },1527 .{ .StringLiteral = .Wide },
1528 .Nl,
1537 .{ .CharLiteral = .None },1529 .{ .CharLiteral = .None },
1538 .Nl,1530 .Nl,
1539 .{ .CharLiteral = .Utf16 },1531 .{ .CharLiteral = .Utf16 },