mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
translate-c: render variables and builtin calls
This commit is contained in:
parent
d7460db044
commit
1147ecc5fd
@ -769,7 +769,7 @@ fn transCreateNodeTypedef(
|
||||
|
||||
const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
|
||||
payload.* = .{
|
||||
.base = .{ .tag = ([2]Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] },
|
||||
.base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(toplevel)] },
|
||||
.data = .{
|
||||
.name = checked_name,
|
||||
.init = init_node,
|
||||
@ -1678,7 +1678,7 @@ fn transStringLiteralAsArray(
|
||||
init_list[i] = try transCreateCharLitNode(c, narrow, code_unit);
|
||||
}
|
||||
while (i < array_size) : (i += 1) {
|
||||
init_list[i] = try transCreateNodeNumber(c, 0);
|
||||
init_list[i] = try transCreateNodeNumber(c, 0, .int);
|
||||
}
|
||||
|
||||
return Tag.array_init.create(c.arena, init_list);
|
||||
@ -2345,7 +2345,7 @@ fn transCharLiteral(
|
||||
// C has a somewhat obscure feature called multi-character character constant
|
||||
// e.g. 'abcd'
|
||||
const int_lit_node = if (kind == .Ascii and val > 255)
|
||||
try transCreateNodeNumber(c, val)
|
||||
try transCreateNodeNumber(c, val, .int)
|
||||
else
|
||||
try transCreateCharLitNode(c, narrow, val);
|
||||
|
||||
@ -2948,7 +2948,7 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {
|
||||
fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
|
||||
// TODO use something more accurate
|
||||
const dbl = stmt.getValueAsApproximateDouble();
|
||||
const node = try transCreateNodeNumber(c, dbl);
|
||||
const node = try transCreateNodeNumber(c, dbl, .float);
|
||||
return maybeSuppressResult(c, scope, used, node);
|
||||
}
|
||||
|
||||
@ -3471,13 +3471,16 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
|
||||
const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
};
|
||||
return Tag.number_literal.create(c.arena, str);
|
||||
return Tag.integer_literal.create(c.arena, str);
|
||||
}
|
||||
|
||||
fn transCreateNodeNumber(c: *Context, int: anytype) !Node {
|
||||
const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(int))) "{d}" else "{s}";
|
||||
const str = try std.fmt.allocPrint(c.arena, fmt_s, .{int});
|
||||
return Tag.number_literal.create(c.arena, str);
|
||||
fn transCreateNodeNumber(c: *Context, num: anytype, num_kind: enum { int, float }) !Node {
|
||||
const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(num))) "{d}" else "{s}";
|
||||
const str = try std.fmt.allocPrint(c.arena, fmt_s, .{num});
|
||||
if (num_kind == .float)
|
||||
return Tag.float_literal.create(c.arena, str)
|
||||
else
|
||||
return Tag.integer_literal.create(c.arena, str);
|
||||
}
|
||||
|
||||
fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: *ast.Payload.Func) !Node {
|
||||
@ -4162,7 +4165,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
|
||||
}
|
||||
|
||||
if (suffix == .none) {
|
||||
return transCreateNodeNumber(c, lit_bytes);
|
||||
return transCreateNodeNumber(c, lit_bytes, .int);
|
||||
}
|
||||
|
||||
const type_node = try Tag.type.create(c.arena, switch (suffix) {
|
||||
@ -4179,21 +4182,21 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
|
||||
.llu => 3,
|
||||
else => unreachable,
|
||||
}];
|
||||
const rhs = try transCreateNodeNumber(c, lit_bytes);
|
||||
const rhs = try transCreateNodeNumber(c, lit_bytes, .int);
|
||||
return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
|
||||
},
|
||||
.FloatLiteral => |suffix| {
|
||||
if (lit_bytes[0] == '.')
|
||||
lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes});
|
||||
if (suffix == .none) {
|
||||
return transCreateNodeNumber(c, lit_bytes);
|
||||
return transCreateNodeNumber(c, lit_bytes, .float);
|
||||
}
|
||||
const type_node = try Tag.type.create(c.arena, switch (suffix) {
|
||||
.f => "f32",
|
||||
.l => "c_longdouble",
|
||||
else => unreachable,
|
||||
});
|
||||
const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1]);
|
||||
const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1], .float);
|
||||
return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
|
||||
},
|
||||
else => unreachable,
|
||||
@ -4369,7 +4372,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
|
||||
return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));
|
||||
} else {
|
||||
const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]});
|
||||
return Tag.number_literal.create(c.arena, str);
|
||||
return Tag.integer_literal.create(c.arena, str);
|
||||
}
|
||||
},
|
||||
.StringLiteral => {
|
||||
|
||||
@ -27,8 +27,8 @@ pub const Node = extern union {
|
||||
usingnamespace_builtins,
|
||||
// After this, the tag requires a payload.
|
||||
|
||||
// int or float, doesn't really matter
|
||||
number_literal,
|
||||
integer_literal,
|
||||
float_literal,
|
||||
string_literal,
|
||||
char_literal,
|
||||
identifier,
|
||||
@ -193,10 +193,8 @@ pub const Node = extern union {
|
||||
/// pub const alias = actual;
|
||||
alias,
|
||||
/// const name = init;
|
||||
typedef,
|
||||
var_simple,
|
||||
/// pub const name = init;
|
||||
pub_typedef,
|
||||
pub_var_simple,
|
||||
/// pub const enum_field_name = @enumToInt(enum_name.field_name);
|
||||
enum_redecl,
|
||||
@ -333,7 +331,8 @@ pub const Node = extern union {
|
||||
.ptr_cast,
|
||||
=> Payload.BinOp,
|
||||
|
||||
.number_literal,
|
||||
.integer_literal,
|
||||
.float_literal,
|
||||
.string_literal,
|
||||
.char_literal,
|
||||
.identifier,
|
||||
@ -358,7 +357,7 @@ pub const Node = extern union {
|
||||
.array_type => Payload.Array,
|
||||
.arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
|
||||
.log2_int_type => Payload.Log2IntType,
|
||||
.typedef, .pub_typedef, .var_simple, .pub_var_simple => Payload.SimpleVarDecl,
|
||||
.var_simple, .pub_var_simple => Payload.SimpleVarDecl,
|
||||
.enum_redecl => Payload.EnumRedecl,
|
||||
.array_filler => Payload.ArrayFiller,
|
||||
.pub_inline_fn => Payload.PubInlineFn,
|
||||
@ -705,7 +704,6 @@ const Context = struct {
|
||||
}
|
||||
|
||||
fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
|
||||
std.debug.assert(tag != .identifier); // use addIdentifier
|
||||
return addTokenFmt(c, tag, "{s}", .{bytes});
|
||||
}
|
||||
|
||||
@ -726,6 +724,17 @@ const Context = struct {
|
||||
try c.nodes.append(c.gpa, elem);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn addExtra(c: *Context, extra: anytype) Allocator.Error!NodeIndex {
|
||||
const fields = std.meta.fields(@TypeOf(extra));
|
||||
try c.extra_data.ensureCapacity(c.gpa, c.extra_data.items.len + fields.len);
|
||||
const result = @intCast(u32, c.extra_data.items.len);
|
||||
inline for (fields) |field| {
|
||||
comptime std.debug.assert(field.field_type == NodeIndex);
|
||||
c.extra_data.appendAssumeCapacity(@field(extra, field.name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
|
||||
@ -734,7 +743,8 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
|
||||
|
||||
for (nodes) |node| {
|
||||
const res = try renderNode(c, node);
|
||||
if (res == 0) continue;
|
||||
if (node.tag() == .warning) continue;
|
||||
if (c.nodes.items(.tag)[res] == .identifier) continue; // TODO remove
|
||||
try result.append(res);
|
||||
}
|
||||
|
||||
@ -744,10 +754,10 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
|
||||
fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
switch (node.tag()) {
|
||||
.warning => {
|
||||
const payload = node.castTag(.warning).?;
|
||||
try c.buf.appendSlice(payload.data);
|
||||
const payload = node.castTag(.warning).?.data;
|
||||
try c.buf.appendSlice(payload);
|
||||
try c.buf.append('\n');
|
||||
return 0;
|
||||
return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
|
||||
},
|
||||
.usingnamespace_builtins => {
|
||||
// pub usingnamespace @import("std").c.builtins;
|
||||
@ -766,34 +776,34 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
});
|
||||
},
|
||||
.std_math_Log2Int => {
|
||||
const payload = node.castTag(.std_math_Log2Int).?;
|
||||
const payload = node.castTag(.std_math_Log2Int).?.data;
|
||||
const import_node = try renderStdImport(c, "math", "Log2Int");
|
||||
return renderCall(c, import_node, &.{payload.data});
|
||||
return renderCall(c, import_node, &.{payload});
|
||||
},
|
||||
.std_meta_cast => {
|
||||
const payload = node.castTag(.std_meta_cast).?;
|
||||
const payload = node.castTag(.std_meta_cast).?.data;
|
||||
const import_node = try renderStdImport(c, "meta", "cast");
|
||||
return renderCall(c, import_node, &.{ payload.data.lhs, payload.data.rhs });
|
||||
return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.std_meta_sizeof => {
|
||||
const payload = node.castTag(.std_meta_sizeof).?;
|
||||
const payload = node.castTag(.std_meta_sizeof).?.data;
|
||||
const import_node = try renderStdImport(c, "meta", "sizeof");
|
||||
return renderCall(c, import_node, &.{payload.data});
|
||||
return renderCall(c, import_node, &.{payload});
|
||||
},
|
||||
.std_mem_zeroes => {
|
||||
const payload = node.castTag(.std_mem_zeroes).?;
|
||||
const payload = node.castTag(.std_mem_zeroes).?.data;
|
||||
const import_node = try renderStdImport(c, "mem", "zeroes");
|
||||
return renderCall(c, import_node, &.{payload.data});
|
||||
return renderCall(c, import_node, &.{payload});
|
||||
},
|
||||
.std_mem_zeroinit => {
|
||||
const payload = node.castTag(.std_mem_zeroinit).?;
|
||||
const payload = node.castTag(.std_mem_zeroinit).?.data;
|
||||
const import_node = try renderStdImport(c, "mem", "zeroInit");
|
||||
return renderCall(c, import_node, &.{ payload.data.lhs, payload.data.rhs });
|
||||
return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.call => {
|
||||
const payload = node.castTag(.call).?;
|
||||
const lhs = try renderNode(c, payload.data.lhs);
|
||||
return renderCall(c, lhs, payload.data.args);
|
||||
const payload = node.castTag(.call).?.data;
|
||||
const lhs = try renderNode(c, payload.lhs);
|
||||
return renderCall(c, lhs, payload.args);
|
||||
},
|
||||
.null_literal => return c.addNode(.{
|
||||
.tag = .null_literal,
|
||||
@ -860,10 +870,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
},
|
||||
}),
|
||||
.type => {
|
||||
const payload = node.castTag(.type).?;
|
||||
const payload = node.castTag(.type).?.data;
|
||||
return c.addNode(.{
|
||||
.tag = .identifier,
|
||||
.main_token = try c.addToken(.identifier, payload.data),
|
||||
.main_token = try c.addToken(.identifier, payload),
|
||||
.data = .{
|
||||
.lhs = undefined,
|
||||
.rhs = undefined,
|
||||
@ -871,22 +881,32 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
});
|
||||
},
|
||||
.identifier => {
|
||||
const payload = node.castTag(.identifier).?;
|
||||
const payload = node.castTag(.identifier).?.data;
|
||||
return c.addNode(.{
|
||||
.tag = .identifier,
|
||||
.main_token = try c.addIdentifier(payload.data),
|
||||
.main_token = try c.addIdentifier(payload),
|
||||
.data = .{
|
||||
.lhs = undefined,
|
||||
.rhs = undefined,
|
||||
},
|
||||
});
|
||||
},
|
||||
.number_literal => {
|
||||
const payload = node.castTag(.number_literal).?;
|
||||
.float_literal => {
|
||||
const payload = node.castTag(.float_literal).?.data;
|
||||
return c.addNode(.{
|
||||
.tag = .identifier,
|
||||
// might be integer or float, but it doesn't matter for rendering
|
||||
.main_token = try c.addToken(.integer_literal, payload.data),
|
||||
.tag = .float_literal,
|
||||
.main_token = try c.addToken(.float_literal, payload),
|
||||
.data = .{
|
||||
.lhs = undefined,
|
||||
.rhs = undefined,
|
||||
},
|
||||
});
|
||||
},
|
||||
.integer_literal => {
|
||||
const payload = node.castTag(.integer_literal).?.data;
|
||||
return c.addNode(.{
|
||||
.tag = .integer_literal,
|
||||
.main_token = try c.addToken(.integer_literal, payload),
|
||||
.data = .{
|
||||
.lhs = undefined,
|
||||
.rhs = undefined,
|
||||
@ -894,10 +914,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
});
|
||||
},
|
||||
.string_literal => {
|
||||
const payload = node.castTag(.string_literal).?;
|
||||
const payload = node.castTag(.string_literal).?.data;
|
||||
return c.addNode(.{
|
||||
.tag = .identifier,
|
||||
.main_token = try c.addToken(.char_literal, payload.data),
|
||||
.main_token = try c.addToken(.string_literal, payload),
|
||||
.data = .{
|
||||
.lhs = undefined,
|
||||
.rhs = undefined,
|
||||
@ -905,10 +925,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
});
|
||||
},
|
||||
.char_literal => {
|
||||
const payload = node.castTag(.char_literal).?;
|
||||
const payload = node.castTag(.char_literal).?.data;
|
||||
return c.addNode(.{
|
||||
.tag = .identifier,
|
||||
.main_token = try c.addToken(.string_literal, payload.data),
|
||||
.main_token = try c.addToken(.string_literal, payload),
|
||||
.data = .{
|
||||
.lhs = undefined,
|
||||
.rhs = undefined,
|
||||
@ -916,17 +936,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
});
|
||||
},
|
||||
.fail_decl => {
|
||||
const payload = node.castTag(.fail_decl).?;
|
||||
const payload = node.castTag(.fail_decl).?.data;
|
||||
// pub const name = @compileError(msg);
|
||||
_ = try c.addToken(.keyword_pub, "pub");
|
||||
const const_kw = try c.addToken(.keyword_const, "const");
|
||||
_ = try c.addIdentifier(payload.data.actual);
|
||||
const const_tok = try c.addToken(.keyword_const, "const");
|
||||
_ = try c.addIdentifier(payload.actual);
|
||||
_ = try c.addToken(.equal, "=");
|
||||
|
||||
|
||||
const compile_error_tok = try c.addToken(.builtin, "@compileError");
|
||||
_ = try c.addToken(.l_paren, "(");
|
||||
const err_msg_tok = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(payload.data.mangled)});
|
||||
const err_msg_tok = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(payload.mangled)});
|
||||
const err_msg = try c.addNode(.{
|
||||
.tag = .string_literal,
|
||||
.main_token = err_msg_tok,
|
||||
@ -948,17 +967,105 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
|
||||
return c.addNode(.{
|
||||
.tag = .simple_var_decl,
|
||||
.main_token = const_kw,
|
||||
.main_token = const_tok,
|
||||
.data = .{
|
||||
.lhs = 0,
|
||||
.rhs = compile_error,
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
else => {
|
||||
try c.buf.writer().print("// TODO renderNode {}\n", .{node.tag()});
|
||||
return @as(u32, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
|
||||
.pub_var_simple, .var_simple => {
|
||||
const payload = @fieldParentPtr(Payload.SimpleVarDecl, "base", node.ptr_otherwise).data;
|
||||
if (node.tag() == .pub_var_simple) _ = try c.addToken(.keyword_pub, "pub");
|
||||
const const_tok = try c.addToken(.keyword_const, "const");
|
||||
_ = try c.addIdentifier(payload.name);
|
||||
_ = try c.addToken(.equal, "=");
|
||||
|
||||
const init = try renderNode(c, payload.init);
|
||||
_ = try c.addToken(.semicolon, ";");
|
||||
|
||||
return c.addNode(.{
|
||||
.tag = .simple_var_decl,
|
||||
.main_token = const_tok,
|
||||
.data = .{
|
||||
.lhs = 0,
|
||||
.rhs = init,
|
||||
},
|
||||
});
|
||||
},
|
||||
.var_decl => return renderVar(c, node),
|
||||
.int_cast => {
|
||||
const payload = node.castTag(.int_cast).?.data;
|
||||
return renderBuiltinCall(c, "@intCast", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.rem => {
|
||||
const payload = node.castTag(.rem).?.data;
|
||||
return renderBuiltinCall(c, "@rem", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.div_trunc => {
|
||||
const payload = node.castTag(.div_trunc).?.data;
|
||||
return renderBuiltinCall(c, "@divTrunc", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.bool_to_int => {
|
||||
const payload = node.castTag(.bool_to_int).?.data;
|
||||
return renderBuiltinCall(c, "@boolToInt", &.{payload});
|
||||
},
|
||||
.as => {
|
||||
const payload = node.castTag(.as).?.data;
|
||||
return renderBuiltinCall(c, "@as", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.truncate => {
|
||||
const payload = node.castTag(.truncate).?.data;
|
||||
return renderBuiltinCall(c, "@truncate", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.bit_cast => {
|
||||
const payload = node.castTag(.bit_cast).?.data;
|
||||
return renderBuiltinCall(c, "@bitCast", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.float_cast => {
|
||||
const payload = node.castTag(.float_cast).?.data;
|
||||
return renderBuiltinCall(c, "@floatCast", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.float_to_int => {
|
||||
const payload = node.castTag(.float_to_int).?.data;
|
||||
return renderBuiltinCall(c, "@floatToInt", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.int_to_float => {
|
||||
const payload = node.castTag(.int_to_float).?.data;
|
||||
return renderBuiltinCall(c, "@intToFloat", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.int_to_enum => {
|
||||
const payload = node.castTag(.int_to_enum).?.data;
|
||||
return renderBuiltinCall(c, "@intToEnum", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.enum_to_int => {
|
||||
const payload = node.castTag(.enum_to_int).?.data;
|
||||
return renderBuiltinCall(c, "@enumToInt", &.{payload});
|
||||
},
|
||||
.int_to_ptr => {
|
||||
const payload = node.castTag(.int_to_ptr).?.data;
|
||||
return renderBuiltinCall(c, "@intToPtr", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.ptr_to_int => {
|
||||
const payload = node.castTag(.ptr_to_int).?.data;
|
||||
return renderBuiltinCall(c, "@ptrToInt", &.{payload});
|
||||
},
|
||||
.align_cast => {
|
||||
const payload = node.castTag(.align_cast).?.data;
|
||||
return renderBuiltinCall(c, "@alignCast", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
.ptr_cast => {
|
||||
const payload = node.castTag(.ptr_cast).?.data;
|
||||
return renderBuiltinCall(c, "@ptrCast", &.{ payload.lhs, payload.rhs });
|
||||
},
|
||||
else => return c.addNode(.{
|
||||
.tag = .identifier,
|
||||
.main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}),
|
||||
.data = .{
|
||||
.lhs = undefined,
|
||||
.rhs = undefined,
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,3 +1157,114 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {
|
||||
_ = try c.addToken(.r_paren, ")");
|
||||
return res;
|
||||
}
|
||||
|
||||
fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !NodeIndex {
|
||||
const builtin_tok = try c.addToken(.builtin, builtin);
|
||||
_ = try c.addToken(.l_paren, "(");
|
||||
var arg_1: NodeIndex = 0;
|
||||
var arg_2: NodeIndex = 0;
|
||||
switch (args.len) {
|
||||
0 => {},
|
||||
1 => {
|
||||
arg_1 = try renderNode(c, args[0]);
|
||||
},
|
||||
2 => {
|
||||
arg_1 = try renderNode(c, args[0]);
|
||||
_ = try c.addToken(.comma, ",");
|
||||
arg_2 = try renderNode(c, args[1]);
|
||||
},
|
||||
else => unreachable, // expand this function as needed.
|
||||
}
|
||||
|
||||
_ = try c.addToken(.r_paren, ")");
|
||||
return c.addNode(.{
|
||||
.tag = .builtin_call_two,
|
||||
.main_token = builtin_tok,
|
||||
.data = .{
|
||||
.lhs = arg_1,
|
||||
.rhs = arg_2,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn renderVar(c: *Context, node: Node) !NodeIndex {
|
||||
const payload = node.castTag(.var_decl).?.data;
|
||||
if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
|
||||
if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
|
||||
if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
|
||||
const mut_tok = if (payload.is_const)
|
||||
try c.addToken(.keyword_const, "const")
|
||||
else
|
||||
try c.addToken(.keyword_var, "var");
|
||||
_ = try c.addIdentifier(payload.name);
|
||||
_ = try c.addToken(.colon, ":");
|
||||
const type_node = try renderNode(c, payload.type);
|
||||
|
||||
const align_node = if (payload.alignment) |some| blk: {
|
||||
_ = try c.addToken(.keyword_align, "align");
|
||||
_ = try c.addToken(.l_paren, "(");
|
||||
const res = try c.addNode(.{
|
||||
.tag = .integer_literal,
|
||||
.main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),
|
||||
.data = .{ .lhs = undefined, .rhs = undefined },
|
||||
});
|
||||
_ = try c.addToken(.r_paren, ")");
|
||||
break :blk res;
|
||||
} else 0;
|
||||
|
||||
const section_node = if (payload.linksection_string) |some| blk: {
|
||||
_ = try c.addToken(.keyword_linksection, "linksection");
|
||||
_ = try c.addToken(.l_paren, "(");
|
||||
const res = try c.addNode(.{
|
||||
.tag = .string_literal,
|
||||
.main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),
|
||||
.data = .{ .lhs = undefined, .rhs = undefined },
|
||||
});
|
||||
_ = try c.addToken(.r_paren, ")");
|
||||
break :blk res;
|
||||
} else 0;
|
||||
|
||||
const init_node = if (payload.init) |some| blk: {
|
||||
_ = try c.addToken(.equal, "=");
|
||||
break :blk try renderNode(c, some);
|
||||
} else 0;
|
||||
_ = try c.addToken(.semicolon, ";");
|
||||
|
||||
if (section_node == 0) {
|
||||
if (align_node == 0) {
|
||||
return c.addNode(.{
|
||||
.tag = .simple_var_decl,
|
||||
.main_token = mut_tok,
|
||||
.data = .{
|
||||
.lhs = type_node,
|
||||
.rhs = init_node,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return c.addNode(.{
|
||||
.tag = .local_var_decl,
|
||||
.main_token = mut_tok,
|
||||
.data = .{
|
||||
.lhs = try c.addExtra(std.zig.ast.Node.LocalVarDecl{
|
||||
.type_node = type_node,
|
||||
.align_node = align_node,
|
||||
}),
|
||||
.rhs = init_node,
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return c.addNode(.{
|
||||
.tag = .global_var_decl,
|
||||
.main_token = mut_tok,
|
||||
.data = .{
|
||||
.lhs = try c.addExtra(std.zig.ast.Node.GlobalVarDecl{
|
||||
.type_node = type_node,
|
||||
.align_node = align_node,
|
||||
.section_node = section_node,
|
||||
}),
|
||||
.rhs = init_node,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user