diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78562f3..6314a58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,11 +16,6 @@ jobs: uses: goto-bus-stop/setup-zig@v2 with: version: 0.13.0 - - - name: Setup Python3.10 - uses: actions/setup-python@v2 - with: - python-version: '3.10' - name: Restore cache uses: actions/cache/restore@v3 diff --git a/build.zig b/build.zig index e0245c1..58a4808 100644 --- a/build.zig +++ b/build.zig @@ -57,8 +57,8 @@ pub fn build(b: *std.Build) !void { exe_options.addOption(usize, "src_file_trimlen", std.fs.path.dirname(std.fs.path.dirname(@src().file).?).?.len); exe_options.addOption(bool, "enable_debug_extensions", enable_debug_extensions); exe_options.addOption(bool, "build_debug", enable_debug); - exe_options.addOption([]const u8, "lib_path", "../python/Lib"); exe.root_module.addOptions("options", exe_options); + exe_options.addOption([]const u8, "lib_path", b.fmt("{s}/python/Lib", .{b.install_path})); const tracer_dep = b.dependency("tracer", .{ .optimize = optimize, .target = target }); const libgc_dep = b.dependency("libgc", .{ .optimize = optimize, .target = target }); @@ -74,11 +74,17 @@ pub fn build(b: *std.Build) !void { } } + const libpython_install = b.addInstallDirectory(.{ + .source_dir = cpython_dep.builder.dependency("python", .{}).path("Lib"), + .install_dir = .{ .custom = "python" }, + .install_subdir = "Lib", + }); + exe.step.dependOn(&libpython_install.step); + const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); if (b.args) |args| run_cmd.addArgs(args); - const run_step = b.step("run", "Run the app"); run_step.dependOn(&run_cmd.step); @@ -86,8 +92,8 @@ pub fn build(b: *std.Build) !void { generateOpCode(b, opcode_step); const test_step = b.step("test", "Test Osmium"); - try cases.addCases(b, exe, test_step); - // test_step.dependOn(&libpython_install.step); + try cases.addCases(b, target, test_step, exe, cpython_dep.artifact("cpython")); + test_step.dependOn(&libpython_install.step); } const TraceBackend = enum { diff --git a/build.zig.zon b/build.zig.zon index 0dab5bc..a116563 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -13,9 +13,6 @@ .url = "https://github.com/Rexicon226/zig-tracer/archive/6400e066bb3849be4906f3b6e124d6c8c5a5083f.tar.gz", .hash = "122057453dba0b0cf6f07610d692cc7ab3f1d66defa150c936b398144812564a0c08", }, - .cpython = .{ - .path = "../zig-cpython", - }, .libgc = .{ .url = "https://github.com/Rexicon226/zig-libgc/archive/1ea12e140ec1471af5d15dae71b225764c9747ba.tar.gz", .hash = "12209ad7282d9422973afe3e468e2f867bb102d04fa446a1d1c94f900bda94b7c68e", @@ -25,5 +22,9 @@ .hash = "12206f2265ca2262f919ec125ff7fe15fa6f3be622806e211d7a9bd3055ba51a0908", .lazy = true, }, + .cpython = .{ + .url = "https://github.com/Rexicon226/zig-cpython/archive/969708680122dc4548d64adfae041261e2af480c.tar.gz", + .hash = "1220240c0fd3b1b062483c3f9f41b610181cdf70a47e047ae6379247178b20c34024", + }, }, } diff --git a/examples/calculator.py b/examples/calculator.py deleted file mode 100644 index 7958851..0000000 --- a/examples/calculator.py +++ /dev/null @@ -1,9 +0,0 @@ -def add(x, y) -> int: - return x + y - -in1 = input("Input 1st number: ") -in2 = input("Input 2nd number: ") - -result = add(int(in1), int(in2)) - -print("Result: ", result) \ No newline at end of file diff --git a/src/frontend/Python.zig b/src/frontend/Python.zig index 8d1954f..b5eefd7 100644 --- a/src/frontend/Python.zig +++ b/src/frontend/Python.zig @@ -87,7 +87,7 @@ pub fn Initialize( _ = externs.PyConfig_Read(&config); const utf32_path = try utf8ToUtf32Z( - "/home/dr/Zython/osmium/zig-out/python/Lib", + build_options.lib_path, allocator, ); diff --git a/graph/plot.py b/src/graph/plot.py similarity index 100% rename from graph/plot.py rename to src/graph/plot.py diff --git a/graph/requirements.txt b/src/graph/requirements.txt similarity index 100% rename from graph/requirements.txt rename to src/graph/requirements.txt diff --git a/tests/cases.zig b/tests/cases.zig index 4724b6d..a2f8cb6 100644 --- a/tests/cases.zig +++ b/tests/cases.zig @@ -3,7 +3,6 @@ // SPDX-License-Identifier: GPL-3.0-only const std = @import("std"); -const matrix = @import("matrix.zig"); const Build = std.Build; const Step = Build.Step; @@ -14,8 +13,81 @@ const test_dirs: []const []const u8 = &.{ "behaviour", }; -pub fn addCases(b: *Build, exe: *Step.Compile, parent_step: *Step) !void { +pub fn addCases( + b: *Build, + target: std.Build.ResolvedTarget, + parent_step: *Step, + osmium: *Step.Compile, + python: *Step.Compile, +) !void { + parent_step.dependOn(&python.step); + + const compare_tool = b.addExecutable(.{ + .name = "compare", + .root_source_file = b.path("tools/compare.zig"), + .target = target, + .optimize = .ReleaseSafe, + .omit_frame_pointer = false, // we need the stack trace + }); + for (test_dirs) |dir| { - parent_step.dependOn(try matrix.addCases(b, dir, exe)); + const files = try getPyFilesInDir(b, b.fmt("tests/{s}", .{dir}), b.allocator); + for (files) |file| { + parent_step.dependOn(addCase(b, file, osmium, python, compare_tool)); + } + } +} + +fn addCase( + b: *std.Build, + file_path: []const u8, + osmium: *std.Build.Step.Compile, + python: *std.Build.Step.Compile, + compare: *std.Build.Step.Compile, +) *std.Build.Step { + const python_run = b.addRunArtifact(python); + python_run.addArg(file_path); + const lib_path = b.fmt("{s}/python/Lib", .{b.install_path}); + python_run.setEnvironmentVariable("PYTHONHOME", lib_path); + python_run.setEnvironmentVariable("PYTHONPATH", lib_path); + const python_stdout = python_run.captureStdOut(); + + const osmium_run = b.addRunArtifact(osmium); + osmium_run.addArg(file_path); + const osmium_stdout = osmium_run.captureStdOut(); + + const compare_run = b.addRunArtifact(compare); + compare_run.addFileArg(osmium_stdout); + compare_run.addFileArg(python_stdout); + compare_run.expectExitCode(0); + compare_run.setName(file_path); + + return &compare_run.step; +} + +pub fn getPyFilesInDir( + b: *std.Build, + dir_path: []const u8, + allocator: std.mem.Allocator, +) ![]const []const u8 { + var files = std.ArrayList([]const u8).init(allocator); + defer files.deinit(); + + var dir = try b.build_root.handle.openDir(dir_path, .{ .iterate = true }); + var it = dir.iterate(); + while (try it.next()) |file| { + if (file.kind != .file) { + continue; + } + if (!std.mem.endsWith(u8, file.name, ".py")) { + continue; + } + try files.append(try std.mem.concat(allocator, u8, &.{ + dir_path, + &.{std.fs.path.sep}, + file.name, + })); } + + return files.toOwnedSlice(); } diff --git a/tests/matrix.zig b/tests/matrix.zig deleted file mode 100644 index 0e04dbe..0000000 --- a/tests/matrix.zig +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2024, David Rubin -// -// SPDX-License-Identifier: GPL-3.0-only - -const std = @import("std"); -const File = std.fs.File; -const Allocator = std.mem.Allocator; - -const Step = std.Build.Step; -const Run = std.Build.Step.Run; - -const MatrixError = error{}; - -pub fn addCases(b: *std.Build, test_dir: []const u8, exe: *Step.Compile) !*Step { - const root_path = try b.build_root.join(b.allocator, &.{ "tests", test_dir }); - - const dir_step = b.step(std.fs.path.basename(test_dir), b.fmt("Tests the files in {s}", .{test_dir})); - const files = try getPyFilesInDir(root_path, b.allocator); - - for (files) |test_file| { - const test_run = try addCase(b, test_file, exe); - dir_step.dependOn(&test_run.step); - } - - return dir_step; -} - -pub fn addCase(b: *std.Build, path: []const u8, exe: *Step.Compile) !*Run { - // Compare against CPython output. - const result = try std.process.Child.run(.{ - .allocator = b.allocator, - .argv = &.{ - "python3.10", - path, - }, - .cwd = std.fs.path.dirname(path).?, - .expand_arg0 = .expand, - }); - - const run_cmd = b.addRunArtifact(exe); - run_cmd.addArg(path); - - run_cmd.expectStdOutEqual(result.stdout); - return run_cmd; -} - -pub fn getPyFilesInDir(dir_path: []const u8, allocator: Allocator) ![]const []const u8 { - var files = std.ArrayList([]const u8).init(allocator); - defer files.deinit(); - - var dir = try std.fs.cwd().openDir(dir_path, .{ .iterate = true }); - var it = dir.iterate(); - while (try it.next()) |file| { - if (file.kind != .file) { - continue; - } - if (!std.mem.endsWith(u8, file.name, ".py")) { - continue; - } - try files.append(try std.mem.concat(allocator, u8, &.{ - dir_path, - &.{std.fs.path.sep}, - file.name, - })); - } - - return try files.toOwnedSlice(); -} diff --git a/tools/compare.zig b/tools/compare.zig new file mode 100644 index 0000000..4e3ec4a --- /dev/null +++ b/tools/compare.zig @@ -0,0 +1,24 @@ +const std = @import("std"); +const assert = std.debug.assert; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + const process_args = try std.process.argsAlloc(allocator); + defer std.process.argsFree(allocator, process_args); + assert(process_args.len == 3); + + const osmium_path = process_args[1]; + const python_path = process_args[2]; + + const osmium_contents = try std.fs.cwd().readFileAlloc(allocator, osmium_path, 10 * 1024); + const python_contents = try std.fs.cwd().readFileAlloc(allocator, python_path, 10 * 1024); + defer { + allocator.free(osmium_contents); + allocator.free(python_contents); + } + + try std.testing.expectEqualSlices(u8, python_contents, osmium_contents); +} diff --git a/vendor/README.md b/vendor/README.md deleted file mode 100644 index f09998e..0000000 --- a/vendor/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `vendor` - -These are all the different vendored files. \ No newline at end of file diff --git a/vendor/opcode.h b/vendor/opcode.h deleted file mode 100644 index 5203975..0000000 --- a/vendor/opcode.h +++ /dev/null @@ -1,172 +0,0 @@ -/* Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py */ -#ifndef Py_OPCODE_H -#define Py_OPCODE_H -#ifdef __cplusplus -extern "C" { -#endif - - - /* Instruction opcodes for compiled code */ -#define POP_TOP 1 -#define ROT_TWO 2 -#define ROT_THREE 3 -#define DUP_TOP 4 -#define DUP_TOP_TWO 5 -#define ROT_FOUR 6 -#define NOP 9 -#define UNARY_POSITIVE 10 -#define UNARY_NEGATIVE 11 -#define UNARY_NOT 12 -#define UNARY_INVERT 15 -#define BINARY_MATRIX_MULTIPLY 16 -#define INPLACE_MATRIX_MULTIPLY 17 -#define BINARY_POWER 19 -#define BINARY_MULTIPLY 20 -#define BINARY_MODULO 22 -#define BINARY_ADD 23 -#define BINARY_SUBTRACT 24 -#define BINARY_SUBSCR 25 -#define BINARY_FLOOR_DIVIDE 26 -#define BINARY_TRUE_DIVIDE 27 -#define INPLACE_FLOOR_DIVIDE 28 -#define INPLACE_TRUE_DIVIDE 29 -#define GET_LEN 30 -#define MATCH_MAPPING 31 -#define MATCH_SEQUENCE 32 -#define MATCH_KEYS 33 -#define COPY_DICT_WITHOUT_KEYS 34 -#define WITH_EXCEPT_START 49 -#define GET_AITER 50 -#define GET_ANEXT 51 -#define BEFORE_ASYNC_WITH 52 -#define END_ASYNC_FOR 54 -#define INPLACE_ADD 55 -#define INPLACE_SUBTRACT 56 -#define INPLACE_MULTIPLY 57 -#define INPLACE_MODULO 59 -#define STORE_SUBSCR 60 -#define DELETE_SUBSCR 61 -#define BINARY_LSHIFT 62 -#define BINARY_RSHIFT 63 -#define BINARY_AND 64 -#define BINARY_XOR 65 -#define BINARY_OR 66 -#define INPLACE_POWER 67 -#define GET_ITER 68 -#define GET_YIELD_FROM_ITER 69 -#define PRINT_EXPR 70 -#define LOAD_BUILD_CLASS 71 -#define YIELD_FROM 72 -#define GET_AWAITABLE 73 -#define LOAD_ASSERTION_ERROR 74 -#define INPLACE_LSHIFT 75 -#define INPLACE_RSHIFT 76 -#define INPLACE_AND 77 -#define INPLACE_XOR 78 -#define INPLACE_OR 79 -#define LIST_TO_TUPLE 82 -#define RETURN_VALUE 83 -#define IMPORT_STAR 84 -#define SETUP_ANNOTATIONS 85 -#define YIELD_VALUE 86 -#define POP_BLOCK 87 -#define POP_EXCEPT 89 -#define HAVE_ARGUMENT 90 -#define STORE_NAME 90 -#define DELETE_NAME 91 -#define UNPACK_SEQUENCE 92 -#define FOR_ITER 93 -#define UNPACK_EX 94 -#define STORE_ATTR 95 -#define DELETE_ATTR 96 -#define STORE_GLOBAL 97 -#define DELETE_GLOBAL 98 -#define ROT_N 99 -#define LOAD_CONST 100 -#define LOAD_NAME 101 -#define BUILD_TUPLE 102 -#define BUILD_LIST 103 -#define BUILD_SET 104 -#define BUILD_MAP 105 -#define LOAD_ATTR 106 -#define COMPARE_OP 107 -#define IMPORT_NAME 108 -#define IMPORT_FROM 109 -#define JUMP_FORWARD 110 -#define JUMP_IF_FALSE_OR_POP 111 -#define JUMP_IF_TRUE_OR_POP 112 -#define JUMP_ABSOLUTE 113 -#define POP_JUMP_IF_FALSE 114 -#define POP_JUMP_IF_TRUE 115 -#define LOAD_GLOBAL 116 -#define IS_OP 117 -#define CONTAINS_OP 118 -#define RERAISE 119 -#define JUMP_IF_NOT_EXC_MATCH 121 -#define SETUP_FINALLY 122 -#define LOAD_FAST 124 -#define STORE_FAST 125 -#define DELETE_FAST 126 -#define GEN_START 129 -#define RAISE_VARARGS 130 -#define CALL_FUNCTION 131 -#define MAKE_FUNCTION 132 -#define BUILD_SLICE 133 -#define LOAD_CLOSURE 135 -#define LOAD_DEREF 136 -#define STORE_DEREF 137 -#define DELETE_DEREF 138 -#define CALL_FUNCTION_KW 141 -#define CALL_FUNCTION_EX 142 -#define SETUP_WITH 143 -#define EXTENDED_ARG 144 -#define LIST_APPEND 145 -#define SET_ADD 146 -#define MAP_ADD 147 -#define LOAD_CLASSDEREF 148 -#define MATCH_CLASS 152 -#define SETUP_ASYNC_WITH 154 -#define FORMAT_VALUE 155 -#define BUILD_CONST_KEY_MAP 156 -#define BUILD_STRING 157 -#define LOAD_METHOD 160 -#define CALL_METHOD 161 -#define LIST_EXTEND 162 -#define SET_UPDATE 163 -#define DICT_MERGE 164 -#define DICT_UPDATE 165 -#ifdef NEED_OPCODE_JUMP_TABLES -static uint32_t _PyOpcode_RelativeJump[8] = { - 0U, - 0U, - 536870912U, - 67125248U, - 67141632U, - 0U, - 0U, - 0U, -}; -static uint32_t _PyOpcode_Jump[8] = { - 0U, - 0U, - 536870912U, - 101695488U, - 67141632U, - 0U, - 0U, - 0U, -}; -#endif /* OPCODE_TABLES */ - -/* EXCEPT_HANDLER is a special, implicit block type which is created when - entering an except handler. It is not an opcode but we define it here - as we want it to be available to both frameobject.c and ceval.c, while - remaining private.*/ -#define EXCEPT_HANDLER 257 - -#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OPCODE_H */