| ... | @@ -5281,6 +5281,18 @@ const MacroCtx = struct { | ... | @@ -5281,6 +5281,18 @@ const MacroCtx = struct { |
| 5281 | return self.list[self.i].id; | 5281 | return self.list[self.i].id; |
| 5282 | } | 5282 | } |
| 5283 | | 5283 | |
| | 5284 | fn skip(self: *MacroCtx, c: *Context, expected_id: std.meta.Tag(CToken.Id)) ParseError!void { |
| | 5285 | const next_id = self.next().?; |
| | 5286 | if (next_id != expected_id) { |
| | 5287 | try self.fail( |
| | 5288 | c, |
| | 5289 | "unable to translate C expr: expected '{s}' instead got '{s}'", |
| | 5290 | .{ CToken.Id.symbol(expected_id), next_id.symbol() }, |
| | 5291 | ); |
| | 5292 | return error.ParseError; |
| | 5293 | } |
| | 5294 | } |
| | 5295 | |
| 5284 | fn slice(self: *MacroCtx) []const u8 { | 5296 | fn slice(self: *MacroCtx) []const u8 { |
| 5285 | const tok = self.list[self.i]; | 5297 | const tok = self.list[self.i]; |
| 5286 | return self.source[tok.start..tok.end]; | 5298 | return self.source[tok.start..tok.end]; |
| ... | @@ -5418,7 +5430,7 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -5418,7 +5430,7 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5418 | const init_node = try parseCExpr(c, m, scope); | 5430 | const init_node = try parseCExpr(c, m, scope); |
| 5419 | const last = m.next().?; | 5431 | const last = m.next().?; |
| 5420 | if (last != .Eof and last != .Nl) | 5432 | if (last != .Eof and last != .Nl) |
| 5421 | return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); | 5433 | return m.fail(c, "unable to translate C expr: unexpected token '{s}'", .{last.symbol()}); |
| 5422 | | 5434 | |
| 5423 | const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = m.name, .init = init_node }); | 5435 | const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = m.name, .init = init_node }); |
| 5424 | try c.global_scope.macro_table.put(m.name, var_decl); | 5436 | try c.global_scope.macro_table.put(m.name, var_decl); |
| ... | @@ -5439,9 +5451,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -5439,9 +5451,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5439 | defer block_scope.deinit(); | 5451 | defer block_scope.deinit(); |
| 5440 | const scope = &block_scope.base; | 5452 | const scope = &block_scope.base; |
| 5441 | | 5453 | |
| 5442 | if (m.next().? != .LParen) { | 5454 | try m.skip(c, .LParen); |
| 5443 | return m.fail(c, "unable to translate C expr: expected '('", .{}); | | |
| 5444 | } | | |
| 5445 | | 5455 | |
| 5446 | var fn_params = std.ArrayList(ast.Payload.Param).init(c.gpa); | 5456 | var fn_params = std.ArrayList(ast.Payload.Param).init(c.gpa); |
| 5447 | defer fn_params.deinit(); | 5457 | defer fn_params.deinit(); |
| ... | @@ -5461,9 +5471,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -5461,9 +5471,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5461 | _ = m.next(); | 5471 | _ = m.next(); |
| 5462 | } | 5472 | } |
| 5463 | | 5473 | |
| 5464 | if (m.next().? != .RParen) { | 5474 | try m.skip(c, .RParen); |
| 5465 | return m.fail(c, "unable to translate C expr: expected ')'", .{}); | | |
| 5466 | } | | |
| 5467 | | 5475 | |
| 5468 | if (m.containsUndefinedIdentifier(scope, fn_params.items)) |ident| | 5476 | if (m.containsUndefinedIdentifier(scope, fn_params.items)) |ident| |
| 5469 | return m.fail(c, "unable to translate macro: undefined identifier `{s}`", .{ident}); | 5477 | return m.fail(c, "unable to translate macro: undefined identifier `{s}`", .{ident}); |
| ... | @@ -5471,7 +5479,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -5471,7 +5479,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5471 | const expr = try parseCExpr(c, m, scope); | 5479 | const expr = try parseCExpr(c, m, scope); |
| 5472 | const last = m.next().?; | 5480 | const last = m.next().?; |
| 5473 | if (last != .Eof and last != .Nl) | 5481 | if (last != .Eof and last != .Nl) |
| 5474 | return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); | 5482 | return m.fail(c, "unable to translate C expr: unexpected token '{s}'", .{last.symbol()}); |
| 5475 | | 5483 | |
| 5476 | const typeof_arg = if (expr.castTag(.block)) |some| blk: { | 5484 | const typeof_arg = if (expr.castTag(.block)) |some| blk: { |
| 5477 | const stmts = some.data.stmts; | 5485 | const stmts = some.data.stmts; |
| ... | @@ -5837,11 +5845,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -5837,11 +5845,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 5837 | .LParen => { | 5845 | .LParen => { |
| 5838 | const inner_node = try parseCExpr(c, m, scope); | 5846 | const inner_node = try parseCExpr(c, m, scope); |
| 5839 | | 5847 | |
| 5840 | const next_id = m.next().?; | 5848 | try m.skip(c, .RParen); |
| 5841 | if (next_id != .RParen) { | | |
| 5842 | try m.fail(c, "unable to translate C expr: expected ')' instead got: {s}", .{@tagName(next_id)}); | | |
| 5843 | return error.ParseError; | | |
| 5844 | } | | |
| 5845 | return inner_node; | 5849 | return inner_node; |
| 5846 | }, | 5850 | }, |
| 5847 | else => { | 5851 | else => { |
| ... | @@ -5851,7 +5855,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -5851,7 +5855,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 5851 | if (try parseCTypeName(c, m, scope, true)) |type_name| { | 5855 | if (try parseCTypeName(c, m, scope, true)) |type_name| { |
| 5852 | return type_name; | 5856 | return type_name; |
| 5853 | } | 5857 | } |
| 5854 | try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)}); | 5858 | try m.fail(c, "unable to translate C expr: unexpected token '{s}'", .{tok.symbol()}); |
| 5855 | return error.ParseError; | 5859 | return error.ParseError; |
| 5856 | }, | 5860 | }, |
| 5857 | } | 5861 | } |
| ... | @@ -5896,10 +5900,7 @@ fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5896,10 +5900,7 @@ fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5896 | _ = m.next(); | 5900 | _ = m.next(); |
| 5897 | | 5901 | |
| 5898 | const then_body = try parseCOrExpr(c, m, scope); | 5902 | const then_body = try parseCOrExpr(c, m, scope); |
| 5899 | if (m.next().? != .Colon) { | 5903 | try m.skip(c, .Colon); |
| 5900 | try m.fail(c, "unable to translate C expr: expected ':'", .{}); | | |
| 5901 | return error.ParseError; | | |
| 5902 | } | | |
| 5903 | const else_body = try parseCCondExpr(c, m, scope); | 5904 | const else_body = try parseCCondExpr(c, m, scope); |
| 5904 | return Tag.@"if".create(c.arena, .{ .cond = node, .then = then_body, .@"else" = else_body }); | 5905 | return Tag.@"if".create(c.arena, .{ .cond = node, .then = then_body, .@"else" = else_body }); |
| 5905 | } | 5906 | } |
| ... | @@ -6086,10 +6087,7 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -6086,10 +6087,7 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 6086 | switch (m.next().?) { | 6087 | switch (m.next().?) { |
| 6087 | .LParen => { | 6088 | .LParen => { |
| 6088 | if (try parseCTypeName(c, m, scope, true)) |type_name| { | 6089 | if (try parseCTypeName(c, m, scope, true)) |type_name| { |
| 6089 | if (m.next().? != .RParen) { | 6090 | try m.skip(c, .RParen); |
| 6090 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); | | |
| 6091 | return error.ParseError; | | |
| 6092 | } | | |
| 6093 | if (m.peek().? == .LBrace) { | 6091 | if (m.peek().? == .LBrace) { |
| 6094 | // initializer list | 6092 | // initializer list |
| 6095 | return parseCPostfixExpr(c, m, scope, type_name); | 6093 | return parseCPostfixExpr(c, m, scope, type_name); |
| ... | @@ -6141,11 +6139,7 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_ | ... | @@ -6141,11 +6139,7 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_ |
| 6141 | .Keyword_enum, .Keyword_struct, .Keyword_union => { | 6139 | .Keyword_enum, .Keyword_struct, .Keyword_union => { |
| 6142 | // struct Foo will be declared as struct_Foo by transRecordDecl | 6140 | // struct Foo will be declared as struct_Foo by transRecordDecl |
| 6143 | const slice = m.slice(); | 6141 | const slice = m.slice(); |
| 6144 | const next_id = m.next().?; | 6142 | try m.skip(c, .Identifier); |
| 6145 | if (next_id != .Identifier) { | | |
| 6146 | try m.fail(c, "unable to translate C expr: expected Identifier instead got: {s}", .{@tagName(next_id)}); | | |
| 6147 | return error.ParseError; | | |
| 6148 | } | | |
| 6149 | | 6143 | |
| 6150 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); | 6144 | const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() }); |
| 6151 | return try Tag.identifier.create(c.arena, name); | 6145 | return try Tag.identifier.create(c.arena, name); |
| ... | @@ -6157,7 +6151,7 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_ | ... | @@ -6157,7 +6151,7 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_ |
| 6157 | m.i -= 1; | 6151 | m.i -= 1; |
| 6158 | return null; | 6152 | return null; |
| 6159 | } else { | 6153 | } else { |
| 6160 | try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)}); | 6154 | try m.fail(c, "unable to translate C expr: unexpected token '{s}'", .{tok.symbol()}); |
| 6161 | return error.ParseError; | 6155 | return error.ParseError; |
| 6162 | } | 6156 | } |
| 6163 | } | 6157 | } |
| ... | @@ -6298,18 +6292,12 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) | ... | @@ -6298,18 +6292,12 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) |
| 6298 | while (true) { | 6292 | while (true) { |
| 6299 | switch (m.next().?) { | 6293 | switch (m.next().?) { |
| 6300 | .Period => { | 6294 | .Period => { |
| 6301 | if (m.next().? != .Identifier) { | 6295 | try m.skip(c, .Identifier); |
| 6302 | try m.fail(c, "unable to translate C expr: expected identifier", .{}); | | |
| 6303 | return error.ParseError; | | |
| 6304 | } | | |
| 6305 | | 6296 | |
| 6306 | node = try Tag.field_access.create(c.arena, .{ .lhs = node, .field_name = m.slice() }); | 6297 | node = try Tag.field_access.create(c.arena, .{ .lhs = node, .field_name = m.slice() }); |
| 6307 | }, | 6298 | }, |
| 6308 | .Arrow => { | 6299 | .Arrow => { |
| 6309 | if (m.next().? != .Identifier) { | 6300 | try m.skip(c, .Identifier); |
| 6310 | try m.fail(c, "unable to translate C expr: expected identifier", .{}); | | |
| 6311 | return error.ParseError; | | |
| 6312 | } | | |
| 6313 | | 6301 | |
| 6314 | const deref = try Tag.deref.create(c.arena, node); | 6302 | const deref = try Tag.deref.create(c.arena, node); |
| 6315 | node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .field_name = m.slice() }); | 6303 | node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .field_name = m.slice() }); |
| ... | @@ -6317,10 +6305,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) | ... | @@ -6317,10 +6305,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) |
| 6317 | .LBracket => { | 6305 | .LBracket => { |
| 6318 | const index = try macroBoolToInt(c, try parseCExpr(c, m, scope)); | 6306 | const index = try macroBoolToInt(c, try parseCExpr(c, m, scope)); |
| 6319 | node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index }); | 6307 | node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index }); |
| 6320 | if (m.next().? != .RBracket) { | 6308 | try m.skip(c, .RBracket); |
| 6321 | try m.fail(c, "unable to translate C expr: expected ']'", .{}); | | |
| 6322 | return error.ParseError; | | |
| 6323 | } | | |
| 6324 | }, | 6309 | }, |
| 6325 | .LParen => { | 6310 | .LParen => { |
| 6326 | if (m.peek().? == .RParen) { | 6311 | if (m.peek().? == .RParen) { |
| ... | @@ -6332,11 +6317,12 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) | ... | @@ -6332,11 +6317,12 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) |
| 6332 | while (true) { | 6317 | while (true) { |
| 6333 | const arg = try parseCCondExpr(c, m, scope); | 6318 | const arg = try parseCCondExpr(c, m, scope); |
| 6334 | try args.append(arg); | 6319 | try args.append(arg); |
| 6335 | switch (m.next().?) { | 6320 | const next_id = m.next().?; |
| | 6321 | switch (next_id) { |
| 6336 | .Comma => {}, | 6322 | .Comma => {}, |
| 6337 | .RParen => break, | 6323 | .RParen => break, |
| 6338 | else => { | 6324 | else => { |
| 6339 | try m.fail(c, "unable to translate C expr: expected ',' or ')'", .{}); | 6325 | try m.fail(c, "unable to translate C expr: expected ',' or ')' instead got '{s}'", .{next_id.symbol()}); |
| 6340 | return error.ParseError; | 6326 | return error.ParseError; |
| 6341 | }, | 6327 | }, |
| 6342 | } | 6328 | } |
| ... | @@ -6351,27 +6337,19 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) | ... | @@ -6351,27 +6337,19 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) |
| 6351 | defer init_vals.deinit(); | 6337 | defer init_vals.deinit(); |
| 6352 | | 6338 | |
| 6353 | while (true) { | 6339 | while (true) { |
| 6354 | if (m.next().? != .Period) { | 6340 | try m.skip(c, .Period); |
| 6355 | try m.fail(c, "unable to translate C expr: expected '.'", .{}); | 6341 | try m.skip(c, .Identifier); |
| 6356 | return error.ParseError; | | |
| 6357 | } | | |
| 6358 | if (m.next().? != .Identifier) { | | |
| 6359 | try m.fail(c, "unable to translate C expr: expected identifier", .{}); | | |
| 6360 | return error.ParseError; | | |
| 6361 | } | | |
| 6362 | const name = m.slice(); | 6342 | const name = m.slice(); |
| 6363 | if (m.next().? != .Equal) { | 6343 | try m.skip(c, .Equal); |
| 6364 | try m.fail(c, "unable to translate C expr: expected '='", .{}); | | |
| 6365 | return error.ParseError; | | |
| 6366 | } | | |
| 6367 | | 6344 | |
| 6368 | const val = try parseCCondExpr(c, m, scope); | 6345 | const val = try parseCCondExpr(c, m, scope); |
| 6369 | try init_vals.append(.{ .name = name, .value = val }); | 6346 | try init_vals.append(.{ .name = name, .value = val }); |
| 6370 | switch (m.next().?) { | 6347 | const next_id = m.next().?; |
| | 6348 | switch (next_id) { |
| 6371 | .Comma => {}, | 6349 | .Comma => {}, |
| 6372 | .RBrace => break, | 6350 | .RBrace => break, |
| 6373 | else => { | 6351 | else => { |
| 6374 | try m.fail(c, "unable to translate C expr: expected ',' or '}}'", .{}); | 6352 | try m.fail(c, "unable to translate C expr: expected ',' or '}}' instead got '{s}'", .{next_id.symbol()}); |
| 6375 | return error.ParseError; | 6353 | return error.ParseError; |
| 6376 | }, | 6354 | }, |
| 6377 | } | 6355 | } |
| ... | @@ -6387,11 +6365,12 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) | ... | @@ -6387,11 +6365,12 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) |
| 6387 | while (true) { | 6365 | while (true) { |
| 6388 | const val = try parseCCondExpr(c, m, scope); | 6366 | const val = try parseCCondExpr(c, m, scope); |
| 6389 | try init_vals.append(val); | 6367 | try init_vals.append(val); |
| 6390 | switch (m.next().?) { | 6368 | const next_id = m.next().?; |
| | 6369 | switch (next_id) { |
| 6391 | .Comma => {}, | 6370 | .Comma => {}, |
| 6392 | .RBrace => break, | 6371 | .RBrace => break, |
| 6393 | else => { | 6372 | else => { |
| 6394 | try m.fail(c, "unable to translate C expr: expected ',' or '}}'", .{}); | 6373 | try m.fail(c, "unable to translate C expr: expected ',' or '}}' instead got '{s}'", .{next_id.symbol()}); |
| 6395 | return error.ParseError; | 6374 | return error.ParseError; |
| 6396 | }, | 6375 | }, |
| 6397 | } | 6376 | } |
| ... | @@ -6438,10 +6417,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -6438,10 +6417,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 6438 | const operand = if (m.peek().? == .LParen) blk: { | 6417 | const operand = if (m.peek().? == .LParen) blk: { |
| 6439 | _ = m.next(); | 6418 | _ = m.next(); |
| 6440 | const inner = (try parseCTypeName(c, m, scope, false)).?; | 6419 | const inner = (try parseCTypeName(c, m, scope, false)).?; |
| 6441 | if (m.next().? != .RParen) { | 6420 | try m.skip(c, .RParen); |
| 6442 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); | | |
| 6443 | return error.ParseError; | | |
| 6444 | } | | |
| 6445 | break :blk inner; | 6421 | break :blk inner; |
| 6446 | } else try parseCUnaryExpr(c, m, scope); | 6422 | } else try parseCUnaryExpr(c, m, scope); |
| 6447 | | 6423 | |
| ... | @@ -6450,15 +6426,9 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -6450,15 +6426,9 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 6450 | .Keyword_alignof => { | 6426 | .Keyword_alignof => { |
| 6451 | // TODO this won't work if using <stdalign.h>'s | 6427 | // TODO this won't work if using <stdalign.h>'s |
| 6452 | // #define alignof _Alignof | 6428 | // #define alignof _Alignof |
| 6453 | if (m.next().? != .LParen) { | 6429 | try m.skip(c, .LParen); |
| 6454 | try m.fail(c, "unable to translate C expr: expected '('", .{}); | | |
| 6455 | return error.ParseError; | | |
| 6456 | } | | |
| 6457 | const operand = (try parseCTypeName(c, m, scope, false)).?; | 6430 | const operand = (try parseCTypeName(c, m, scope, false)).?; |
| 6458 | if (m.next().? != .RParen) { | 6431 | try m.skip(c, .RParen); |
| 6459 | try m.fail(c, "unable to translate C expr: expected ')'", .{}); | | |
| 6460 | return error.ParseError; | | |
| 6461 | } | | |
| 6462 | | 6432 | |
| 6463 | return Tag.alignof.create(c.arena, operand); | 6433 | return Tag.alignof.create(c.arena, operand); |
| 6464 | }, | 6434 | }, |