diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Dict.zig | 66 | ||||
| -rw-r--r-- | src/Interpreter.zig | 39 | ||||
| -rw-r--r-- | src/Object.zig | 40 | ||||
| -rw-r--r-- | src/Str.zig | 22 | ||||
| -rw-r--r-- | src/c.h | 1 | ||||
| -rw-r--r-- | src/main.zig | 22 | ||||
| -rw-r--r-- | src/root.zig | 10 |
7 files changed, 200 insertions, 0 deletions
diff --git a/src/Dict.zig b/src/Dict.zig new file mode 100644 index 0000000..89964cf --- /dev/null +++ b/src/Dict.zig @@ -0,0 +1,66 @@ +const std = @import("std"); +const c = @import("c"); + +const zpy = @import("root.zig"); + +const Self = @This(); + +object: zpy.Object, + +pub const Key = union(enum) { + string: [*c]const u8, + object: zpy.Object, +}; + +pub fn new() zpy.Error!Self { + if (c.PyDict_New()) |object| { + return .{ .object = .fromPtr(object) }; + } + + return error.Exception; +} + +pub fn clear(self: *Self) void { + c.PyDict_Clear(self.object.ptr); +} + +pub fn contains(self: *const Self, key: Key) bool { + return switch (key) { + .string => |str| c.PyDict_ContainsString(self.object.ptr, str), + .object => |obj| c.PyDict_Contains(self.object.ptr, obj.ptr), + } == 1; +} + +pub fn copy(self: *const Self) Self { + return .{ .object = .fromPtr(c.PyDict_Copy(self.object.ptr)) }; +} + +pub fn set(self: *Self, key: Key, value: zpy.Object) !void { + const ret = switch (key) { + .string => |str| c.PyDict_SetItemString(self.object.ptr, str, value.ptr), + .object => |obj| c.PyDict_SetItem(self.object.ptr, obj.ptr, value.ptr), + }; + + if (ret == -1) return error.Exception; +} + +pub fn get(self: *const Self, key: Key) ?zpy.Object { + return .fromC(switch (key) { + .string => |str| c.PyDict_GetItemString(self.object.ptr, str), + .object => |obj| c.PyDict_GetItem(self.object.ptr, obj.ptr), + }); +} + +pub fn delete(self: *Self, key: Key) !void { + const ret = switch (key) { + .string => |str| c.PyDict_DelItemString(self.object.ptr, str), + .object => |obj| c.PyDict_DelItem(self.object.ptr, obj.ptr), + }; + + if (ret == -1) return error.Exception; +} + +pub fn deinit(self: *Self) void { + self.object.decref(); + self.* = undefined; +} diff --git a/src/Interpreter.zig b/src/Interpreter.zig new file mode 100644 index 0000000..6862706 --- /dev/null +++ b/src/Interpreter.zig @@ -0,0 +1,39 @@ +const c = @import("c"); + +const zpy = @import("root.zig"); + +const Self = @This(); + +globals: zpy.Dict, + +pub fn init() !Self { + c.Py_Initialize(); + + const self: Self = .{ + .globals = try .new(), + }; + + return self; +} + +pub const RunOptions = struct { + locals: ?*zpy.Dict = null, +}; + +pub fn run(self: *Self, str: [*c]const u8, options: RunOptions) zpy.Error!zpy.Object { + if (c.PyRun_String( + str, + c.Py_file_input, + self.globals.object.ptr, + if (options.locals) |loc| loc.object.ptr else null, + )) |object| { + return .fromPtr(object); + } + + return error.Exception; +} + +pub fn deinit(self: *Self) void { + c.Py_Finalize(); + self.* = undefined; +} diff --git a/src/Object.zig b/src/Object.zig new file mode 100644 index 0000000..782071f --- /dev/null +++ b/src/Object.zig @@ -0,0 +1,40 @@ +const std = @import("std"); +const c = @import("c"); +const zpy = @import("root.zig"); + +const Self = @This(); + +ptr: *c.PyObject, + +pub fn fromPtr(ptr: *c.PyObject) Self { + return .{ .ptr = ptr }; +} + + +pub fn fromC(ptr: [*c]c.PyObject) ?Self { + return if (ptr) |p| .fromPtr(p) else null; +} + +pub fn decref(self: *Self) void { + c.Py_DecRef(self.ptr); +} + +pub fn repr(self: *const Self) zpy.Str { + return .{ .object = .fromPtr(c.PyObject_Repr(self.ptr)) }; +} + +pub fn call(self: *Self, args: anytype) zpy.Error!zpy.Object { + _ = args; + if (c.PyObject_CallObject(self.ptr, null)) |object| { + return .fromPtr(object); + } + + return error.Exception; +} + +pub fn format(self: *const Self, writer: *std.Io.Writer) !void { + var str = self.repr(); + defer str.deinit(); + + try writer.print("{s}", .{str.asUtf8() catch return error.WriteFailed}); +} diff --git a/src/Str.zig b/src/Str.zig new file mode 100644 index 0000000..eaca378 --- /dev/null +++ b/src/Str.zig @@ -0,0 +1,22 @@ + +const c = @import("c"); +const zpy = @import("root.zig"); + +const Self = @This(); + +object: zpy.Object, + + +pub fn asUtf8(self: *Self) zpy.Error![]const u8 { + var size: c.Py_ssize_t = undefined; + const string: [*]const u8 = c.PyUnicode_AsUTF8AndSize(self.object.ptr, &size); + + if (size == -1) return error.Exception; + + return string[0..@as(usize, @intCast(size))]; +} + +pub fn deinit(self: *Self) void { + self.object.decref(); + self.* = undefined; +} @@ -0,0 +1 @@ +#include <Python.h> diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..a39c79f --- /dev/null +++ b/src/main.zig @@ -0,0 +1,22 @@ +const std = @import("std"); +const Io = std.Io; + +const zpy = @import("zpy"); + +pub fn main() !void { + var py: zpy.Interpreter = try .init(); + defer py.deinit(); + + var locals = try zpy.Dict.new(); + defer locals.deinit(); + + _ = try py.run("def test(): print('hello')", .{ + .locals = &locals, + }); + + var test_fn = locals.get(.{ .string = "test" }) orelse unreachable; + defer test_fn.decref(); + const result = try test_fn.call(.{}); + + std.debug.print("test() = {f}\n", .{result}); +} diff --git a/src/root.zig b/src/root.zig new file mode 100644 index 0000000..0e3d9e4 --- /dev/null +++ b/src/root.zig @@ -0,0 +1,10 @@ +const std = @import("std"); + +pub const Object = @import("Object.zig"); +pub const Interpreter = @import("Interpreter.zig"); +pub const Dict = @import("Dict.zig"); +pub const Str = @import("Str.zig"); + +pub const Error = error { + Exception, +}; |