| ... | @@ -92,7 +92,7 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop | ... | @@ -92,7 +92,7 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop |
| 92 | return mod.failNode(scope, init_node, "TODO implement result locations", .{}); | 92 | return mod.failNode(scope, init_node, "TODO implement result locations", .{}); |
| 93 | } | 93 | } |
| 94 | const init_inst = try expr(mod, scope, init_node); | 94 | const init_inst = try expr(mod, scope, init_node); |
| 95 | const ident_name = tree.tokenSlice(node.name_token); // TODO support @"aoeu" identifiers | 95 | const ident_name = try identifierTokenString(mod, scope, node.name_token); |
| 96 | return Scope.LocalVar{ | 96 | return Scope.LocalVar{ |
| 97 | .parent = scope, | 97 | .parent = scope, |
| 98 | .gen_zir = scope.getGenZIR(), | 98 | .gen_zir = scope.getGenZIR(), |
| ... | @@ -112,7 +112,7 @@ fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) Inne | ... | @@ -112,7 +112,7 @@ fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) Inne |
| 112 | if (infix_node.lhs.tag == .Identifier) { | 112 | if (infix_node.lhs.tag == .Identifier) { |
| 113 | const ident = @fieldParentPtr(ast.Node.Identifier, "base", infix_node.lhs); | 113 | const ident = @fieldParentPtr(ast.Node.Identifier, "base", infix_node.lhs); |
| 114 | const tree = scope.tree(); | 114 | const tree = scope.tree(); |
| 115 | const ident_name = tree.tokenSlice(ident.token); | 115 | const ident_name = try identifierTokenString(mod, scope, ident.token); |
| 116 | if (std.mem.eql(u8, ident_name, "_")) { | 116 | if (std.mem.eql(u8, ident_name, "_")) { |
| 117 | return expr(mod, scope, infix_node.rhs); | 117 | return expr(mod, scope, infix_node.rhs); |
| 118 | } else { | 118 | } else { |
| ... | @@ -123,14 +123,31 @@ fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) Inne | ... | @@ -123,14 +123,31 @@ fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) Inne |
| 123 | } | 123 | } |
| 124 | } | 124 | } |
| 125 | | 125 | |
| 126 | /// Identifier nodes -> ZIR string instruction | 126 | /// Identifier token -> String (allocated in scope.arena()) |
| 127 | pub fn identifierString(mod: *Module, scope: *Scope, node: *ast.Node.Identifier) InnerError!*zir.Inst { | 127 | pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex) InnerError![]const u8 { |
| | 128 | const tree = scope.tree(); |
| | 129 | |
| | 130 | const ident_name = tree.tokenSlice(token); |
| | 131 | if (std.mem.startsWith(u8, ident_name, "@")) { |
| | 132 | const raw_string = ident_name[1..]; |
| | 133 | var bad_index: usize = undefined; |
| | 134 | return std.zig.parseStringLiteral(scope.arena(), raw_string, &bad_index) catch |err| switch (err) { |
| | 135 | error.InvalidCharacter => { |
| | 136 | const bad_byte = raw_string[bad_index]; |
| | 137 | const src = tree.token_locs[token].start; |
| | 138 | return mod.fail(scope, src + 1 + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte}); |
| | 139 | }, |
| | 140 | else => |e| return e, |
| | 141 | }; |
| | 142 | } |
| | 143 | return ident_name; |
| | 144 | } |
| | 145 | |
| | 146 | pub fn identifierStringInst(mod: *Module, scope: *Scope, node: *ast.Node.Identifier) InnerError!*zir.Inst { |
| 128 | const tree = scope.tree(); | 147 | const tree = scope.tree(); |
| 129 | const src = tree.token_locs[node.token].start; | 148 | const src = tree.token_locs[node.token].start; |
| 130 | | 149 | |
| 131 | var ident_name = tree.tokenSlice(node.token); | 150 | const ident_name = try identifierTokenString(mod, scope, node.token); |
| 132 | if (std.mem.startsWith(u8, ident_name, "@")) | | |
| 133 | ident_name = ident_name[2 .. ident_name.len - 1]; | | |
| 134 | | 151 | |
| 135 | return mod.addZIRInst(scope, src, zir.Inst.Str, .{ .bytes = ident_name }, .{}); | 152 | return mod.addZIRInst(scope, src, zir.Inst.Str, .{ .bytes = ident_name }, .{}); |
| 136 | } | 153 | } |
| ... | @@ -140,7 +157,7 @@ fn field(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp) InnerError! | ... | @@ -140,7 +157,7 @@ fn field(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp) InnerError! |
| 140 | const src = tree.token_locs[node.op_token].start; | 157 | const src = tree.token_locs[node.op_token].start; |
| 141 | | 158 | |
| 142 | const lhs = try expr(mod, scope, node.lhs); | 159 | const lhs = try expr(mod, scope, node.lhs); |
| 143 | const field_name = try identifierString(mod, scope, node.rhs.castTag(.Identifier).?); | 160 | const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?); |
| 144 | | 161 | |
| 145 | const pointer = try mod.addZIRInst(scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{}); | 162 | const pointer = try mod.addZIRInst(scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{}); |
| 146 | return mod.addZIRInst(scope, src, zir.Inst.Deref, .{ .ptr = pointer }, .{}); | 163 | return mod.addZIRInst(scope, src, zir.Inst.Deref, .{ .ptr = pointer }, .{}); |
| ... | @@ -296,8 +313,7 @@ fn identifier(mod: *Module, scope: *Scope, ident: *ast.Node.Identifier) InnerErr | ... | @@ -296,8 +313,7 @@ fn identifier(mod: *Module, scope: *Scope, ident: *ast.Node.Identifier) InnerErr |
| 296 | defer tracy.end(); | 313 | defer tracy.end(); |
| 297 | | 314 | |
| 298 | const tree = scope.tree(); | 315 | const tree = scope.tree(); |
| 299 | // TODO implement @"aoeu" identifiers | 316 | const ident_name = try identifierTokenString(mod, scope, ident.token); |
| 300 | const ident_name = tree.tokenSlice(ident.token); | | |
| 301 | const src = tree.token_locs[ident.token].start; | 317 | const src = tree.token_locs[ident.token].start; |
| 302 | if (mem.eql(u8, ident_name, "_")) { | 318 | if (mem.eql(u8, ident_name, "_")) { |
| 303 | return mod.failNode(scope, &ident.base, "TODO implement '_' identifier", .{}); | 319 | return mod.failNode(scope, &ident.base, "TODO implement '_' identifier", .{}); |