Ultima attività 1 day ago

yumaikas's Avatar yumaikas ha revisionato questo gist 1 day ago. Vai alla revisione

1 file changed, 84 insertions

quotationBuilder.zig(file creato)

@@ -0,0 +1,84 @@
1 + const 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 + };
Più nuovi Più vecchi