astgen: implement array types
This commit is contained in:
@@ -1430,7 +1430,7 @@ pub const Tree = struct {
|
||||
.ast = .{
|
||||
.lbracket = tree.nodes.items(.main_token)[node],
|
||||
.elem_count = data.lhs,
|
||||
.sentinel = null,
|
||||
.sentinel = 0,
|
||||
.elem_type = data.rhs,
|
||||
},
|
||||
};
|
||||
@@ -1440,6 +1440,7 @@ pub const Tree = struct {
|
||||
assert(tree.nodes.items(.tag)[node] == .array_type_sentinel);
|
||||
const data = tree.nodes.items(.data)[node];
|
||||
const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel);
|
||||
assert(extra.sentinel != 0);
|
||||
return .{
|
||||
.ast = .{
|
||||
.lbracket = tree.nodes.items(.main_token)[node],
|
||||
@@ -2262,7 +2263,7 @@ pub const full = struct {
|
||||
pub const Ast = struct {
|
||||
lbracket: TokenIndex,
|
||||
elem_count: Node.Index,
|
||||
sentinel: ?Node.Index,
|
||||
sentinel: Node.Index,
|
||||
elem_type: Node.Index,
|
||||
};
|
||||
};
|
||||
@@ -2549,9 +2550,9 @@ pub const Node = struct {
|
||||
@"await",
|
||||
/// `?lhs`. rhs unused. main_token is the `?`.
|
||||
optional_type,
|
||||
/// `[lhs]rhs`. lhs can be omitted to make it a slice.
|
||||
/// `[lhs]rhs`.
|
||||
array_type,
|
||||
/// `[lhs:a]b`. `array_type_sentinel[rhs]`.
|
||||
/// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`.
|
||||
array_type_sentinel,
|
||||
/// `[*]align(lhs) rhs`. lhs can be omitted.
|
||||
/// `*align(lhs) rhs`. lhs can be omitted.
|
||||
|
||||
@@ -717,9 +717,9 @@ fn renderArrayType(
|
||||
ais.pushIndentNextLine();
|
||||
try renderToken(ais, tree, array_type.ast.lbracket, inner_space); // lbracket
|
||||
try renderExpression(gpa, ais, tree, array_type.ast.elem_count, inner_space);
|
||||
if (array_type.ast.sentinel) |sentinel| {
|
||||
try renderToken(ais, tree, tree.firstToken(sentinel) - 1, inner_space); // colon
|
||||
try renderExpression(gpa, ais, tree, sentinel, inner_space);
|
||||
if (array_type.ast.sentinel != 0) {
|
||||
try renderToken(ais, tree, tree.firstToken(array_type.ast.sentinel) - 1, inner_space); // colon
|
||||
try renderExpression(gpa, ais, tree, array_type.ast.sentinel, inner_space);
|
||||
}
|
||||
ais.popIndent();
|
||||
try renderToken(ais, tree, rbracket, .none); // rbracket
|
||||
|
||||
@@ -1210,6 +1210,32 @@ pub const Scope = struct {
|
||||
return new_index + gz.zir_code.ref_start_index;
|
||||
}
|
||||
|
||||
pub fn addArrayTypeSentinel(
|
||||
gz: *GenZir,
|
||||
len: zir.Inst.Ref,
|
||||
sentinel: zir.Inst.Ref,
|
||||
elem_type: zir.Inst.Ref,
|
||||
) !zir.Inst.Ref {
|
||||
const gpa = gz.zir_code.gpa;
|
||||
try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
|
||||
try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
|
||||
|
||||
const payload_index = try gz.zir_code.addExtra(zir.Inst.ArrayTypeSentinel{
|
||||
.sentinel = sentinel,
|
||||
.elem_type = elem_type,
|
||||
});
|
||||
const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
|
||||
gz.zir_code.instructions.appendAssumeCapacity(.{
|
||||
.tag = .array_type_sentinel,
|
||||
.data = .{ .array_type_sentinel = .{
|
||||
.len = len,
|
||||
.payload_index = payload_index,
|
||||
} },
|
||||
});
|
||||
gz.instructions.appendAssumeCapacity(new_index);
|
||||
return new_index + gz.zir_code.ref_start_index;
|
||||
}
|
||||
|
||||
pub fn addUnTok(
|
||||
gz: *GenZir,
|
||||
tag: zir.Inst.Tag,
|
||||
|
||||
@@ -1390,56 +1390,33 @@ fn ptrType(
|
||||
}
|
||||
|
||||
fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
const tree = scope.tree();
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
const gz = scope.getGenZir();
|
||||
const usize_type = @enumToInt(zir.Const.usize_type);
|
||||
|
||||
const usize_type = try addZIRInstConst(mod, scope, src, .{
|
||||
.ty = Type.initTag(.type),
|
||||
.val = Value.initTag(.usize_type),
|
||||
});
|
||||
const len_node = node_datas[node].lhs;
|
||||
const elem_node = node_datas[node].rhs;
|
||||
if (len_node == 0) {
|
||||
const elem_type = try typeExpr(mod, scope, elem_node);
|
||||
const result = try addZIRUnOp(mod, scope, src, .mut_slice_type, elem_type);
|
||||
return rvalue(mod, scope, rl, result);
|
||||
} else {
|
||||
// TODO check for [_]T
|
||||
const len = try expr(mod, scope, .{ .ty = usize_type }, len_node);
|
||||
const elem_type = try typeExpr(mod, scope, elem_node);
|
||||
// TODO check for [_]T
|
||||
const len = try expr(mod, scope, .{ .ty = usize_type }, node_datas[node].lhs);
|
||||
const elem_type = try typeExpr(mod, scope, node_datas[node].rhs);
|
||||
|
||||
const result = try addZIRBinOp(mod, scope, src, .array_type, len, elem_type);
|
||||
return rvalue(mod, scope, rl, result);
|
||||
}
|
||||
const result = try gz.addBin(.array_type, len, elem_type);
|
||||
return rvalue(mod, scope, rl, result, node);
|
||||
}
|
||||
|
||||
fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref {
|
||||
if (true) @panic("TODO update for zir-memory-layout");
|
||||
const tree = scope.tree();
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
|
||||
const len_node = node_datas[node].lhs;
|
||||
const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);
|
||||
const usize_type = try addZIRInstConst(mod, scope, src, .{
|
||||
.ty = Type.initTag(.type),
|
||||
.val = Value.initTag(.usize_type),
|
||||
});
|
||||
const gz = scope.getGenZir();
|
||||
const usize_type = @enumToInt(zir.Const.usize_type);
|
||||
|
||||
// TODO check for [_]T
|
||||
const len = try expr(mod, scope, .{ .ty = usize_type }, len_node);
|
||||
const sentinel_uncasted = try expr(mod, scope, .none, extra.sentinel);
|
||||
const len = try expr(mod, scope, .{ .ty = usize_type }, node_datas[node].lhs);
|
||||
const elem_type = try typeExpr(mod, scope, extra.elem_type);
|
||||
const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted);
|
||||
const sentinel = try expr(mod, scope, .{ .ty = elem_type }, extra.sentinel);
|
||||
|
||||
const result = try addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{
|
||||
.len = len,
|
||||
.sentinel = sentinel,
|
||||
.elem_type = elem_type,
|
||||
}, .{});
|
||||
return rvalue(mod, scope, rl, result);
|
||||
const result = try gz.addArrayTypeSentinel(len, elem_type, sentinel);
|
||||
return rvalue(mod, scope, rl, result, node);
|
||||
}
|
||||
|
||||
fn containerDecl(
|
||||
|
||||
Reference in New Issue
Block a user