aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/translate_c.zig4
-rw-r--r--src/translate_c/ast.zig262
2 files changed, 234 insertions, 32 deletions
diff --git a/src/translate_c.zig b/src/translate_c.zig
index 821f3c5b74..03695186ec 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -3049,7 +3049,7 @@ fn maybeSuppressResult(
result: Node,
) TransError!Node {
if (used == .used) return result;
- return Tag.ignore.create(c.arena, result);
+ return Tag.discard.create(c.arena, result);
}
fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
@@ -4127,7 +4127,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
var last = node;
while (true) {
// suppress result
- const ignore = try Tag.ignore.create(c.arena, last);
+ const ignore = try Tag.discard.create(c.arena, last);
try block_scope.statements.append(ignore);
last = try parseCCondExpr(c, m, scope);
diff --git a/src/translate_c/ast.zig b/src/translate_c/ast.zig
index 282e645f2e..3bc1dc986f 100644
--- a/src/translate_c/ast.zig
+++ b/src/translate_c/ast.zig
@@ -60,6 +60,7 @@ pub const Node = extern union {
tuple,
container_init,
std_meta_cast,
+ /// _ = operand;
discard,
// a + b
@@ -67,43 +68,30 @@ pub const Node = extern union {
// a = b
add_assign,
// c = (a = b)
- add_assign_value,
add_wrap,
add_wrap_assign,
- add_wrap_assign_value,
sub,
sub_assign,
- sub_assign_value,
sub_wrap,
sub_wrap_assign,
- sub_wrap_assign_value,
mul,
mul_assign,
- mul_assign_value,
mul_wrap,
mul_wrap_assign,
- mul_wrap_assign_value,
div,
div_assign,
- div_assign_value,
shl,
shl_assign,
- shl_assign_value,
shr,
shr_assign,
- shr_assign_value,
mod,
mod_assign,
- mod_assign_value,
@"and",
and_assign,
- and_assign_value,
@"or",
or_assign,
- or_assign_value,
xor,
xor_assign,
- xor_assign_value,
less_than,
less_than_equal,
greater_than,
@@ -207,9 +195,6 @@ pub const Node = extern union {
/// [1]type{val} ** count
array_filler,
- /// _ = operand;
- ignore,
-
pub const last_no_payload_tag = Tag.usingnamespace_builtins;
pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
@@ -249,7 +234,6 @@ pub const Node = extern union {
.while_true,
.if_not_break,
.switch_else,
- .ignore,
.block_single,
.std_meta_sizeof,
.bool_to_int,
@@ -260,43 +244,30 @@ pub const Node = extern union {
.add,
.add_assign,
- .add_assign_value,
.add_wrap,
.add_wrap_assign,
- .add_wrap_assign_value,
.sub,
.sub_assign,
- .sub_assign_value,
.sub_wrap,
.sub_wrap_assign,
- .sub_wrap_assign_value,
.mul,
.mul_assign,
- .mul_assign_value,
.mul_wrap,
.mul_wrap_assign,
- .mul_wrap_assign_value,
.div,
.div_assign,
- .div_assign_value,
.shl,
.shl_assign,
- .shl_assign_value,
.shr,
.shr_assign,
- .shr_assign_value,
.mod,
.mod_assign,
- .mod_assign_value,
.@"and",
.and_assign,
- .and_assign_value,
.@"or",
.or_assign,
- .or_assign_value,
.xor,
.xor_assign,
- .xor_assign_value,
.less_than,
.less_than_equal,
.greater_than,
@@ -869,6 +840,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
.rhs = undefined,
},
}),
+ .noreturn_type => return try c.addNode(.{
+ .tag = .identifier,
+ .main_token = try c.addToken(.identifier, "noreturn"),
+ .data = .{
+ .lhs = undefined,
+ .rhs = undefined,
+ },
+ }),
.type => {
const payload = node.castTag(.type).?.data;
return c.addNode(.{
@@ -880,6 +859,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
},
});
},
+ .log2_int_type => {
+ const payload = node.castTag(.log2_int_type).?.data;
+ return c.addNode(.{
+ .tag = .identifier,
+ .main_token = try c.addTokenFmt(.identifier, "u{d}", .{payload}),
+ .data = .{
+ .lhs = undefined,
+ .rhs = undefined,
+ },
+ });
+ },
.identifier => {
const payload = node.castTag(.identifier).?.data;
return c.addNode(.{
@@ -1058,6 +1048,51 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
const payload = node.castTag(.ptr_cast).?.data;
return renderBuiltinCall(c, "@ptrCast", &.{ payload.lhs, payload.rhs });
},
+ .sizeof => {
+ const payload = node.castTag(.sizeof).?.data;
+ return renderBuiltinCall(c, "@sizeOf", &.{payload});
+ },
+ .alignof => {
+ const payload = node.castTag(.alignof).?.data;
+ return renderBuiltinCall(c, "@alignOf", &.{payload});
+ },
+ .typeof => {
+ const payload = node.castTag(.typeof).?.data;
+ return renderBuiltinCall(c, "@TypeOf", &.{payload});
+ },
+ .negate => return renderPrefixOp(c, node, .negation, .minus, "-"),
+ .negate_wrap => return renderPrefixOp(c, node, .negation_wrap, .minus_percent, "-%"),
+ .bit_not => return renderPrefixOp(c, node, .bit_not, .tilde, "~"),
+ .not => return renderPrefixOp(c, node, .bool_not, .bang, "!"),
+ .optional_type => return renderPrefixOp(c, node, .optional_type, .question_mark, "?"),
+ .address_of => return renderPrefixOp(c, node, .address_of, .ampersand, "&"),
+ .deref => {
+ const payload = node.castTag(.deref).?.data;
+ const operand = try renderNodeGrouped(c, payload);
+ const deref_tok = try c.addToken(.period_asterisk, ".*");
+ return c.addNode(.{
+ .tag = .deref,
+ .main_token = deref_tok,
+ .data = .{
+ .lhs = operand,
+ .rhs = undefined,
+ },
+ });
+ },
+ .unwrap => {
+ const payload = node.castTag(.unwrap).?.data;
+ const operand = try renderNodeGrouped(c, payload);
+ const period = try c.addToken(.period, ".");
+ const question_mark = try c.addToken(.question_mark, "?");
+ return c.addNode(.{
+ .tag = .unwrap_optional,
+ .main_token = period,
+ .data = .{
+ .lhs = operand,
+ .rhs = question_mark,
+ },
+ });
+ },
else => return c.addNode(.{
.tag = .identifier,
.main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}),
@@ -1069,6 +1104,173 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
}
}
+fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
+ switch (node.tag()) {
+ .null_literal,
+ .undefined_literal,
+ .true_literal,
+ .false_literal,
+ .return_void,
+ .zero_literal,
+ .one_literal,
+ .void_type,
+ .noreturn_type,
+ .@"anytype",
+ .div_trunc,
+ .rem,
+ .int_cast,
+ .as,
+ .truncate,
+ .bit_cast,
+ .float_cast,
+ .float_to_int,
+ .int_to_float,
+ .int_to_enum,
+ .int_to_ptr,
+ .std_mem_zeroes,
+ .std_math_Log2Int,
+ .log2_int_type,
+ .ptr_to_int,
+ .enum_to_int,
+ .sizeof,
+ .alignof,
+ .typeof,
+ .std_meta_sizeof,
+ .std_meta_cast,
+ .std_mem_zeroinit,
+ .integer_literal,
+ .float_literal,
+ .string_literal,
+ .char_literal,
+ .identifier,
+ .field_access,
+ .ptr_cast,
+ .type,
+ .array_access,
+ .align_cast,
+ => {
+ // no grouping needed
+ return renderNode(c, node);
+ },
+
+ .negate,
+ .negate_wrap,
+ .bit_not,
+ .opaque_literal,
+ .not,
+ .optional_type,
+ .address_of,
+ .unwrap,
+ .deref,
+ .empty_array,
+ .block_single,
+ .bool_to_int,
+ .add,
+ .add_wrap,
+ .sub,
+ .sub_wrap,
+ .mul,
+ .mul_wrap,
+ .div,
+ .shl,
+ .shr,
+ .mod,
+ .@"and",
+ .@"or",
+ .xor,
+ .less_than,
+ .less_than_equal,
+ .greater_than,
+ .greater_than_equal,
+ .equal,
+ .not_equal,
+ .bit_and,
+ .bit_or,
+ .bit_xor,
+ .empty_block,
+ .array_cat,
+ .array_filler,
+ .@"if",
+ .call,
+ .@"enum",
+ .@"struct",
+ .@"union",
+ .array_init,
+ .tuple,
+ .container_init,
+ .block,
+ .c_pointer,
+ .single_pointer,
+ .array_type,
+ => return c.addNode(.{
+ .tag = .grouped_expression,
+ .main_token = try c.addToken(.l_paren, "("),
+ .data = .{
+ .lhs = try renderNode(c, node),
+ .rhs = try c.addToken(.r_paren, ")"),
+ },
+ }),
+ .ellipsis3,
+ .switch_prong,
+ .warning,
+ .var_decl,
+ .func,
+ .fail_decl,
+ .arg_redecl,
+ .alias,
+ .var_simple,
+ .pub_var_simple,
+ .enum_redecl,
+ .@"while",
+ .@"switch",
+ .@"break",
+ .break_val,
+ .pub_inline_fn,
+ .discard,
+ .@"continue",
+ .@"return",
+ .usingnamespace_builtins,
+ .while_true,
+ .if_not_break,
+ .switch_else,
+ .add_assign,
+ .add_wrap_assign,
+ .sub_assign,
+ .sub_wrap_assign,
+ .mul_assign,
+ .mul_wrap_assign,
+ .div_assign,
+ .shl_assign,
+ .shr_assign,
+ .mod_assign,
+ .and_assign,
+ .or_assign,
+ .xor_assign,
+ .bit_and_assign,
+ .bit_or_assign,
+ .bit_xor_assign,
+ .assign,
+ => {
+ // these should never appear in places where grouping might be needed.
+ unreachable;
+ },
+ }
+}
+
+fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
+ const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;
+ const tok = try c.addToken(tok_tag, bytes);
+ const operand = try renderNodeGrouped(c, payload);
+ return c.addNode(.{
+ .tag = tag,
+ .main_token = tok,
+ .data = .{
+ .lhs = operand,
+ .rhs = undefined,
+ },
+ });
+}
+
fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {
const import_tok = try c.addToken(.builtin, "@import");
_ = try c.addToken(.l_paren, "(");