feature. See also
. The project being documented here (as the example) is the Zig library itself.
compile.compile
pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions) !void
File
Code
pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions) !void {
var lexer = lex.Lexer.init(source, .{
.default_code_page = options.default_code_page,
.source_mappings = options.source_mappings,
.max_string_literal_codepoints = options.max_string_literal_codepoints,
});
var parser = Parser.init(&lexer, .{
.warn_instead_of_error_on_invalid_code_page = options.warn_instead_of_error_on_invalid_code_page,
.disjoint_code_page = options.disjoint_code_page,
});
var tree = try parser.parse(allocator, options.diagnostics);
defer tree.deinit();
var search_dirs: std.ArrayList(SearchDir) = .empty;
defer {
for (search_dirs.items) |*search_dir| {
search_dir.deinit(allocator, io);
}
search_dirs.deinit(allocator);
}
if (options.source_mappings) |source_mappings| {
const root_path = source_mappings.files.get(source_mappings.root_filename_offset);
// the cwd so we don't need to add it as a distinct search path.
if (std.fs.path.dirname(root_path)) |root_dir_path| {
var root_dir = try options.cwd.openDir(io, root_dir_path, .{});
errdefer root_dir.close(io);
try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) });
}
}
const cwd_dir = options.cwd.openDir(io, ".", .{}) catch |err| {
try options.diagnostics.append(.{
.err = .failed_to_open_cwd,
.token = .{
.id = .invalid,
.start = 0,
.end = 0,
.line_number = 1,
},
.code_page = .utf8,
.print_source_line = false,
.extra = .{ .file_open_error = .{
.err = ErrorDetails.FileOpenError.enumFromError(err),
.filename_string_index = undefined,
} },
});
return error.CompileError;
};
try search_dirs.append(allocator, .{ .dir = cwd_dir, .path = null });
for (options.extra_include_paths) |extra_include_path| {
var dir = openSearchPathDir(options.cwd, io, extra_include_path) catch {
continue;
};
errdefer dir.close(io);
try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, extra_include_path) });
}
for (options.system_include_paths) |system_include_path| {
var dir = openSearchPathDir(options.cwd, io, system_include_path) catch {
continue;
};
errdefer dir.close(io);
try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) });
}
if (!options.ignore_include_env_var) {
const INCLUDE = options.include_env_value orelse "";
// delimiter. There's no precedence set by `rc.exe` since it's Windows-only.
const delimiter = switch (builtin.os.tag) {
.windows => ';',
else => ':',
};
var it = std.mem.tokenizeScalar(u8, INCLUDE, delimiter);
while (it.next()) |search_path| {
var dir = openSearchPathDir(options.cwd, io, search_path) catch continue;
errdefer dir.close(io);
try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, search_path) });
}
}
var arena_allocator = std.heap.ArenaAllocator.init(allocator);
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
var compiler: Compiler = .{
.source = source,
.arena = arena,
.allocator = allocator,
.io = io,
.cwd = options.cwd,
.diagnostics = options.diagnostics,
.dependencies = options.dependencies,
.input_code_pages = &tree.input_code_pages,
.output_code_pages = &tree.output_code_pages,
.search_dirs = search_dirs.items,
.null_terminate_string_table_strings = options.null_terminate_string_table_strings,
.silent_duplicate_control_ids = options.silent_duplicate_control_ids,
};
if (options.default_language_id) |default_language_id| {
compiler.state.language = res.Language.fromInt(default_language_id);
}
try compiler.writeRoot(tree.root(), writer);
}