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