mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 03:03:09 +00:00
translate-c: render a bunch of simple nodes and calls
This commit is contained in:
parent
13a9db2085
commit
d7460db044
@ -550,14 +550,11 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
|
|||||||
|
|
||||||
.builtin_call_two, .builtin_call_two_comma => {
|
.builtin_call_two, .builtin_call_two_comma => {
|
||||||
if (datas[node].lhs == 0) {
|
if (datas[node].lhs == 0) {
|
||||||
const params = [_]ast.Node.Index{};
|
return renderBuiltinCall(ais, tree, main_tokens[node], &.{}, space);
|
||||||
return renderBuiltinCall(ais, tree, main_tokens[node], ¶ms, space);
|
|
||||||
} else if (datas[node].rhs == 0) {
|
} else if (datas[node].rhs == 0) {
|
||||||
const params = [_]ast.Node.Index{datas[node].lhs};
|
return renderBuiltinCall(ais, tree, main_tokens[node], &.{datas[node].lhs}, space);
|
||||||
return renderBuiltinCall(ais, tree, main_tokens[node], ¶ms, space);
|
|
||||||
} else {
|
} else {
|
||||||
const params = [_]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
|
return renderBuiltinCall(ais, tree, main_tokens[node], &.{ datas[node].lhs, datas[node].rhs }, space);
|
||||||
return renderBuiltinCall(ais, tree, main_tokens[node], ¶ms, space);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.builtin_call, .builtin_call_comma => {
|
.builtin_call, .builtin_call_comma => {
|
||||||
|
|||||||
@ -3054,6 +3054,7 @@ fn maybeSuppressResult(
|
|||||||
|
|
||||||
fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
|
fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
|
||||||
_ = try c.global_scope.sym_table.put(name, decl_node);
|
_ = try c.global_scope.sym_table.put(name, decl_node);
|
||||||
|
try c.global_scope.nodes.append(decl_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translate a qual type for a variable with an initializer. The initializer
|
/// Translate a qual type for a variable with an initializer. The initializer
|
||||||
@ -3903,10 +3904,10 @@ fn fail(
|
|||||||
pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) Error!void {
|
pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) Error!void {
|
||||||
// location
|
// location
|
||||||
// pub const name = @compileError(msg);
|
// pub const name = @compileError(msg);
|
||||||
|
const fail_msg = try std.fmt.allocPrint(c.arena, format, args);
|
||||||
|
try c.global_scope.nodes.append(try Tag.fail_decl.create(c.arena, .{ .actual = name, .mangled = fail_msg }));
|
||||||
const location_comment = try std.fmt.allocPrint(c.arena, "// {s}", .{c.locStr(loc)});
|
const location_comment = try std.fmt.allocPrint(c.arena, "// {s}", .{c.locStr(loc)});
|
||||||
try c.global_scope.nodes.append(try Tag.warning.create(c.arena, location_comment));
|
try c.global_scope.nodes.append(try Tag.warning.create(c.arena, location_comment));
|
||||||
const fail_msg = try std.fmt.allocPrint(c.arena, format, args);
|
|
||||||
try c.global_scope.nodes.append(try Tag.fail_decl.create(c.arena, fail_msg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeErrors(errors: []ClangErrMsg) void {
|
pub fn freeErrors(errors: []ClangErrMsg) void {
|
||||||
|
|||||||
@ -52,7 +52,6 @@ pub const Node = extern union {
|
|||||||
var_decl,
|
var_decl,
|
||||||
func,
|
func,
|
||||||
warning,
|
warning,
|
||||||
failed_decl,
|
|
||||||
/// All enums are non-exhaustive
|
/// All enums are non-exhaustive
|
||||||
@"enum",
|
@"enum",
|
||||||
@"struct",
|
@"struct",
|
||||||
@ -339,9 +338,7 @@ pub const Node = extern union {
|
|||||||
.char_literal,
|
.char_literal,
|
||||||
.identifier,
|
.identifier,
|
||||||
.warning,
|
.warning,
|
||||||
.failed_decl,
|
|
||||||
.type,
|
.type,
|
||||||
.fail_decl,
|
|
||||||
=> Payload.Value,
|
=> Payload.Value,
|
||||||
.@"if" => Payload.If,
|
.@"if" => Payload.If,
|
||||||
.@"while" => Payload.While,
|
.@"while" => Payload.While,
|
||||||
@ -359,7 +356,7 @@ pub const Node = extern union {
|
|||||||
.block => Payload.Block,
|
.block => Payload.Block,
|
||||||
.c_pointer, .single_pointer => Payload.Pointer,
|
.c_pointer, .single_pointer => Payload.Pointer,
|
||||||
.array_type => Payload.Array,
|
.array_type => Payload.Array,
|
||||||
.arg_redecl, .alias => Payload.ArgRedecl,
|
.arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
|
||||||
.log2_int_type => Payload.Log2IntType,
|
.log2_int_type => Payload.Log2IntType,
|
||||||
.typedef, .pub_typedef, .var_simple, .pub_var_simple => Payload.SimpleVarDecl,
|
.typedef, .pub_typedef, .var_simple, .pub_var_simple => Payload.SimpleVarDecl,
|
||||||
.enum_redecl => Payload.EnumRedecl,
|
.enum_redecl => Payload.EnumRedecl,
|
||||||
@ -695,7 +692,7 @@ const Context = struct {
|
|||||||
extra_data: std.ArrayListUnmanaged(std.zig.ast.Node.Index) = .{},
|
extra_data: std.ArrayListUnmanaged(std.zig.ast.Node.Index) = .{},
|
||||||
tokens: std.zig.ast.TokenList = .{},
|
tokens: std.zig.ast.TokenList = .{},
|
||||||
|
|
||||||
fn appendTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
|
fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
|
||||||
const start_index = c.buf.items.len;
|
const start_index = c.buf.items.len;
|
||||||
try c.buf.writer().print(format ++ " ", args);
|
try c.buf.writer().print(format ++ " ", args);
|
||||||
|
|
||||||
@ -707,13 +704,13 @@ const Context = struct {
|
|||||||
return @intCast(u32, c.tokens.len - 1);
|
return @intCast(u32, c.tokens.len - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn appendToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
|
fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
|
||||||
std.debug.assert(tag != .identifier); // use appendIdentifier
|
std.debug.assert(tag != .identifier); // use addIdentifier
|
||||||
return appendTokenFmt(c, tag, "{s}", .{bytes});
|
return addTokenFmt(c, tag, "{s}", .{bytes});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn appendIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex {
|
fn addIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex {
|
||||||
return appendTokenFmt(c, .identifier, "{s}", .{std.zig.fmtId(bytes)});
|
return addTokenFmt(c, .identifier, "{s}", .{std.zig.fmtId(bytes)});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange {
|
fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange {
|
||||||
@ -724,14 +721,14 @@ const Context = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn appendNode(c: *Context, elem: std.zig.ast.NodeList.Elem) Allocator.Error!NodeIndex {
|
fn addNode(c: *Context, elem: std.zig.ast.NodeList.Elem) Allocator.Error!NodeIndex {
|
||||||
const result = @intCast(NodeIndex, c.nodes.len);
|
const result = @intCast(NodeIndex, c.nodes.len);
|
||||||
try c.nodes.append(c.gpa, elem);
|
try c.nodes.append(c.gpa, elem);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn renderNodes(c: *Context, nodes: []const Node) !NodeSubRange {
|
fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
|
||||||
var result = std.ArrayList(NodeIndex).init(c.gpa);
|
var result = std.ArrayList(NodeIndex).init(c.gpa);
|
||||||
defer result.deinit();
|
defer result.deinit();
|
||||||
|
|
||||||
@ -744,7 +741,7 @@ fn renderNodes(c: *Context, nodes: []const Node) !NodeSubRange {
|
|||||||
return try c.listToSpan(result.items);
|
return try c.listToSpan(result.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderNode(c: *Context, node: Node) !NodeIndex {
|
fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||||
switch (node.tag()) {
|
switch (node.tag()) {
|
||||||
.warning => {
|
.warning => {
|
||||||
const payload = node.castTag(.warning).?;
|
const payload = node.castTag(.warning).?;
|
||||||
@ -754,12 +751,12 @@ fn renderNode(c: *Context, node: Node) !NodeIndex {
|
|||||||
},
|
},
|
||||||
.usingnamespace_builtins => {
|
.usingnamespace_builtins => {
|
||||||
// pub usingnamespace @import("std").c.builtins;
|
// pub usingnamespace @import("std").c.builtins;
|
||||||
_ = try c.appendToken(.keyword_pub, "pub");
|
_ = try c.addToken(.keyword_pub, "pub");
|
||||||
const usingnamespace_token = try c.appendToken(.keyword_usingnamespace, "usingnamespace");
|
const usingnamespace_token = try c.addToken(.keyword_usingnamespace, "usingnamespace");
|
||||||
const import_node = try renderStdImport(c, "c", "builtins");
|
const import_node = try renderStdImport(c, "c", "builtins");
|
||||||
_ = try c.appendToken(.semicolon, ";");
|
_ = try c.addToken(.semicolon, ";");
|
||||||
|
|
||||||
return c.appendNode(.{
|
return c.addNode(.{
|
||||||
.tag = .@"usingnamespace",
|
.tag = .@"usingnamespace",
|
||||||
.main_token = usingnamespace_token,
|
.main_token = usingnamespace_token,
|
||||||
.data = .{
|
.data = .{
|
||||||
@ -768,6 +765,196 @@ fn renderNode(c: *Context, node: Node) !NodeIndex {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
.std_math_Log2Int => {
|
||||||
|
const payload = node.castTag(.std_math_Log2Int).?;
|
||||||
|
const import_node = try renderStdImport(c, "math", "Log2Int");
|
||||||
|
return renderCall(c, import_node, &.{payload.data});
|
||||||
|
},
|
||||||
|
.std_meta_cast => {
|
||||||
|
const payload = node.castTag(.std_meta_cast).?;
|
||||||
|
const import_node = try renderStdImport(c, "meta", "cast");
|
||||||
|
return renderCall(c, import_node, &.{ payload.data.lhs, payload.data.rhs });
|
||||||
|
},
|
||||||
|
.std_meta_sizeof => {
|
||||||
|
const payload = node.castTag(.std_meta_sizeof).?;
|
||||||
|
const import_node = try renderStdImport(c, "meta", "sizeof");
|
||||||
|
return renderCall(c, import_node, &.{payload.data});
|
||||||
|
},
|
||||||
|
.std_mem_zeroes => {
|
||||||
|
const payload = node.castTag(.std_mem_zeroes).?;
|
||||||
|
const import_node = try renderStdImport(c, "mem", "zeroes");
|
||||||
|
return renderCall(c, import_node, &.{payload.data});
|
||||||
|
},
|
||||||
|
.std_mem_zeroinit => {
|
||||||
|
const payload = node.castTag(.std_mem_zeroinit).?;
|
||||||
|
const import_node = try renderStdImport(c, "mem", "zeroInit");
|
||||||
|
return renderCall(c, import_node, &.{ payload.data.lhs, payload.data.rhs });
|
||||||
|
},
|
||||||
|
.call => {
|
||||||
|
const payload = node.castTag(.call).?;
|
||||||
|
const lhs = try renderNode(c, payload.data.lhs);
|
||||||
|
return renderCall(c, lhs, payload.data.args);
|
||||||
|
},
|
||||||
|
.null_literal => return c.addNode(.{
|
||||||
|
.tag = .null_literal,
|
||||||
|
.main_token = try c.addToken(.keyword_null, "null"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.undefined_literal => return c.addNode(.{
|
||||||
|
.tag = .undefined_literal,
|
||||||
|
.main_token = try c.addToken(.keyword_undefined, "undefined"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.true_literal => return c.addNode(.{
|
||||||
|
.tag = .true_literal,
|
||||||
|
.main_token = try c.addToken(.keyword_true, "true"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.false_literal => return c.addNode(.{
|
||||||
|
.tag = .false_literal,
|
||||||
|
.main_token = try c.addToken(.keyword_false, "false"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.zero_literal => return c.addNode(.{
|
||||||
|
.tag = .integer_literal,
|
||||||
|
.main_token = try c.addToken(.integer_literal, "0"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.one_literal => return c.addNode(.{
|
||||||
|
.tag = .integer_literal,
|
||||||
|
.main_token = try c.addToken(.integer_literal, "1"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.void_type => return c.addNode(.{
|
||||||
|
.tag = .identifier,
|
||||||
|
.main_token = try c.addToken(.identifier, "void"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.@"anytype" => return try c.addNode(.{
|
||||||
|
.tag = .@"anytype",
|
||||||
|
.main_token = try c.addToken(.keyword_anytype, "anytype"),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
.type => {
|
||||||
|
const payload = node.castTag(.type).?;
|
||||||
|
return c.addNode(.{
|
||||||
|
.tag = .identifier,
|
||||||
|
.main_token = try c.addToken(.identifier, payload.data),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.identifier => {
|
||||||
|
const payload = node.castTag(.identifier).?;
|
||||||
|
return c.addNode(.{
|
||||||
|
.tag = .identifier,
|
||||||
|
.main_token = try c.addIdentifier(payload.data),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.number_literal => {
|
||||||
|
const payload = node.castTag(.number_literal).?;
|
||||||
|
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),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.string_literal => {
|
||||||
|
const payload = node.castTag(.string_literal).?;
|
||||||
|
return c.addNode(.{
|
||||||
|
.tag = .identifier,
|
||||||
|
.main_token = try c.addToken(.char_literal, payload.data),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.char_literal => {
|
||||||
|
const payload = node.castTag(.char_literal).?;
|
||||||
|
return c.addNode(.{
|
||||||
|
.tag = .identifier,
|
||||||
|
.main_token = try c.addToken(.string_literal, payload.data),
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.fail_decl => {
|
||||||
|
const payload = node.castTag(.fail_decl).?;
|
||||||
|
// 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);
|
||||||
|
_ = 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 = try c.addNode(.{
|
||||||
|
.tag = .string_literal,
|
||||||
|
.main_token = err_msg_tok,
|
||||||
|
.data = .{
|
||||||
|
.lhs = undefined,
|
||||||
|
.rhs = undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
_ = try c.addToken(.r_paren, ")");
|
||||||
|
const compile_error = try c.addNode(.{
|
||||||
|
.tag = .builtin_call_two,
|
||||||
|
.main_token = compile_error_tok,
|
||||||
|
.data = .{
|
||||||
|
.lhs = err_msg,
|
||||||
|
.rhs = 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
_ = try c.addToken(.semicolon, ";");
|
||||||
|
|
||||||
|
return c.addNode(.{
|
||||||
|
.tag = .simple_var_decl,
|
||||||
|
.main_token = const_kw,
|
||||||
|
.data = .{
|
||||||
|
.lhs = 0,
|
||||||
|
.rhs = compile_error,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
else => {
|
else => {
|
||||||
try c.buf.writer().print("// TODO renderNode {}\n", .{node.tag()});
|
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'
|
return @as(u32, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
|
||||||
@ -776,22 +963,20 @@ fn renderNode(c: *Context, node: Node) !NodeIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {
|
fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {
|
||||||
const import_tok = try c.appendToken(.builtin, "@import");
|
const import_tok = try c.addToken(.builtin, "@import");
|
||||||
_ = try c.appendToken(.l_paren, "(");
|
_ = try c.addToken(.l_paren, "(");
|
||||||
|
const std_tok = try c.addToken(.string_literal, "\"std\"");
|
||||||
const std_tok = try c.appendToken(.string_literal, "\"std\"");
|
const std_node = try c.addNode(.{
|
||||||
const std_node = try c.appendNode(.{
|
|
||||||
.tag = .string_literal,
|
.tag = .string_literal,
|
||||||
.main_token = std_tok,
|
.main_token = std_tok,
|
||||||
.data = .{
|
.data = .{
|
||||||
.lhs = std_tok,
|
.lhs = undefined,
|
||||||
.rhs = std_tok,
|
.rhs = undefined,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
_ = try c.addToken(.r_paren, ")");
|
||||||
|
|
||||||
_ = try c.appendToken(.r_paren, ")");
|
const import_node = try c.addNode(.{
|
||||||
|
|
||||||
const import_node = try c.appendNode(.{
|
|
||||||
.tag = .builtin_call_two,
|
.tag = .builtin_call_two,
|
||||||
.main_token = import_tok,
|
.main_token = import_tok,
|
||||||
.data = .{
|
.data = .{
|
||||||
@ -801,21 +986,67 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde
|
|||||||
});
|
});
|
||||||
|
|
||||||
var access_chain = import_node;
|
var access_chain = import_node;
|
||||||
access_chain = try c.appendNode(.{
|
access_chain = try c.addNode(.{
|
||||||
.tag = .field_access,
|
.tag = .field_access,
|
||||||
.main_token = try c.appendToken(.period, "."),
|
.main_token = try c.addToken(.period, "."),
|
||||||
.data = .{
|
.data = .{
|
||||||
.lhs = access_chain,
|
.lhs = access_chain,
|
||||||
.rhs = try c.appendIdentifier(first),
|
.rhs = try c.addIdentifier(first),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
access_chain = try c.appendNode(.{
|
access_chain = try c.addNode(.{
|
||||||
.tag = .field_access,
|
.tag = .field_access,
|
||||||
.main_token = try c.appendToken(.period, "."),
|
.main_token = try c.addToken(.period, "."),
|
||||||
.data = .{
|
.data = .{
|
||||||
.lhs = access_chain,
|
.lhs = access_chain,
|
||||||
.rhs = try c.appendIdentifier(second),
|
.rhs = try c.addIdentifier(second),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return access_chain;
|
return access_chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {
|
||||||
|
const lparen = try c.addToken(.l_paren, "(");
|
||||||
|
const res = switch (args.len) {
|
||||||
|
0 => try c.addNode(.{
|
||||||
|
.tag = .call_one,
|
||||||
|
.main_token = lparen,
|
||||||
|
.data = .{
|
||||||
|
.lhs = lhs,
|
||||||
|
.rhs = 0,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
1 => blk: {
|
||||||
|
const arg = try renderNode(c, args[0]);
|
||||||
|
break :blk try c.addNode(.{
|
||||||
|
.tag = .call_one,
|
||||||
|
.main_token = lparen,
|
||||||
|
.data = .{
|
||||||
|
.lhs = lhs,
|
||||||
|
.rhs = arg,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
else => blk: {
|
||||||
|
const start = @intCast(u32, c.extra_data.items.len);
|
||||||
|
const end = @intCast(u32, start + args.len);
|
||||||
|
try c.extra_data.ensureCapacity(c.gpa, end + 2); // + 2 for span start + end
|
||||||
|
for (args) |arg, i| {
|
||||||
|
if (i != 0) _ = try c.addToken(.comma, ",");
|
||||||
|
c.extra_data.appendAssumeCapacity(try renderNode(c, arg));
|
||||||
|
}
|
||||||
|
c.extra_data.appendAssumeCapacity(start);
|
||||||
|
c.extra_data.appendAssumeCapacity(end);
|
||||||
|
break :blk try c.addNode(.{
|
||||||
|
.tag = .call_comma,
|
||||||
|
.main_token = lparen,
|
||||||
|
.data = .{
|
||||||
|
.lhs = lhs,
|
||||||
|
.rhs = end + 2,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
_ = try c.addToken(.r_paren, ")");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user