| author | |
| committer | |
| log | 3e67ef5c9f539d63e93867c0928ad1fdf2658682 |
| tree | 0e99cee6aa6b700a0b87a182f83acd0ca5a14edc |
| parent | c9050565625bb7a43b8cc10b1103826ffccea69d |
Use `@` syntax to escape `_` when used as an identifier.
Remove the stage1 astgen prohibition against assigning from `_`
Note: there a few stage1 bugs preventing `_` from being used as an identifier
for a local variable or function parameter; these will be fixed by stage2.
They are unlikely to arise in real C code since identifiers starting with
underscore are reserved for the implementation.5 files changed, 18 insertions(+), 9 deletions(-)
lib/std/zig/fmt.zig+1| ... | @@ -23,6 +23,7 @@ pub fn fmtId(bytes: []const u8) std.fmt.Formatter(formatId) { | ... | @@ -23,6 +23,7 @@ pub fn fmtId(bytes: []const u8) std.fmt.Formatter(formatId) { |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | pub fn isValidId(bytes: []const u8) bool { | 25 | pub fn isValidId(bytes: []const u8) bool { |
| 26 | if (mem.eql(u8, bytes, "_")) return false; | ||
| 26 | for (bytes) |c, i| { | 27 | for (bytes) |c, i| { |
| 27 | switch (c) { | 28 | switch (c) { |
| 28 | '_', 'a'...'z', 'A'...'Z' => {}, | 29 | '_', 'a'...'z', 'A'...'Z' => {}, |
src/stage1/astgen.cpp-3| ... | @@ -3821,9 +3821,6 @@ static Stage1ZirInst *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode | ... | @@ -3821,9 +3821,6 @@ static Stage1ZirInst *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode |
| 3821 | const_instruction->value->special = ConstValSpecialStatic; | 3821 | const_instruction->value->special = ConstValSpecialStatic; |
| 3822 | const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard; | 3822 | const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard; |
| 3823 | return &const_instruction->base; | 3823 | return &const_instruction->base; |
| 3824 | } else { | ||
| 3825 | add_node_error(ag->codegen, node, buf_sprintf("`_` may only be used to assign things to")); | ||
| 3826 | return ag->codegen->invalid_inst_src; | ||
| 3827 | } | 3824 | } |
| 3828 | } | 3825 | } |
| 3829 | 3826 |
src/translate_c.zig-4| ... | @@ -4951,10 +4951,6 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -4951,10 +4951,6 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 4951 | const scope = &c.global_scope.base; | 4951 | const scope = &c.global_scope.base; |
| 4952 | 4952 | ||
| 4953 | const init_node = try parseCExpr(c, m, scope); | 4953 | const init_node = try parseCExpr(c, m, scope); |
| 4954 | if (init_node.castTag(.identifier)) |ident_node| { | ||
| 4955 | if (mem.eql(u8, "_", ident_node.data)) | ||
| 4956 | return m.fail(c, "unable to translate C expr: illegal identifier _", .{}); | ||
| 4957 | } | ||
| 4958 | const last = m.next().?; | 4954 | const last = m.next().?; |
| 4959 | if (last != .Eof and last != .Nl) | 4955 | if (last != .Eof and last != .Nl) |
| 4960 | return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); | 4956 | return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); |
test/run_translated_c.zig+12| ... | @@ -1647,4 +1647,16 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { | ... | @@ -1647,4 +1647,16 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 1647 | \\ if (a != 1) abort(); | 1647 | \\ if (a != 1) abort(); |
| 1648 | \\} | 1648 | \\} |
| 1649 | , ""); | 1649 | , ""); |
| 1650 | |||
| 1651 | cases.add("Underscore identifiers", | ||
| 1652 | \\#include <stdlib.h> | ||
| 1653 | \\int _ = 10; | ||
| 1654 | \\typedef struct { int _; } S; | ||
| 1655 | \\int main(void) { | ||
| 1656 | \\ if (_ != 10) abort(); | ||
| 1657 | \\ S foo = { ._ = _ }; | ||
| 1658 | \\ if (foo._ != _) abort(); | ||
| 1659 | \\ return 0; | ||
| 1660 | \\} | ||
| 1661 | , ""); | ||
| 1650 | } | 1662 | } |
test/translate_c.zig+5-2| ... | @@ -3616,9 +3616,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3616,9 +3616,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3616 | \\} | 3616 | \\} |
| 3617 | }); | 3617 | }); |
| 3618 | 3618 | ||
| 3619 | cases.add("Don't allow underscore identifier in macros", | 3619 | cases.add("Use @ syntax for bare underscore identifier in macro or public symbol", |
| 3620 | \\#define FOO _ | 3620 | \\#define FOO _ |
| 3621 | \\int _ = 42; | ||
| 3621 | , &[_][]const u8{ | 3622 | , &[_][]const u8{ |
| 3622 | \\pub const FOO = @compileError("unable to translate C expr: illegal identifier _"); | 3623 | \\pub const FOO = @"_"; |
| 3624 | , | ||
| 3625 | \\pub export var @"_": c_int = 42; | ||
| 3623 | }); | 3626 | }); |
| 3624 | } | 3627 | } |