Factorial calculation with Lua and Swift

image credits

The result of multiplying a given number of consecutive integers from 1 to the given number. In equations, it is symbolized by an exclamation mark (!). For example, 5! = 1 × 2 × 3 × 4 × 5 = 120. – Wiktionary: factorial

In the previous blog post I showed how Lua can be integrated within Swift. In this blog post we will call a Lua function from Swift and print the result. For this I use a factorial example where the code is called recursively. In the next step / blog post the Lua code will call the Swift code, which again calls the Lua code. This is a recursion within programming languages 🤯.

But first we adapt the project for the Factorial Example. The following steps are necessary:

  • Factorial Lua Code
  • Implement call function
  • Adjust ViewController.swift

You can find the source code on Github.

Factorial Lua Code

Extend or replace the script.lua file with this Lua code:

-- factorial
function factorial(n)
    if (n == 0) then
        return 1
    else
        return n * factorial(n - 1)
    end
end

The factorial function is called with a number. This number is multiplied by the next lower number. The factorial method is called recursively and the number is reduced by 1. This is done until the number is 0. In this case, the previous result is multiplied by 1, otherwise everything would be 0.

The script.lua file only defines the factorial method but doesn’t run it. To execute it and read the result, we implement a call method in the luaWrapper files.

Implement call function

luaWrapper.h

The call method is called with these parameters:

  • the Lua state
  • the method name of the Lua function
  • the parameter of the Lua function, in this case the number to be factorized

Insert the following code into the luaWrapper.h file before @end:

- (LUA_NUMBER) call: (lua_State *) state
            methode: (const char *) methode
              value: (LUA_NUMBER) value;

luaWrapper.m

If the call method is called with a state, then this state is used, otherwise the internal state. This is necessary for the next blog post.

lua_getglobal sets the Lua function name on the stack, just like the lua_pushnumber method which sets the parameter. The lua_pcall method (see lua_pacall) reads the parameter and function name and executes the Lua function. The result is written to the stack. The parameters in the lua_pcall method are the state, the number of passed parameters, the number of return values and a stack index in case of an error.

- (LUA_NUMBER) call: (lua_State *) state
            methode:  (const char *) methode
              value: (LUA_NUMBER) value {

    lua_State * luaStateEx = luaState;

    if (state != Nil) {
        luaStateEx = state;
    }

    lua_getglobal(luaStateEx, methode);
    lua_pushnumber(luaStateEx, value);
    lua_pcall(luaStateEx, 1, 1, 0);

    LUA_NUMBER result = lua_tonumber(luaStateEx, -1);
    lua_pop(luaStateEx, 1);
    return result;
}

After the lua_pcall call the result is on the stack. The lua_tonumber method reads it and converts it into a number. The lua_pop method takes it from the stack.

Insert the code into luaWrapper.m file (before @end).

Adjust ViewController.swift

Add the following code to the ViewController.swift file in the viewDidLoad method after free(ptrScript):

let ptrFname = strdup("factorial")
let value = lua_Number(100)
let result = lua.call(nil, methode: ptrFname, value: value)
free(ptrFname)
print(result)

The call method — defined in the luaWrapper files — is called with the function name of the Lua function and the value which will be factorized. At the end the result is printed.

For this example the output of factorial 100! is 9.33262154439441e+157 (see Wolfram Alpha for the exact output).

Next

In this example I have shown how to call a Lua function in Swift and read the result. In the next blog post I show how to register a Swift function so that it can be used by Lua. Since we use a recursive function, I thought a recursion inside Lua and Swift might be interesting.