lib/choir/src/compiler/root.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const choir = @import("../root.zig");
3 const ir = choir.ir;
4 const dialects = choir.dialects;
5 const extensions = choir.extensions;
6
7 pub const default_compiler_dialects = [_][]const u8{
8 "builtin",
9 "arith",
10 "memref",
11 "scf",
12 "func",
13 };
14
15 pub const ContextOptions = struct {
16 context_limits: ir.Context.Limits,
17 packages: []const extensions.PackageExtension = &.{},
18 preload_dialects: []const []const u8 = &default_compiler_dialects,
19 preload_all_choir_dialects: bool = false,
20 };
21
22 pub const Session = struct {
23 allocator: std.mem.Allocator,
24 ctx: ir.Context,
25 extension_registry: extensions.ExtensionRegistry,
26 live: bool = true,
27
28 pub fn init(allocator: std.mem.Allocator, options: ContextOptions) !Session {
29 var ctx = try ir.Context.init(allocator, options.context_limits);
30 errdefer ctx.deinit(allocator);
31
32 try registerCoreDialects(&ctx);
33
34 var extension_registry = extensions.ExtensionRegistry.init(allocator);
35 errdefer extension_registry.deinit();
36 for (options.packages) |package| {
37 try extension_registry.registerPackage(&ctx, package);
38 }
39 try preloadRequestedDialects(&ctx, options);
40
41 return .{
42 .allocator = allocator,
43 .ctx = ctx,
44 .extension_registry = extension_registry,
45 };
46 }
47
48 pub fn deinit(self: *Session) void {
49 if (!self.live) return;
50 self.extension_registry.deinit();
51 self.ctx.deinit(self.allocator);
52 self.live = false;
53 }
54
55 pub fn context(self: *Session) *ir.Context {
56 return &self.ctx;
57 }
58
59 pub fn extensionRegistry(self: *Session) *extensions.ExtensionRegistry {
60 return &self.extension_registry;
61 }
62 };
63
64 pub fn initContext(allocator: std.mem.Allocator, options: ContextOptions) !ir.Context {
65 var ctx = try ir.Context.init(allocator, options.context_limits);
66 errdefer ctx.deinit(allocator);
67
68 try registerCoreDialects(&ctx);
69 for (options.packages) |package| {
70 try package.registerContext(&ctx);
71 }
72 try preloadRequestedDialects(&ctx, options);
73
74 return ctx;
75 }
76
77 fn registerCoreDialects(ctx: *ir.Context) !void {
78 try ctx.requireRegistered();
79 try dialects.registerChoirDialect(ctx);
80 }
81
82 fn preloadRequestedDialects(ctx: *ir.Context, options: ContextOptions) !void {
83 if (options.preload_all_choir_dialects) {
84 inline for (dialects.choir_registry.entries) |entry| {
85 _ = try ctx.getOrLoadDialect(entry.name);
86 }
87 }
88
89 for (options.preload_dialects) |name| {
90 _ = try ctx.getOrLoadDialect(name);
91 }
92 }