| ... | @@ -92,6 +92,8 @@ pub const Parser = struct { | ... | @@ -92,6 +92,8 @@ pub const Parser = struct { |
| 92 | FnDef: &ast.NodeFnProto, | 92 | FnDef: &ast.NodeFnProto, |
| 93 | Block: &ast.NodeBlock, | 93 | Block: &ast.NodeBlock, |
| 94 | Statement: &ast.NodeBlock, | 94 | Statement: &ast.NodeBlock, |
| | 95 | ExprListItemOrEnd: &ArrayList(&ast.Node), |
| | 96 | ExprListCommaOrEnd: &ArrayList(&ast.Node), |
| 95 | }; | 97 | }; |
| 96 | | 98 | |
| 97 | /// Returns an AST tree, allocated with the parser's allocator. | 99 | /// Returns an AST tree, allocated with the parser's allocator. |
| ... | @@ -297,6 +299,21 @@ pub const Parser = struct { | ... | @@ -297,6 +299,21 @@ pub const Parser = struct { |
| 297 | try stack.append(State.AfterOperand); | 299 | try stack.append(State.AfterOperand); |
| 298 | continue; | 300 | continue; |
| 299 | }, | 301 | }, |
| | 302 | Token.Id.Builtin => { |
| | 303 | const node = try arena.create(ast.NodeBuiltinCall); |
| | 304 | *node = ast.NodeBuiltinCall { |
| | 305 | .base = ast.Node {.id = ast.Node.Id.BuiltinCall}, |
| | 306 | .builtin_token = token, |
| | 307 | .params = ArrayList(&ast.Node).init(arena), |
| | 308 | }; |
| | 309 | try stack.append(State { |
| | 310 | .Operand = &node.base |
| | 311 | }); |
| | 312 | try stack.append(State.AfterOperand); |
| | 313 | try stack.append(State {.ExprListItemOrEnd = &node.params }); |
| | 314 | try stack.append(State {.ExpectToken = Token.Id.LParen }); |
| | 315 | continue; |
| | 316 | }, |
| 300 | else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)), | 317 | else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)), |
| 301 | } | 318 | } |
| 302 | }, | 319 | }, |
| ... | @@ -352,6 +369,29 @@ pub const Parser = struct { | ... | @@ -352,6 +369,29 @@ pub const Parser = struct { |
| 352 | } | 369 | } |
| 353 | }, | 370 | }, |
| 354 | | 371 | |
| | 372 | State.ExprListItemOrEnd => |params| { |
| | 373 | var token = self.getNextToken(); |
| | 374 | switch (token.id) { |
| | 375 | Token.Id.RParen => continue, |
| | 376 | else => { |
| | 377 | self.putBackToken(token); |
| | 378 | stack.append(State { .ExprListCommaOrEnd = params }) catch unreachable; |
| | 379 | try stack.append(State { .Expression = DestPtr{.List = params} }); |
| | 380 | }, |
| | 381 | } |
| | 382 | }, |
| | 383 | |
| | 384 | State.ExprListCommaOrEnd => |params| { |
| | 385 | var token = self.getNextToken(); |
| | 386 | switch (token.id) { |
| | 387 | Token.Id.Comma => { |
| | 388 | stack.append(State { .ExprListItemOrEnd = params }) catch unreachable; |
| | 389 | }, |
| | 390 | Token.Id.RParen => continue, |
| | 391 | else => return self.parseError(token, "expected ',' or ')', found {}", @tagName(token.id)), |
| | 392 | } |
| | 393 | }, |
| | 394 | |
| 355 | State.AddrOfModifiers => |addr_of_info| { | 395 | State.AddrOfModifiers => |addr_of_info| { |
| 356 | var token = self.getNextToken(); | 396 | var token = self.getNextToken(); |
| 357 | switch (token.id) { | 397 | switch (token.id) { |
| ... | @@ -539,8 +579,6 @@ pub const Parser = struct { | ... | @@ -539,8 +579,6 @@ pub const Parser = struct { |
| 539 | State.PrefixOp => unreachable, | 579 | State.PrefixOp => unreachable, |
| 540 | State.Operand => unreachable, | 580 | State.Operand => unreachable, |
| 541 | } | 581 | } |
| 542 | @import("std").debug.panic("{}", @tagName(state)); | | |
| 543 | //unreachable; | | |
| 544 | } | 582 | } |
| 545 | } | 583 | } |
| 546 | | 584 | |
| ... | @@ -988,6 +1026,10 @@ pub const Parser = struct { | ... | @@ -988,6 +1026,10 @@ pub const Parser = struct { |
| 988 | const float_literal = @fieldParentPtr(ast.NodeFloatLiteral, "base", base); | 1026 | const float_literal = @fieldParentPtr(ast.NodeFloatLiteral, "base", base); |
| 989 | try stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token)); | 1027 | try stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token)); |
| 990 | }, | 1028 | }, |
| | 1029 | ast.Node.Id.BuiltinCall => { |
| | 1030 | const builtin_call = @fieldParentPtr(ast.NodeBuiltinCall, "base", base); |
| | 1031 | try stream.print("{}()", self.tokenizer.getTokenSlice(builtin_call.builtin_token)); |
| | 1032 | }, |
| 991 | else => unreachable, | 1033 | else => unreachable, |
| 992 | }, | 1034 | }, |
| 993 | RenderState.FnProtoRParen => |fn_proto| { | 1035 | RenderState.FnProtoRParen => |fn_proto| { |
| ... | @@ -1098,6 +1140,11 @@ fn testCanonical(source: []const u8) !void { | ... | @@ -1098,6 +1140,11 @@ fn testCanonical(source: []const u8) !void { |
| 1098 | } | 1140 | } |
| 1099 | | 1141 | |
| 1100 | test "zig fmt" { | 1142 | test "zig fmt" { |
| | 1143 | try testCanonical( |
| | 1144 | \\const std = @import(); |
| | 1145 | \\ |
| | 1146 | ); |
| | 1147 | |
| 1101 | try testCanonical( | 1148 | try testCanonical( |
| 1102 | \\extern fn puts(s: &const u8) c_int; | 1149 | \\extern fn puts(s: &const u8) c_int; |
| 1103 | \\ | 1150 | \\ |