Zuletzt aktiv 1 day ago

Änderung 3f131f36058fd8a45ea4cfe892866cb86c096c76

quotationBuilder.zig Originalformat Playground
1const QuotationBuilder = struct {
2 symbols: std.ArrayList(vm.Symbol),
3 ops: std.ArrayList(vm.Op),
4 literals: std.ArrayList(vm.Value),
5 alloc: std.mem.Allocator,
6 postQuoteSymbol: ?vm.Symbol,
7
8 fn idxForLiteral(self: *QuotationBuilder, toFind: struct {vm.Value, *bool }) !u16 {
9 const literal, const found = toFind;
10 for (self.literals.items, 0..) |i,idx| {
11 if (i.equal(literal)) {
12 found.* = true;
13 return @intCast(idx);
14 }
15 }
16 found.* = false;
17 if (self.literals.items.len >= 65535) {
18 return ParseError.TooManyLiteralsInQuotation;
19 }
20 const slot: u16 = @intCast(self.literals.items.len);
21 try self.literals.append(self.alloc, literal);
22 return slot;
23 }
24
25 pub fn compile(self: *QuotationBuilder, toCompile: Compilation) !void {
26 switch(toCompile) {
27 .op => try self.ops.append(self.alloc, toCompile.op),
28 .lit => try self.ops.appendSlice(self.alloc, &.{
29 .LIT, @enumFromInt(try self.idxForLiteral(toCompile.lit)),
30 }),
31 .immediate => try self.ops.append(self.alloc,
32 @enumFromInt(try self.idxForLiteral(toCompile.immediate))),
33 }
34 }
35 pub fn comp(self: *QuotationBuilder, toCompile: []const Compilation) !void {
36 for (toCompile) |c| { try self.compile(c); }
37 }
38
39 pub fn addSymbolFrom(self: *QuotationBuilder, name: []const u8, location: source.Location) !void {
40 try self.addSymbol(.{ .name=name, .location=location });
41 }
42
43 pub fn addSymbol(self: *QuotationBuilder, s: vm.Symbol) !void {
44 try self.symbols.append(self.alloc, s);
45 }
46
47 pub fn toCodeObj(self: *QuotationBuilder) !vm.Value {
48 return .{ .quotation = try self.toQuotation() };
49 }
50
51 pub fn toQuotation(self: *QuotationBuilder) !*vm.Quotation {
52 const ret = try self.alloc.create(vm.Quotation);
53 ret.* = .{
54 .refcount = 0,
55 .symbols = try self.symbols.toOwnedSlice(self.alloc),
56 .ops = try self.ops.toOwnedSlice(self.alloc),
57 .literals = try self.literals.toOwnedSlice(self.alloc),
58 .alloc = self.alloc,
59 };
60 return ret;
61 }
62
63 pub fn init(gpa: std.mem.Allocator) !*QuotationBuilder {
64 const me = try gpa.create(QuotationBuilder);
65 me.* = .{
66 .symbols = try std.ArrayList(vm.Symbol).initCapacity(gpa, 32),
67 .ops = try std.ArrayList(vm.Op).initCapacity(gpa, 128),
68 .literals = try std.ArrayList(vm.Value).initCapacity(gpa, 16),
69 .postQuoteSymbol = null,
70 .alloc = gpa,
71 };
72 return me;
73 }
74
75 pub fn deinit(self: *QuotationBuilder) void {
76 self.symbols.deinit(self.alloc);
77 self.ops.deinit(self.alloc);
78 // for (self.literals.items) |i| { i.deref(); }
79 self.literals.deinit(self.alloc);
80 if (self.postQuoteSymbol) |s| { s.deinit(self.alloc); }
81 self.alloc.destroy(self);
82 }
83
84};
85