feat: ink variable semantics, global ref table for astgen
This commit is contained in:
parent
197a37ebe7
commit
9658c8a308
7 changed files with 298 additions and 141 deletions
85
src/Ir.zig
85
src/Ir.zig
|
|
@ -4,6 +4,7 @@ const Ir = @This();
|
|||
|
||||
string_bytes: []u8,
|
||||
instructions: []Inst,
|
||||
globals: []Global,
|
||||
extra: []u32,
|
||||
errors: []Ast.Error,
|
||||
|
||||
|
|
@ -23,6 +24,9 @@ pub const Inst = struct {
|
|||
decl_var,
|
||||
decl_ref,
|
||||
block,
|
||||
alloc_local,
|
||||
load_local,
|
||||
store_local,
|
||||
add,
|
||||
sub,
|
||||
mul,
|
||||
|
|
@ -78,6 +82,17 @@ pub const Inst = struct {
|
|||
};
|
||||
};
|
||||
|
||||
pub const Global = struct {
|
||||
tag: Tag,
|
||||
name: Ir.NullTerminatedString,
|
||||
is_constant: bool,
|
||||
|
||||
pub const Tag = enum {
|
||||
knot,
|
||||
variable,
|
||||
};
|
||||
};
|
||||
|
||||
pub const NullTerminatedString = enum(u32) {
|
||||
empty,
|
||||
_,
|
||||
|
|
@ -91,6 +106,7 @@ pub const IndexSlice = struct {
|
|||
pub fn deinit(ir: *Ir, gpa: std.mem.Allocator) void {
|
||||
gpa.free(ir.string_bytes);
|
||||
gpa.free(ir.instructions);
|
||||
gpa.free(ir.globals);
|
||||
gpa.free(ir.extra);
|
||||
gpa.free(ir.errors);
|
||||
ir.* = undefined;
|
||||
|
|
@ -129,12 +145,17 @@ const Render = struct {
|
|||
WriteFailed,
|
||||
};
|
||||
|
||||
fn renderUnaryInst(r: *Render, inst: Inst) Error!void {
|
||||
fn renderSimple(r: *Render, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
return io_w.print("{s}(?)", .{@tagName(inst.tag)});
|
||||
}
|
||||
|
||||
fn renderUnary(r: *Render, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
return io_w.print("{s}(%{d})", .{ @tagName(inst.tag), inst.data.un.lhs });
|
||||
}
|
||||
|
||||
fn renderBinaryInst(r: *Render, inst: Inst) Error!void {
|
||||
fn renderBinary(r: *Render, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
return io_w.print("{s}(%{d}, %{d})", .{ @tagName(inst.tag), inst.data.bin.lhs, inst.data.bin.rhs });
|
||||
}
|
||||
|
|
@ -152,7 +173,7 @@ const Render = struct {
|
|||
try io_w.writeAll("}");
|
||||
}
|
||||
|
||||
fn renderBlockInst(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
fn renderBlock(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
const extra = ir.extraData(Inst.Block, inst.data.payload.payload_index);
|
||||
const body_slice = ir.bodySlice(extra.end, extra.data.body_len);
|
||||
|
|
@ -182,16 +203,6 @@ const Render = struct {
|
|||
try io_w.writeAll(")");
|
||||
}
|
||||
|
||||
fn renderFileInst(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
const extra = ir.extraData(Inst.Block, inst.data.payload.payload_index);
|
||||
const body_slice = ir.bodySlice(extra.end, extra.data.body_len);
|
||||
|
||||
try io_w.print("{s}(", .{@tagName(inst.tag)});
|
||||
try renderBodyInner(r, ir, body_slice);
|
||||
return io_w.writeAll(")");
|
||||
}
|
||||
|
||||
fn renderDeclaration(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
const extra = ir.extraData(Inst.Declaration, inst.data.payload.payload_index);
|
||||
|
|
@ -207,6 +218,16 @@ const Render = struct {
|
|||
return io_w.writeAll(")");
|
||||
}
|
||||
|
||||
fn renderFile(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
const extra = ir.extraData(Inst.Block, inst.data.payload.payload_index);
|
||||
const body_slice = ir.bodySlice(extra.end, extra.data.body_len);
|
||||
|
||||
try io_w.print("{s}(", .{@tagName(inst.tag)});
|
||||
try renderBodyInner(r, ir, body_slice);
|
||||
return io_w.writeAll(")");
|
||||
}
|
||||
|
||||
fn renderInst(r: *Render, ir: Ir, index: Inst.Index) Error!void {
|
||||
const io_w = r.writer;
|
||||
const inst_index: u32 = @intFromEnum(index);
|
||||
|
|
@ -215,7 +236,7 @@ const Render = struct {
|
|||
try r.prefix.writeIndent(io_w);
|
||||
try io_w.print("%{d} = ", .{inst_index});
|
||||
switch (inst.tag) {
|
||||
.file => try r.renderFileInst(ir, inst),
|
||||
.file => try r.renderFile(ir, inst),
|
||||
.declaration => try r.renderDeclaration(ir, inst),
|
||||
.decl_knot => try r.renderKnotDecl(ir, inst),
|
||||
.decl_var => try r.renderVarDecl(ir, inst),
|
||||
|
|
@ -223,13 +244,16 @@ const Render = struct {
|
|||
const str_bytes = inst.data.string.get(ir);
|
||||
try io_w.print("{s}(\"{s}\")", .{ @tagName(inst.tag), str_bytes });
|
||||
},
|
||||
.block => try r.renderBlockInst(ir, inst),
|
||||
.add => try r.renderBinaryInst(inst),
|
||||
.sub => try r.renderBinaryInst(inst),
|
||||
.mul => try r.renderBinaryInst(inst),
|
||||
.div => try r.renderBinaryInst(inst),
|
||||
.mod => try r.renderBinaryInst(inst),
|
||||
.neg => try r.renderUnaryInst(inst),
|
||||
.alloc_local => try r.renderSimple(inst),
|
||||
.load_local => try r.renderUnary(inst),
|
||||
.store_local => try r.renderBinary(inst),
|
||||
.block => try r.renderBlock(ir, inst),
|
||||
.add => try r.renderBinary(inst),
|
||||
.sub => try r.renderBinary(inst),
|
||||
.mul => try r.renderBinary(inst),
|
||||
.div => try r.renderBinary(inst),
|
||||
.mod => try r.renderBinary(inst),
|
||||
.neg => try r.renderUnary(inst),
|
||||
.true_literal => {
|
||||
try io_w.print("{s}", .{@tagName(inst.tag)});
|
||||
},
|
||||
|
|
@ -244,7 +268,7 @@ const Render = struct {
|
|||
const str_bytes = inst.data.string.get(ir);
|
||||
try io_w.print("{s}(\"{s}\")", .{ @tagName(inst.tag), str_bytes });
|
||||
},
|
||||
.content => try r.renderUnaryInst(inst),
|
||||
.content => try r.renderUnary(inst),
|
||||
}
|
||||
try io_w.writeAll("\n");
|
||||
}
|
||||
|
|
@ -259,18 +283,23 @@ pub fn render(ir: Ir, gpa: std.mem.Allocator, writer: *std.Io.Writer) !void {
|
|||
return writer.flush();
|
||||
}
|
||||
|
||||
pub fn dumpStringsWithHex(cu: *const Ir) void {
|
||||
const bytes = cu.string_bytes;
|
||||
pub fn dumpInfo(ir: Ir, writer: *std.Io.Writer) !void {
|
||||
const bytes = ir.string_bytes;
|
||||
|
||||
var start: usize = 0;
|
||||
while (start < bytes.len) {
|
||||
const end = std.mem.indexOfScalarPos(u8, bytes, start, 0) orelse break;
|
||||
const s = bytes[start..end];
|
||||
const str = bytes[start..end];
|
||||
|
||||
std.debug.print("[{d:04}] ", .{start});
|
||||
for (s) |b| std.debug.print("{x:02} ", .{b});
|
||||
std.debug.print("00: {s}\n", .{s});
|
||||
try writer.print("[{d:04}] ", .{start});
|
||||
for (str) |b| try writer.print("{x:02} ", .{b});
|
||||
try writer.print("00: {s}\n", .{str});
|
||||
start = end + 1;
|
||||
}
|
||||
for (ir.globals) |global| {
|
||||
try writer.print("{any}\n", .{global});
|
||||
}
|
||||
return writer.flush();
|
||||
}
|
||||
|
||||
fn ExtraData(comptime T: type) type {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue