diff --git a/.github/workflows/go-test.yaml b/.github/workflows/go-test.yaml index 42cc0731..681371d6 100644 --- a/.github/workflows/go-test.yaml +++ b/.github/workflows/go-test.yaml @@ -26,6 +26,9 @@ jobs: matrix: os: [macos-12, macos-latest, ubuntu-20.04, ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: "go" steps: - name: Git checkout uses: actions/checkout@v2 @@ -33,6 +36,9 @@ jobs: uses: actions/setup-go@v2 with: go-version: 1.22 + - uses: korandoru/setup-zig@v1 + with: + zig-version: master - name: Ready msys2 uses: msys2/setup-msys2@v2 with: diff --git a/.github/workflows/zig-test.yaml b/.github/workflows/zig-test.yaml new file mode 100644 index 00000000..19344ace --- /dev/null +++ b/.github/workflows/zig-test.yaml @@ -0,0 +1,51 @@ +name: zig-test + +on: + push: + branches: + - main + - master + tags: + - '*' + pull_request: + branches: + - main + paths: + - "zig/**" + - ".github/workflows/zig-test.yaml" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + build-and-test: + defaults: + run: + working-directory: "zig" + strategy: + matrix: + os: [macos-12, macos-latest, ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: korandoru/setup-zig@v1 + with: + zig-version: master + - name: Ready msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: git mingw-w64-x86_64-toolchain + path-type: inherit + if: matrix.os == 'windows-latest' + - name: Check + run: zig fmt --check . + if: matrix.os != 'windows-latest' + - name: Build and Test + run: zig build test diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..989e2c59 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/go/.gitignore b/go/.gitignore index 1847db01..9a61abeb 100644 --- a/go/.gitignore +++ b/go/.gitignore @@ -4,3 +4,4 @@ !lib/**/*.lib !lib/**/*.so !lib/**/*.exe +!lib/**/*.a diff --git a/go/lib/windows-amd64/static/libkclvm_cli_cdylib.a b/go/lib/windows-amd64/static/libkclvm_cli_cdylib.a new file mode 100644 index 00000000..f16f9522 Binary files /dev/null and b/go/lib/windows-amd64/static/libkclvm_cli_cdylib.a differ diff --git a/go/lib/windows-arm64/static/libkclvm_cli_cdylib.a b/go/lib/windows-arm64/static/libkclvm_cli_cdylib.a new file mode 100644 index 00000000..f16f9522 Binary files /dev/null and b/go/lib/windows-arm64/static/libkclvm_cli_cdylib.a differ diff --git a/go/native/cgo.go b/go/native/cgo.go index 74d209f0..3d1dcce4 100644 --- a/go/native/cgo.go +++ b/go/native/cgo.go @@ -1,5 +1,5 @@ -//go:build !windows && cgo -// +build !windows,cgo +//go:build cgo +// +build cgo package native @@ -10,7 +10,7 @@ package native // #cgo linux,arm64 LDFLAGS:-L${SRCDIR}/../lib/linux-arm64 -Wl,-rpath,${SRCDIR}/../lib/linux-arm64 // #cgo darwin,amd64 LDFLAGS:-L${SRCDIR}/../lib/darwin-amd64 -Wl,-rpath,${SRCDIR}/../lib/darwin-amd64 // #cgo darwin,arm64 LDFLAGS:-L${SRCDIR}/../lib/darwin-arm64 -Wl,-rpath,${SRCDIR}/../lib/darwin-arm64 -// #cgo windows,amd64 LDFLAGS:-L${SRCDIR}/../lib/windows-amd64 -Wl,-rpath,${SRCDIR}/../lib/windows-amd64 +// #cgo windows,amd64 LDFLAGS:-L${SRCDIR}/../lib/windows-amd64/static -Wl,-rpath,${SRCDIR}/../lib/windows-amd64 // #include import "C" diff --git a/go/native/client.go b/go/native/client.go index 2289e260..82bf0ec4 100644 --- a/go/native/client.go +++ b/go/native/client.go @@ -1,5 +1,5 @@ -//go:build !windows && cgo -// +build !windows,cgo +//go:build cgo +// +build cgo package native diff --git a/go/native/client_test.go b/go/native/client_test.go index 32dc62d2..00a0c35b 100644 --- a/go/native/client_test.go +++ b/go/native/client_test.go @@ -1,5 +1,5 @@ -//go:build !windows && cgo -// +build !windows,cgo +//go:build cgo +// +build cgo package native diff --git a/go/plugin/api.go b/go/plugin/api.go index a7270034..0abe221d 100644 --- a/go/plugin/api.go +++ b/go/plugin/api.go @@ -1,5 +1,5 @@ -//go:build !windows -// +build !windows +//go:build cgo +// +build cgo // Copyright The KCL Authors. All rights reserved. diff --git a/go/plugin/api_test.go b/go/plugin/api_test.go index e914a154..7047dced 100644 --- a/go/plugin/api_test.go +++ b/go/plugin/api_test.go @@ -1,5 +1,5 @@ -//go:build !windows -// +build !windows +//go:build cgo +// +build cgo // Copyright The KCL Authors. All rights reserved. diff --git a/go/plugin/error.go b/go/plugin/error.go index 3d3fe111..7b033822 100644 --- a/go/plugin/error.go +++ b/go/plugin/error.go @@ -1,5 +1,5 @@ -//go:build !windows -// +build !windows +//go:build cgo +// +build cgo // Copyright The KCL Authors. All rights reserved. diff --git a/go/plugin/plugin.go b/go/plugin/plugin.go index 0b487048..ca5f2b93 100644 --- a/go/plugin/plugin.go +++ b/go/plugin/plugin.go @@ -1,5 +1,5 @@ -//go:build !windows && cgo -// +build !windows,cgo +//go:build cgo +// +build cgo // Copyright The KCL Authors. All rights reserved. @@ -8,13 +8,11 @@ package plugin /* #include #include - -extern char* kcl_go_capi_InvokeJsonProxy( +char* kcl_go_capi_InvokeJsonProxy( char* method, char* args_json, char* kwargs_json ); - static uint64_t kcl_go_capi_getInvokeJsonProxyPtr() { return (uint64_t)(kcl_go_capi_InvokeJsonProxy); } @@ -84,27 +82,24 @@ func _Invoke(method, args_json, kwargs_json string) (result_json string) { } }() - // check method + // Check method name if method == "" { return JSONError(fmt.Errorf("empty method")) } - // parse args, kwargs + // Parse args, kwargs args, err := ParseMethodArgs(args_json, kwargs_json) if err != nil { return JSONError(err) } - // todo: check args type - // todo: check kwargs type - - // get method + // Get plugin method methodSpec, found := GetMethodSpec(method) if !found { return JSONError(fmt.Errorf("invalid method: %s, not found", method)) } - // call plugin method + // Call plugin method result, err := methodSpec.Body(args) if err != nil { return JSONError(err) @@ -113,7 +108,7 @@ func _Invoke(method, args_json, kwargs_json string) (result_json string) { result = new(MethodResult) } - // encode result + // Encode result to JSON data, err := json.Marshal(result.V) if err != nil { return JSONError(err) diff --git a/go/plugin/spec.go b/go/plugin/spec.go index fc122842..1f552665 100644 --- a/go/plugin/spec.go +++ b/go/plugin/spec.go @@ -1,5 +1,5 @@ -//go:build !windows -// +build !windows +//go:build cgo +// +build cgo // Copyright The KCL Authors. All rights reserved. package plugin diff --git a/go/plugin/utils_c_string.go b/go/plugin/utils_c_string.go index 3d68e71c..23bdd172 100644 --- a/go/plugin/utils_c_string.go +++ b/go/plugin/utils_c_string.go @@ -1,5 +1,5 @@ -//go:build !windows && cgo -// +build !windows,cgo +//go:build cgo +// +build cgo // Copyright 2023 The KCL Authors. All rights reserved. diff --git a/nodejs/examples/exec-program/.gitignore b/nodejs/examples/exec-program/.gitignore index a2b5be15..ea9f96ac 100644 --- a/nodejs/examples/exec-program/.gitignore +++ b/nodejs/examples/exec-program/.gitignore @@ -18,6 +18,7 @@ pids *.pid *.seed *.pid.lock +package-lock.json # Directory for instrumented libs generated by jscoverage/JSCover lib-cov @@ -121,7 +122,7 @@ dist .AppleDouble .LSOverride -# Icon must end with two +# Icon must end with two Icon diff --git a/zig/.gitignore b/zig/.gitignore new file mode 100644 index 00000000..647ecf84 --- /dev/null +++ b/zig/.gitignore @@ -0,0 +1,36 @@ + + +*.a +*.o +*.so + +*.exe +*.lib +*.dll + +a.out* +zz_* +/_build* +*.dylib +*.lock +.kclvm + +# KCL cache and temp output +.kclvm +.kclvm_cov +*.dylib +*.so +*.dll +*.d +*.ll +*.ll.lock +_a.out.* +_a.out_*.* + +**/target/ +**/.DS_Store +**/.vscode +__pycache__ +build +zig-out +.zig-cache diff --git a/zig/README.md b/zig/README.md new file mode 100644 index 00000000..acc81cc1 --- /dev/null +++ b/zig/README.md @@ -0,0 +1,15 @@ +# KCL Artifact Library for Zig + +This repo is under development, PRs welcome! + +## Developing + +## Prerequisites + ++ Zig 0.13.0+ + +## Build and Test + +```shell +zig build test +``` diff --git a/zig/build.zig b/zig/build.zig new file mode 100644 index 00000000..b1d3a90c --- /dev/null +++ b/zig/build.zig @@ -0,0 +1,121 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +// Although this function looks imperative, note that its job is to +// declaratively construct a build graph that will be executed by an external +// runner. +pub fn build(b: *std.Build) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + // Standard optimization options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not + // set a preferred release mode, allowing the user to decide how to optimize. + const optimize = b.standardOptimizeOption(.{}); + + const os = target.query.os_tag orelse builtin.os.tag; + + const lib = b.addStaticLibrary(.{ + .name = "kcl_lib_zig", + // In this case the main source file is merely a path, however, in more + // complicated build scripts, this could be a generated file. + .root_source_file = b.path("src/root.zig"), + .target = target, + .optimize = optimize, + }); + + lib.linkLibC(); + lib.linkLibCpp(); + lib.addLibraryPath(kclLibPath(b, &target)); + lib.linkSystemLibrary(kclLibName()); + if (os == .windows) { + linkWindowsLibraries(lib); + } + + // This declares intent for the library to be installed into the standard + // location when the user invokes the "install" step (the default step when + // running `zig build`). + b.installArtifact(lib); + + // Creates a step for unit testing. This only builds the test executable + // but does not run it. + const lib_unit_tests = b.addTest(.{ + .root_source_file = b.path("src/root.zig"), + .target = target, + .optimize = optimize, + }); + + lib_unit_tests.linkLibC(); + lib_unit_tests.linkLibCpp(); + lib_unit_tests.addLibraryPath(kclLibPath(b, &target)); + lib_unit_tests.linkSystemLibrary(kclLibName()); + if (os == .windows) { + linkWindowsLibraries(lib_unit_tests); + } + + const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&run_lib_unit_tests.step); +} + +fn linkWindowsLibraries(lib: *std.Build.Step.Compile) void { + lib.linkSystemLibrary("userenv"); + lib.linkSystemLibrary("ole32"); + lib.linkSystemLibrary("ntdll"); + lib.linkSystemLibrary("kernel32"); + lib.linkSystemLibrary("bcrypt"); + lib.linkSystemLibrary("ws2_32"); +} + +fn kclLibName() []const u8 { + return "kclvm_cli_cdylib"; +} + +fn kclLibPath(b: *std.Build, target: *const std.Build.ResolvedTarget) std.Build.LazyPath { + const os = target.query.os_tag orelse builtin.os.tag; + const arch = target.query.cpu_arch orelse builtin.cpu.arch; + switch (os) { + .windows => { + switch (arch) { + .x86_64 => { + return b.path("../go/lib/windows-amd64/static"); + }, + .x86 => { + return b.path("../go/lib/windows-amd64/static"); + }, + .aarch64 => { + return b.path("../go/lib/windows-arm64/static"); + }, + else => @panic("Unsupported Windows architecture"), + } + }, + .linux => { + switch (arch) { + .x86_64 => { + return b.path("../go/lib/linux-amd64/"); + }, + .x86 => { + return b.path("../go/lib/linux-amd64/"); + }, + .aarch64 => { + return b.path("../go/lib/linux-arm64/"); + }, + else => @panic("Unsupported Linux architecture"), + } + }, + .macos => { + switch (arch) { + .x86_64 => { + return b.path("../go/lib/darwin-amd64/"); + }, + .aarch64 => { + return b.path("../go/lib/darwin-arm64/"); + }, + else => @panic("Unsupported macOS architecture"), + } + }, + else => @panic("Unsupported operating system"), + } +} diff --git a/zig/build.zig.zon b/zig/build.zig.zon new file mode 100644 index 00000000..8f39f23f --- /dev/null +++ b/zig/build.zig.zon @@ -0,0 +1,71 @@ +.{ + // This is the default name used by packages depending on this one. For + // example, when a user runs `zig fetch --save `, this field is used + // as the key in the `dependencies` table. Although the user can choose a + // different name, most users will stick with this provided value. + // + // It is redundant to include "zig" in this name because it is already + // within the Zig package namespace. + .name = "kcl-lib-zig", + + // This is a [Semantic Version](https://semver.org/). + // In a future version of Zig it will be used for package deduplication. + .version = "0.10.0-rc.1", + + // This field is optional. + // This is currently advisory only; Zig does not yet do anything + // with this value. + //.minimum_zig_version = "0.11.0", + + // This field is optional. + // Each dependency must either provide a `url` and `hash`, or a `path`. + // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. + // Once all dependencies are fetched, `zig build` no longer requires + // internet connectivity. + .dependencies = .{ + // See `zig fetch --save ` for a command-line interface for adding dependencies. + //.example = .{ + // // When updating this field to a new URL, be sure to delete the corresponding + // // `hash`, otherwise you are communicating that you expect to find the old hash at + // // the new URL. + // .url = "https://example.com/foo.tar.gz", + // + // // This is computed from the file contents of the directory of files that is + // // obtained after fetching `url` and applying the inclusion rules given by + // // `paths`. + // // + // // This field is the source of truth; packages do not come from a `url`; they + // // come from a `hash`. `url` is just one of many possible mirrors for how to + // // obtain a package matching this `hash`. + // // + // // Uses the [multihash](https://multiformats.io/multihash/) format. + // .hash = "...", + // + // // When this is provided, the package is found in a directory relative to the + // // build root. In this case the package's hash is irrelevant and therefore not + // // computed. This field and `url` are mutually exclusive. + // .path = "foo", + // + // // When this is set to `true`, a package is declared to be lazily + // // fetched. This makes the dependency only get fetched if it is + // // actually used. + // .lazy = false, + //}, + }, + + // Specifies the set of files and directories that are included in this package. + // Only files and directories listed here are included in the `hash` that + // is computed for this package. Only files listed here will remain on disk + // when using the zig package manager. As a rule of thumb, one should list + // files required for compilation plus any license(s). + // Paths are relative to the build root. Use the empty string (`""`) to refer to + // the build root itself. + // A directory listed here means that all files within, recursively, are included. + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + "../LICENSE", + "README.md", + }, +} diff --git a/zig/src/root.zig b/zig/src/root.zig new file mode 100644 index 00000000..8f172f1f --- /dev/null +++ b/zig/src/root.zig @@ -0,0 +1,21 @@ +//! By convention, root.zig is the root source file when making a library. If +//! you are making an executable, the convention is to delete this file and +//! start with main.zig instead. +const std = @import("std"); +const testing = std.testing; + +extern "c" fn kcl_run(filename_ptr: [*c]const u8, src_ptr: [*c]const u8) [*:0]const u8; +extern "c" fn kcl_fmt(src_ptr: [*c]const u8) [*:0]const u8; + +test "basic kcl run functionality" { + const filename = "test.k"; + const source = "a = 1"; + const result = kcl_run(filename, source); + std.debug.print("KCL Run Result: {s}\n", .{result}); +} + +test "basic kcl fmt functionality" { + const source = "a = 1"; + const result = kcl_fmt(source); + std.debug.print("KCL Fmt Result: {s}\n", .{result}); +}