Swift scripts and swift programs

I'm currently writing a Swift program and I need a way to process user-created scripts. I want to do it in a way where there is a script, an API and the script should call this API.

Initially, I wanted to make that happen with Python. However, I don't know if and how I can provide context and values to Python scripts when running them (e.g. setting variables, so they can be accessed from within the script, etc.)

And then it hit me - Swift can be used as a scripting language! I still have the problem of script context and predefined values. Is something similar to Kotlin's scripting engine available for Swift? (Kotlin, being JVM-based, requires everything to be in a class. When scripting with Kotlin, I can create a class on the host and have the script code be run as if it was inside a method of the class, giving me access to its instance methods and properties.)
And how can I even run Swift scripts from within Swift anyway?

Example: Say I want a script to be able to call an API function someFunction(a:b:c:). I can define this function in my compiled Swift program, but how can I make it accessible to a Swift script?

Edit: I forgot to mention that the program in question is not strictly a macOS application. It is a cross-platform command-line tool, and I'm developing on Linux.

2 Likes

This is something I've been wanting for a while. And seems somewhat related to other recently asked things like Is there any similar functionality existing or planned similar to dotNet's MEF system?.

If you want a plugin system I don't think Swift itself provides anything out of the box. But macOS has some plugin documentation that predates Swift.

But for running on the fly user input Swift code I don't think there is any other solution that embedding the compiler in the app.

1 Like

Understood. Is there a way this can be done with Python still? I don't want to have to resort to using Lua

Iā€™m really bit an expert on this kind of system so hopefully somebody else can answer.
But it seems to me that you still need to embed the python interpreter on the app or assume there is a system one.

Particularly i think is easy to just embed Python.

Swift have language constructions like @dynamicCallable that allow to call functions and access variables of foreign VM's directly in Swift code.

Here is a great library to help you embed CPython:

Im not an expert in Swift scripting, but went to that route very superficially once, and the way the current scripting works is by using LLDB. The lldb attach a executable, push the input and call it on the binary. If im not mistaken is a Python script.

So is a little convoluted i think to reuse, but i'm sure is doable. A great hacking resource for me was the swift tensorflow project. There they provide a Swift notebook that execute swift on runtime.

If you ask me now where it is, i wouldn't know, but if you dont find it yourself, i can try to find it again for you..

Edit:

You can also try using a WebAssembly interpreter. Compile Swift to WebAssembly target, get the binary payload and execute it on the interpreter.

Something like