quotationBuilder.zig(檔案已創建)
| @@ -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 | + | }; | |
上一頁
下一頁