fix: content behavior bugs
This commit is contained in:
parent
2260ccda25
commit
11d99fba38
59 changed files with 243 additions and 31 deletions
|
|
@ -1224,7 +1224,34 @@ fn divertExpr(gi: *GenIr, scope: *Scope, node: *const Ast.Node) !void {
|
||||||
// FIXME: Oh God, the AST is completely fucked for this.
|
// FIXME: Oh God, the AST is completely fucked for this.
|
||||||
const lhs = node.data.bin.lhs.?;
|
const lhs = node.data.bin.lhs.?;
|
||||||
switch (lhs.tag) {
|
switch (lhs.tag) {
|
||||||
.identifier, .selector_expr => {
|
.identifier => {
|
||||||
|
// TODO: Revisit this
|
||||||
|
const str_slice = gi.astgen.tree.nodeSlice(lhs);
|
||||||
|
if (std.mem.eql(u8, str_slice, "DONE")) {
|
||||||
|
_ = try gi.addUnaryNode(.done, .none);
|
||||||
|
return;
|
||||||
|
} else if (std.mem.eql(u8, str_slice, "END")) {
|
||||||
|
_ = try gi.addUnaryNode(.exit, .none);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const callee = try calleeExpr(gi, scope, lhs);
|
||||||
|
switch (callee) {
|
||||||
|
.direct => |callee_obj| {
|
||||||
|
_ = try gi.addPayloadNode(.divert, lhs, Ir.Inst.Call{
|
||||||
|
.callee = callee_obj,
|
||||||
|
.args_len = 0,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.field => |callee_field| {
|
||||||
|
_ = try gi.addPayloadNode(.field_divert, lhs, Ir.Inst.FieldCall{
|
||||||
|
.obj_ptr = callee_field.obj_ptr,
|
||||||
|
.field_name_start = callee_field.field_name_start,
|
||||||
|
.args_len = 0,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.selector_expr => {
|
||||||
const callee = try calleeExpr(gi, scope, lhs);
|
const callee = try calleeExpr(gi, scope, lhs);
|
||||||
switch (callee) {
|
switch (callee) {
|
||||||
.direct => |callee_obj| {
|
.direct => |callee_obj| {
|
||||||
|
|
@ -1310,7 +1337,7 @@ fn blockInner(gi: *GenIr, parent_scope: *Scope, stmt_list: []*Ast.Node) !void {
|
||||||
.choice_stmt => try choiceStmt(gi, &child_scope, inner_node),
|
.choice_stmt => try choiceStmt(gi, &child_scope, inner_node),
|
||||||
.expr_stmt => try exprStmt(gi, &child_scope, inner_node),
|
.expr_stmt => try exprStmt(gi, &child_scope, inner_node),
|
||||||
.divert_stmt => try divertStmt(gi, &child_scope, inner_node),
|
.divert_stmt => try divertStmt(gi, &child_scope, inner_node),
|
||||||
else => unreachable,
|
inline else => |e| @panic("Unexpected node: " ++ @tagName(e)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
_ = try gi.addUnaryNode(.implicit_ret, .none);
|
_ = try gi.addUnaryNode(.implicit_ret, .none);
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,8 @@ pub const Inst = struct {
|
||||||
field_call,
|
field_call,
|
||||||
field_divert,
|
field_divert,
|
||||||
param,
|
param,
|
||||||
|
done,
|
||||||
|
exit,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Data = union {
|
pub const Data = union {
|
||||||
|
|
|
||||||
37
src/Sema.zig
37
src/Sema.zig
|
|
@ -24,6 +24,7 @@ const InnerError = error{
|
||||||
|
|
||||||
pub const ValueInfo = union(enum) {
|
pub const ValueInfo = union(enum) {
|
||||||
none,
|
none,
|
||||||
|
stack,
|
||||||
value: InternPool.Index,
|
value: InternPool.Index,
|
||||||
variable: InternPool.Index,
|
variable: InternPool.Index,
|
||||||
knot: InternPool.Index,
|
knot: InternPool.Index,
|
||||||
|
|
@ -288,6 +289,7 @@ pub const Builder = struct {
|
||||||
fn ensureLoad(self: *Builder, info: ValueInfo) InnerError!void {
|
fn ensureLoad(self: *Builder, info: ValueInfo) InnerError!void {
|
||||||
switch (info) {
|
switch (info) {
|
||||||
.none => unreachable, // caller should never load .none
|
.none => unreachable, // caller should never load .none
|
||||||
|
.stack => {},
|
||||||
.value => |index| {
|
.value => |index| {
|
||||||
const local_index = try self.getOrPutConstantIndex(index);
|
const local_index = try self.getOrPutConstantIndex(index);
|
||||||
try self.addConstOp(.load_const, @intCast(local_index));
|
try self.addConstOp(.load_const, @intCast(local_index));
|
||||||
|
|
@ -451,7 +453,7 @@ fn irUnaryOp(
|
||||||
|
|
||||||
try builder.ensureLoad(lhs);
|
try builder.ensureLoad(lhs);
|
||||||
try builder.addByteOp(op);
|
try builder.addByteOp(op);
|
||||||
return .none;
|
return .stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn irBinaryOp(
|
fn irBinaryOp(
|
||||||
|
|
@ -485,7 +487,7 @@ fn irBinaryOp(
|
||||||
try builder.ensureLoad(lhs);
|
try builder.ensureLoad(lhs);
|
||||||
try builder.ensureLoad(rhs);
|
try builder.ensureLoad(rhs);
|
||||||
try builder.addByteOp(op);
|
try builder.addByteOp(op);
|
||||||
return .none;
|
return .stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn irLogicalOp(
|
fn irLogicalOp(
|
||||||
|
|
@ -567,8 +569,16 @@ fn irStore(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void
|
||||||
try builder.ensureLoad(rhs);
|
try builder.ensureLoad(rhs);
|
||||||
|
|
||||||
switch (lhs) {
|
switch (lhs) {
|
||||||
|
.none => unreachable,
|
||||||
|
.stack => {},
|
||||||
.value => |_| return sema.fail(src, "could not assign to constant value", .{}),
|
.value => |_| return sema.fail(src, "could not assign to constant value", .{}),
|
||||||
else => unreachable,
|
.variable => |index| {
|
||||||
|
const local_index = try builder.getOrPutConstantIndex(index);
|
||||||
|
try builder.addConstOp(.store_global, @intCast(local_index));
|
||||||
|
},
|
||||||
|
.temp => |temp| try builder.addConstOp(.store, @intCast(temp)),
|
||||||
|
.stitch => |_| return sema.fail(src, "could not assign to stitch", .{}),
|
||||||
|
.knot => |_| return sema.fail(src, "could not assign to knot", .{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
try builder.addByteOp(.pop);
|
try builder.addByteOp(.pop);
|
||||||
|
|
@ -577,8 +587,10 @@ fn irStore(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void
|
||||||
fn irLoad(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!ValueInfo {
|
fn irLoad(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!ValueInfo {
|
||||||
const data = sema.ir.instructions[@intFromEnum(inst)].data.un;
|
const data = sema.ir.instructions[@intFromEnum(inst)].data.un;
|
||||||
const lhs = sema.resolveInst(data.lhs);
|
const lhs = sema.resolveInst(data.lhs);
|
||||||
|
if (lhs == .value) return lhs;
|
||||||
|
|
||||||
try builder.ensureLoad(lhs);
|
try builder.ensureLoad(lhs);
|
||||||
return .none;
|
return .stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn irCondBr(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!ValueInfo {
|
fn irCondBr(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!ValueInfo {
|
||||||
|
|
@ -670,9 +682,8 @@ fn irSwitchBr(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!vo
|
||||||
fn irContentPush(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void {
|
fn irContentPush(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void {
|
||||||
const data = sema.ir.instructions[@intFromEnum(inst)].data.un;
|
const data = sema.ir.instructions[@intFromEnum(inst)].data.un;
|
||||||
const lhs = sema.resolveInst(data.lhs);
|
const lhs = sema.resolveInst(data.lhs);
|
||||||
if (lhs != .none) {
|
if (lhs == .none) return error.AnalysisFail;
|
||||||
try builder.ensureLoad(lhs);
|
if (lhs != .stack) try builder.ensureLoad(lhs);
|
||||||
}
|
|
||||||
try builder.addByteOp(.stream_push);
|
try builder.addByteOp(.stream_push);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -820,6 +831,16 @@ fn irParam(_: *Sema, builder: *Builder, _: Ir.Inst.Index) !ValueInfo {
|
||||||
return .{ .temp = builder.addParameter() };
|
return .{ .temp = builder.addParameter() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn irDone(_: *Sema, builder: *Builder, _: Ir.Inst.Index) !ValueInfo {
|
||||||
|
try builder.addByteOp(.done);
|
||||||
|
return .none;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn irExit(_: *Sema, builder: *Builder, _: Ir.Inst.Index) !ValueInfo {
|
||||||
|
try builder.addByteOp(.exit);
|
||||||
|
return .none;
|
||||||
|
}
|
||||||
|
|
||||||
fn analyzeArithmeticArg(
|
fn analyzeArithmeticArg(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
builder: *Builder,
|
builder: *Builder,
|
||||||
|
|
@ -939,6 +960,8 @@ fn analyzeBodyInner(
|
||||||
},
|
},
|
||||||
.field_ptr => try irFieldPtr(sema, builder, inst),
|
.field_ptr => try irFieldPtr(sema, builder, inst),
|
||||||
.param => try irParam(sema, builder, inst),
|
.param => try irParam(sema, builder, inst),
|
||||||
|
.done => try irDone(sema, builder, inst),
|
||||||
|
.exit => try irExit(sema, builder, inst),
|
||||||
};
|
};
|
||||||
try sema.inst_map.put(sema.gpa, inst, result);
|
try sema.inst_map.put(sema.gpa, inst, result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ pub const Choice = struct {
|
||||||
pub const Opcode = enum(u8) {
|
pub const Opcode = enum(u8) {
|
||||||
/// Exit the VM normally.
|
/// Exit the VM normally.
|
||||||
exit,
|
exit,
|
||||||
|
done,
|
||||||
ret,
|
ret,
|
||||||
/// Pop a value off the stack, discarding it.
|
/// Pop a value off the stack, discarding it.
|
||||||
pop,
|
pop,
|
||||||
|
|
@ -395,9 +396,8 @@ fn setGlobal(vm: *Story, key: Value, value: Value) !void {
|
||||||
|
|
||||||
fn execute(vm: *Story) !std.ArrayListUnmanaged(u8) {
|
fn execute(vm: *Story) !std.ArrayListUnmanaged(u8) {
|
||||||
const gpa = vm.allocator;
|
const gpa = vm.allocator;
|
||||||
errdefer {
|
errdefer vm.can_advance = false;
|
||||||
vm.can_advance = false;
|
|
||||||
}
|
|
||||||
if (vm.isCallStackEmpty()) return .empty;
|
if (vm.isCallStackEmpty()) return .empty;
|
||||||
|
|
||||||
var stream_writer = std.Io.Writer.Allocating.init(gpa);
|
var stream_writer = std.Io.Writer.Allocating.init(gpa);
|
||||||
|
|
@ -415,6 +415,10 @@ fn execute(vm: *Story) !std.ArrayListUnmanaged(u8) {
|
||||||
vm.can_advance = false;
|
vm.can_advance = false;
|
||||||
return .empty;
|
return .empty;
|
||||||
},
|
},
|
||||||
|
.done => {
|
||||||
|
vm.can_advance = false;
|
||||||
|
return .empty;
|
||||||
|
},
|
||||||
.true => {
|
.true => {
|
||||||
const value: Value = .{ .bool = true };
|
const value: Value = .{ .bool = true };
|
||||||
try vm.pushStack(value);
|
try vm.pushStack(value);
|
||||||
|
|
@ -588,7 +592,6 @@ fn execute(vm: *Story) !std.ArrayListUnmanaged(u8) {
|
||||||
frame.ip += 3;
|
frame.ip += 3;
|
||||||
},
|
},
|
||||||
.br_table => {
|
.br_table => {
|
||||||
// No-op currently.
|
|
||||||
frame.ip += 1;
|
frame.ip += 1;
|
||||||
},
|
},
|
||||||
.br_select_index => {
|
.br_select_index => {
|
||||||
|
|
@ -599,7 +602,12 @@ fn execute(vm: *Story) !std.ArrayListUnmanaged(u8) {
|
||||||
.br_dispatch => {
|
.br_dispatch => {
|
||||||
const index = vm.choice_index;
|
const index = vm.choice_index;
|
||||||
const branch_dispatch = vm.current_choices.items[index];
|
const branch_dispatch = vm.current_choices.items[index];
|
||||||
defer vm.current_choices.clearRetainingCapacity();
|
defer {
|
||||||
|
for (vm.current_choices.items) |*choice| {
|
||||||
|
choice.text.deinit(gpa);
|
||||||
|
}
|
||||||
|
vm.current_choices.clearRetainingCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
frame.ip = branch_dispatch.dest_offset;
|
frame.ip = branch_dispatch.dest_offset;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ pub fn dumpInst(
|
||||||
}
|
}
|
||||||
switch (op) {
|
switch (op) {
|
||||||
.exit => return self.dumpSimpleInst(w, offset, op),
|
.exit => return self.dumpSimpleInst(w, offset, op),
|
||||||
|
.done => return self.dumpSimpleInst(w, offset, op),
|
||||||
.ret => return self.dumpSimpleInst(w, offset, op),
|
.ret => return self.dumpSimpleInst(w, offset, op),
|
||||||
.pop => return self.dumpSimpleInst(w, offset, op),
|
.pop => return self.dumpSimpleInst(w, offset, op),
|
||||||
.true => return self.dumpSimpleInst(w, offset, op),
|
.true => return self.dumpSimpleInst(w, offset, op),
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,6 @@ const std = @import("std");
|
||||||
const fatal = std.process.fatal;
|
const fatal = std.process.fatal;
|
||||||
const ink = @import("../root.zig");
|
const ink = @import("../root.zig");
|
||||||
|
|
||||||
test "fixture - hello world" {
|
|
||||||
try testRuntimeFixture("hello-world");
|
|
||||||
}
|
|
||||||
|
|
||||||
test "fixture - monsieur-fogg" {
|
|
||||||
try testRuntimeFixture("monsieur-fogg");
|
|
||||||
}
|
|
||||||
|
|
||||||
test "fixture - variable arithmetic" {
|
test "fixture - variable arithmetic" {
|
||||||
try testRuntimeFixture("variable-arithmetic");
|
try testRuntimeFixture("variable-arithmetic");
|
||||||
}
|
}
|
||||||
|
|
@ -18,6 +10,75 @@ test "fixture - constant folding" {
|
||||||
try testRuntimeFixture("constant-folding");
|
try testRuntimeFixture("constant-folding");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "fixture - I001 (Minimal story)" {
|
||||||
|
try testRuntimeFixture("I001");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I002 (Fogg comforts Passepartout)" {
|
||||||
|
try testRuntimeFixture("I002");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I005 (Const variable)" {
|
||||||
|
try testRuntimeFixture("I005");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I007 (Set non existant variable)" {
|
||||||
|
try testRuntimeFixture("I007");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I011 (Temporaries at global scope)" {
|
||||||
|
try testRuntimeFixture("I011");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This needs gather points.
|
||||||
|
//test "fixture - I012 (Variable declaration in conditional)" {
|
||||||
|
// try testRuntimeFixture("I012");
|
||||||
|
//}
|
||||||
|
|
||||||
|
test "fixture - I016 (Empty)" {
|
||||||
|
try testRuntimeFixture("I016");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I017 (End)" {
|
||||||
|
try testRuntimeFixture("I017");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I018 (End, the return of the end)" {
|
||||||
|
try testRuntimeFixture("I018");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I019 (End of content)" {
|
||||||
|
try testRuntimeFixture("I019");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I021 (Identifiers can start with numbers)" {
|
||||||
|
try testRuntimeFixture("I021");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I023 (Whitespace)" {
|
||||||
|
try testRuntimeFixture("I023");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I035 (Newline consistency, the third)" {
|
||||||
|
try testRuntimeFixture("I035");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I042 (Weave options)" {
|
||||||
|
try testRuntimeFixture("I042");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I051 (String constants)" {
|
||||||
|
try testRuntimeFixture("I051");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I064 (Done stops thread)" {
|
||||||
|
try testRuntimeFixture("I064");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "fixture - I078 (Choice with brackets only)" {
|
||||||
|
try testRuntimeFixture("I078");
|
||||||
|
}
|
||||||
|
|
||||||
test "fixture - I118 (Literal unary)" {
|
test "fixture - I118 (Literal unary)" {
|
||||||
try testRuntimeFixture("I118");
|
try testRuntimeFixture("I118");
|
||||||
}
|
}
|
||||||
|
|
@ -62,16 +123,20 @@ fn testRunner(gpa: std.mem.Allocator, source_bytes: [:0]const u8, options: Optio
|
||||||
}
|
}
|
||||||
if (story.current_choices.items.len > 0) {
|
if (story.current_choices.items.len > 0) {
|
||||||
for (story.current_choices.items, 0..) |*choice, index| {
|
for (story.current_choices.items, 0..) |*choice, index| {
|
||||||
const choice_text = try choice.text.toOwnedSlice(gpa);
|
try io_w.print("{d}: {s}\n", .{ index + 1, choice.text.items });
|
||||||
defer gpa.free(choice_text);
|
|
||||||
try io_w.print("{d}: {s}\n", .{ index + 1, choice_text });
|
|
||||||
}
|
}
|
||||||
try io_w.print("?> ", .{});
|
try io_w.print("?> ", .{});
|
||||||
|
|
||||||
const input_line = try io_r.takeDelimiter('\n');
|
const input_line = try io_r.takeDelimiter('\n');
|
||||||
if (input_line) |bytes| {
|
if (input_line) |bytes| {
|
||||||
const choice_index = try std.fmt.parseUnsigned(usize, bytes, 10);
|
const parsed_choice_index = try std.fmt.parseUnsigned(usize, bytes, 10);
|
||||||
try story.selectChoiceIndex(if (choice_index == 0) 0 else choice_index - 1);
|
const choice_index = if (parsed_choice_index == 0) 0 else parsed_choice_index - 1;
|
||||||
|
// TODO: Seems like Ink proof wants to check the option text, not the actually
|
||||||
|
// rendered text.
|
||||||
|
//const result_text = story.current_choices.items[choice_index];
|
||||||
|
//try io_w.print("{s}\n", .{result_text.text.items});
|
||||||
|
|
||||||
|
try story.selectChoiceIndex(choice_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
0
src/Story/testdata/I005/input.txt
vendored
Normal file
0
src/Story/testdata/I005/input.txt
vendored
Normal file
3
src/Story/testdata/I005/story.ink
vendored
Normal file
3
src/Story/testdata/I005/story.ink
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
VAR x = c
|
||||||
|
CONST c = 5
|
||||||
|
{x}
|
||||||
1
src/Story/testdata/I005/transcript.txt
vendored
Normal file
1
src/Story/testdata/I005/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
5
|
||||||
0
src/Story/testdata/I007/input.txt
vendored
Normal file
0
src/Story/testdata/I007/input.txt
vendored
Normal file
2
src/Story/testdata/I007/story.ink
vendored
Normal file
2
src/Story/testdata/I007/story.ink
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
VAR x = "world"
|
||||||
|
Hello {x}.
|
||||||
1
src/Story/testdata/I007/transcript.txt
vendored
Normal file
1
src/Story/testdata/I007/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Hello world.
|
||||||
0
src/Story/testdata/I011/input.txt
vendored
Normal file
0
src/Story/testdata/I011/input.txt
vendored
Normal file
3
src/Story/testdata/I011/story.ink
vendored
Normal file
3
src/Story/testdata/I011/story.ink
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
VAR x = 5
|
||||||
|
~ temp y = 4
|
||||||
|
{x}{y}
|
||||||
1
src/Story/testdata/I011/transcript.txt
vendored
Normal file
1
src/Story/testdata/I011/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
54
|
||||||
0
src/Story/testdata/I012/input.txt
vendored
Normal file
0
src/Story/testdata/I012/input.txt
vendored
Normal file
5
src/Story/testdata/I012/story.ink
vendored
Normal file
5
src/Story/testdata/I012/story.ink
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
VAR x = 0
|
||||||
|
{true:
|
||||||
|
- ~ x = 5
|
||||||
|
}
|
||||||
|
{x}
|
||||||
1
src/Story/testdata/I012/transcript.txt
vendored
Normal file
1
src/Story/testdata/I012/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
5
|
||||||
0
src/Story/testdata/I016/input.txt
vendored
Normal file
0
src/Story/testdata/I016/input.txt
vendored
Normal file
0
src/Story/testdata/I016/story.ink
vendored
Normal file
0
src/Story/testdata/I016/story.ink
vendored
Normal file
0
src/Story/testdata/I016/transcript.txt
vendored
Normal file
0
src/Story/testdata/I016/transcript.txt
vendored
Normal file
0
src/Story/testdata/I017/input.txt
vendored
Normal file
0
src/Story/testdata/I017/input.txt
vendored
Normal file
4
src/Story/testdata/I017/story.ink
vendored
Normal file
4
src/Story/testdata/I017/story.ink
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
hello
|
||||||
|
-> END
|
||||||
|
world
|
||||||
|
-> END
|
||||||
1
src/Story/testdata/I017/transcript.txt
vendored
Normal file
1
src/Story/testdata/I017/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
hello
|
||||||
0
src/Story/testdata/I018/input.txt
vendored
Normal file
0
src/Story/testdata/I018/input.txt
vendored
Normal file
6
src/Story/testdata/I018/story.ink
vendored
Normal file
6
src/Story/testdata/I018/story.ink
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
-> test
|
||||||
|
== test ==
|
||||||
|
hello
|
||||||
|
-> END
|
||||||
|
world
|
||||||
|
-> END
|
||||||
1
src/Story/testdata/I018/transcript.txt
vendored
Normal file
1
src/Story/testdata/I018/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
hello
|
||||||
0
src/Story/testdata/I019/input.txt
vendored
Normal file
0
src/Story/testdata/I019/input.txt
vendored
Normal file
3
src/Story/testdata/I019/story.ink
vendored
Normal file
3
src/Story/testdata/I019/story.ink
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
== test ==
|
||||||
|
Content
|
||||||
|
-> END
|
||||||
0
src/Story/testdata/I019/transcript.txt
vendored
Normal file
0
src/Story/testdata/I019/transcript.txt
vendored
Normal file
0
src/Story/testdata/I021/input.txt
vendored
Normal file
0
src/Story/testdata/I021/input.txt
vendored
Normal file
7
src/Story/testdata/I021/story.ink
vendored
Normal file
7
src/Story/testdata/I021/story.ink
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
-> 2tests
|
||||||
|
== 2tests ==
|
||||||
|
~ temp 512x2 = 512 * 2
|
||||||
|
~ temp 512x2p2 = 512x2 + 2
|
||||||
|
512x2 = {512x2}
|
||||||
|
512x2p2 = {512x2p2}
|
||||||
|
-> DONE
|
||||||
2
src/Story/testdata/I021/transcript.txt
vendored
Normal file
2
src/Story/testdata/I021/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
512x2 = 1024
|
||||||
|
512x2p2 = 1026
|
||||||
0
src/Story/testdata/I023/input.txt
vendored
Normal file
0
src/Story/testdata/I023/input.txt
vendored
Normal file
7
src/Story/testdata/I023/story.ink
vendored
Normal file
7
src/Story/testdata/I023/story.ink
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
-> firstKnot
|
||||||
|
=== firstKnot
|
||||||
|
Hello!
|
||||||
|
-> anotherKnot
|
||||||
|
=== anotherKnot
|
||||||
|
World.
|
||||||
|
-> END
|
||||||
2
src/Story/testdata/I023/transcript.txt
vendored
Normal file
2
src/Story/testdata/I023/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Hello!
|
||||||
|
World.
|
||||||
1
src/Story/testdata/I035/input.txt
vendored
Normal file
1
src/Story/testdata/I035/input.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
||||||
5
src/Story/testdata/I035/story.ink
vendored
Normal file
5
src/Story/testdata/I035/story.ink
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
* hello
|
||||||
|
-> world
|
||||||
|
== world
|
||||||
|
world
|
||||||
|
-> END
|
||||||
3
src/Story/testdata/I035/transcript.txt
vendored
Normal file
3
src/Story/testdata/I035/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
1: hello
|
||||||
|
?> hello
|
||||||
|
world
|
||||||
2
src/Story/testdata/I042/input.txt
vendored
Normal file
2
src/Story/testdata/I042/input.txt
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
1
|
||||||
|
1
|
||||||
4
src/Story/testdata/I042/story.ink
vendored
Normal file
4
src/Story/testdata/I042/story.ink
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
-> test
|
||||||
|
=== test
|
||||||
|
* Hello[.], world.
|
||||||
|
-> END
|
||||||
2
src/Story/testdata/I042/transcript.txt
vendored
Normal file
2
src/Story/testdata/I042/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
1: Hello.
|
||||||
|
?> Hello, world.
|
||||||
0
src/Story/testdata/I051/input.txt
vendored
Normal file
0
src/Story/testdata/I051/input.txt
vendored
Normal file
3
src/Story/testdata/I051/story.ink
vendored
Normal file
3
src/Story/testdata/I051/story.ink
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{x}
|
||||||
|
VAR x = kX
|
||||||
|
CONST kX = "hi"
|
||||||
1
src/Story/testdata/I051/transcript.txt
vendored
Normal file
1
src/Story/testdata/I051/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
hi
|
||||||
0
src/Story/testdata/I064/input.txt
vendored
Normal file
0
src/Story/testdata/I064/input.txt
vendored
Normal file
2
src/Story/testdata/I064/story.ink
vendored
Normal file
2
src/Story/testdata/I064/story.ink
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
-> DONE
|
||||||
|
This content is inaccessible.
|
||||||
0
src/Story/testdata/I064/transcript.txt
vendored
Normal file
0
src/Story/testdata/I064/transcript.txt
vendored
Normal file
1
src/Story/testdata/I078/input.txt
vendored
Normal file
1
src/Story/testdata/I078/input.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
||||||
2
src/Story/testdata/I078/story.ink
vendored
Normal file
2
src/Story/testdata/I078/story.ink
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
* [Option]
|
||||||
|
Text
|
||||||
2
src/Story/testdata/I078/transcript.txt
vendored
Normal file
2
src/Story/testdata/I078/transcript.txt
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
1: Option
|
||||||
|
?> Text
|
||||||
|
|
@ -153,9 +153,14 @@ pub const InternPool = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(ip: *InternPool, gpa: std.mem.Allocator) void {
|
pub fn deinit(ip: *InternPool, gpa: std.mem.Allocator) void {
|
||||||
|
for (ip.code_chunks.items) |chunk| {
|
||||||
|
chunk.constants.deinit(gpa);
|
||||||
|
chunk.bytecode.deinit(gpa);
|
||||||
|
}
|
||||||
ip.values.deinit(gpa);
|
ip.values.deinit(gpa);
|
||||||
ip.values_map.deinit(gpa);
|
ip.values_map.deinit(gpa);
|
||||||
ip.code_chunks.deinit(gpa);
|
ip.code_chunks.deinit(gpa);
|
||||||
|
ip.* = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -179,11 +184,11 @@ pub const Module = struct {
|
||||||
arena: std.mem.Allocator,
|
arena: std.mem.Allocator,
|
||||||
tree: Ast,
|
tree: Ast,
|
||||||
ir: Ir,
|
ir: Ir,
|
||||||
intern_pool: InternPool = .{},
|
|
||||||
globals: std.ArrayListUnmanaged(Global) = .empty,
|
globals: std.ArrayListUnmanaged(Global) = .empty,
|
||||||
knots: std.ArrayListUnmanaged(Knot) = .empty,
|
knots: std.ArrayListUnmanaged(Knot) = .empty,
|
||||||
stitches: std.ArrayListUnmanaged(Stitch) = .empty,
|
stitches: std.ArrayListUnmanaged(Stitch) = .empty,
|
||||||
errors: std.ArrayListUnmanaged(Error) = .empty,
|
errors: std.ArrayListUnmanaged(Error) = .empty,
|
||||||
|
intern_pool: InternPool = .{},
|
||||||
work_queue: WorkQueue = .{},
|
work_queue: WorkQueue = .{},
|
||||||
|
|
||||||
pub const Global = struct {
|
pub const Global = struct {
|
||||||
|
|
@ -277,9 +282,12 @@ pub const Module = struct {
|
||||||
|
|
||||||
while (mod.work_queue.pop()) |work_unit| {
|
while (mod.work_queue.pop()) |work_unit| {
|
||||||
const chunk_index = mod.intern_pool.code_chunks.items.len;
|
const chunk_index = mod.intern_pool.code_chunks.items.len;
|
||||||
|
const code_chunk = try mod.createCodeChunk();
|
||||||
|
try mod.intern_pool.code_chunks.append(gpa, code_chunk);
|
||||||
|
|
||||||
var builder: Sema.Builder = .{
|
var builder: Sema.Builder = .{
|
||||||
.sema = &sema,
|
.sema = &sema,
|
||||||
.code = try mod.createCodeChunk(),
|
.code = code_chunk,
|
||||||
.namespace = work_unit.namespace,
|
.namespace = work_unit.namespace,
|
||||||
};
|
};
|
||||||
defer builder.deinit(gpa);
|
defer builder.deinit(gpa);
|
||||||
|
|
@ -292,7 +300,6 @@ pub const Module = struct {
|
||||||
try builder.finalize();
|
try builder.finalize();
|
||||||
|
|
||||||
knot_index = @enumFromInt(mod.knots.items.len);
|
knot_index = @enumFromInt(mod.knots.items.len);
|
||||||
try mod.intern_pool.code_chunks.append(gpa, builder.code);
|
|
||||||
try mod.knots.append(gpa, .{
|
try mod.knots.append(gpa, .{
|
||||||
.name_index = work_unit.decl_name,
|
.name_index = work_unit.decl_name,
|
||||||
.code_index = @enumFromInt(chunk_index),
|
.code_index = @enumFromInt(chunk_index),
|
||||||
|
|
@ -302,7 +309,6 @@ pub const Module = struct {
|
||||||
try sema.analyzeStitch(&builder, work_unit.inst_index);
|
try sema.analyzeStitch(&builder, work_unit.inst_index);
|
||||||
try builder.finalize();
|
try builder.finalize();
|
||||||
|
|
||||||
try mod.intern_pool.code_chunks.append(gpa, builder.code);
|
|
||||||
try mod.stitches.append(gpa, .{
|
try mod.stitches.append(gpa, .{
|
||||||
.knot_index = knot_index,
|
.knot_index = knot_index,
|
||||||
.name_index = work_unit.decl_name,
|
.name_index = work_unit.decl_name,
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,8 @@ pub const Writer = struct {
|
||||||
.field_divert => try self.writeCallInst(w, inst, .field),
|
.field_divert => try self.writeCallInst(w, inst, .field),
|
||||||
.field_ptr => try self.writeFieldPtrInst(w, inst),
|
.field_ptr => try self.writeFieldPtrInst(w, inst),
|
||||||
.param => try self.writeStrTokInst(w, inst),
|
.param => try self.writeStrTokInst(w, inst),
|
||||||
|
.done => try self.writeUnaryInst(w, inst),
|
||||||
|
.exit => try self.writeUnaryInst(w, inst),
|
||||||
}
|
}
|
||||||
try w.writeAll(")");
|
try w.writeAll(")");
|
||||||
try w.writeAll("\n");
|
try w.writeAll("\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue