authorgravatar for pfg@pfg.pwpfg <pfg@pfg.pw> 2020-07-16 14:08:36-07:00
committergravatar for pfg@pfg.pwpfg <pfg@pfg.pw> 2020-07-16 14:08:36-07:00
log86922b8d0812977df667c0872c54c7f9c44493d7
treedefcc27a2584b74978b3941f927d29cc3653dac8
parent83a0073b68f905786caccf5ce7907b7e562096fd

stage2: support @"identifier" syntax


1 files changed, 26 insertions(+), 10 deletions(-)

src-self-hosted/astgen.zig+26-10
...@@ -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" identifiers95 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}
125125
126/// Identifier nodes -> ZIR string instruction126/// Identifier token -> String (allocated in scope.arena())
127pub fn identifierString(mod: *Module, scope: *Scope, node: *ast.Node.Identifier) InnerError!*zir.Inst {127pub 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
146pub 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;
130149
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];
134151
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;
141158
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).?);
144161
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();
297314
298 const tree = scope.tree();315 const tree = scope.tree();
299 // TODO implement @"aoeu" identifiers316 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", .{});