feature. See also
. The project being documented here (as the example) is the Zig library itself.
MacroTranslator.parseCPostfixExprInner
fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) ParseError!ZigNode
File
Code
fn parseCPostfixExprInner(mt: *MacroTranslator, scope: *Scope, type_name: ?ZigNode) ParseError!ZigNode {
const gpa = mt.t.gpa;
const arena = mt.t.arena;
var node = type_name orelse try mt.parseCPrimaryExpr(scope);
while (true) {
switch (mt.peek()) {
.period => {
mt.i += 1;
const tok = mt.tokens[mt.i];
if (tok.id == .macro_param or tok.id == .macro_param_no_expand) {
const param = mt.macro.params[tok.end];
mt.i += 1;
const mangled_name = scope.getAlias(param) orelse param;
const field_name = try ZigTag.identifier.create(arena, mangled_name);
node = try ZigTag.field_builtin.create(arena, .{ .lhs = node, .rhs = field_name });
continue;
}
const field_name = mt.tokSlice();
try mt.expect(.identifier);
node = try ZigTag.field_access.create(arena, .{ .lhs = node, .field_name = field_name });
},
.arrow => {
mt.i += 1;
const tok = mt.tokens[mt.i];
if (tok.id == .macro_param or tok.id == .macro_param_no_expand) {
const param = mt.macro.params[tok.end];
mt.i += 1;
const mangled_name = scope.getAlias(param) orelse param;
const field_name = try ZigTag.identifier.create(arena, mangled_name);
node = try ZigTag.field_builtin.create(arena, .{ .lhs = node, .rhs = field_name });
continue;
}
const field_name = mt.tokSlice();
try mt.expect(.identifier);
const deref = try ZigTag.deref.create(arena, node);
node = try ZigTag.field_access.create(arena, .{ .lhs = deref, .field_name = field_name });
},
.l_bracket => {
mt.i += 1;
const index_val = try mt.macroIntFromBool(try mt.parseCExpr(scope));
const index = try ZigTag.as.create(arena, .{
.lhs = try ZigTag.type.create(arena, "usize"),
.rhs = try ZigTag.int_cast.create(arena, index_val),
});
node = try ZigTag.array_access.create(arena, .{ .lhs = node, .rhs = index });
try mt.expect(.r_bracket);
},
.l_paren => {
mt.i += 1;
if (mt.eat(.r_paren)) {
node = try ZigTag.call.create(arena, .{ .lhs = node, .args = &.{} });
} else {
var args: std.ArrayList(ZigNode) = .empty;
defer args.deinit(gpa);
while (true) {
const arg = try mt.parseCCondExpr(scope);
try args.append(gpa, arg);
const next_id = mt.peek();
switch (next_id) {
.comma => {
mt.i += 1;
},
.r_paren => {
mt.i += 1;
break;
},
else => {
try mt.fail("unable to translate C expr: expected ',' or ')' instead got '{s}'", .{next_id.symbol()});
return error.ParseError;
},
}
}
node = try ZigTag.call.create(arena, .{ .lhs = node, .args = try arena.dupe(ZigNode, args.items) });
}
},
.l_brace => {
mt.i += 1;
if (mt.peek() == .period) {
var init_vals: std.ArrayList(ast.Payload.ContainerInitDot.Initializer) = .empty;
defer init_vals.deinit(gpa);
while (true) {
try mt.expect(.period);
const name = mt.tokSlice();
try mt.expect(.identifier);
try mt.expect(.equal);
const val = try mt.parseCCondExpr(scope);
try init_vals.append(gpa, .{ .name = name, .value = val });
const next_id = mt.peek();
switch (next_id) {
.comma => {
mt.i += 1;
},
.r_brace => {
mt.i += 1;
break;
},
else => {
try mt.fail("unable to translate C expr: expected ',' or '}}' instead got '{s}'", .{next_id.symbol()});
return error.ParseError;
},
}
}
const tuple_node = try ZigTag.container_init_dot.create(arena, try arena.dupe(ast.Payload.ContainerInitDot.Initializer, init_vals.items));
node = try ZigTag.std_mem_zeroinit.create(arena, .{ .lhs = node, .rhs = tuple_node });
continue;
}
var init_vals: std.ArrayList(ZigNode) = .empty;
defer init_vals.deinit(gpa);
while (true) {
const val = try mt.parseCCondExpr(scope);
try init_vals.append(gpa, val);
const next_id = mt.peek();
switch (next_id) {
.comma => {
mt.i += 1;
},
.r_brace => {
mt.i += 1;
break;
},
else => {
try mt.fail("unable to translate C expr: expected ',' or '}}' instead got '{s}'", .{next_id.symbol()});
return error.ParseError;
},
}
}
const tuple_node = try ZigTag.tuple.create(arena, try arena.dupe(ZigNode, init_vals.items));
node = try ZigTag.std_mem_zeroinit.create(arena, .{ .lhs = node, .rhs = tuple_node });
},
.plus_plus, .minus_minus => {
try mt.fail("TODO postfix inc/dec expr", .{});
return error.ParseError;
},
else => return node,
}
}
}