Skip to content

Commit

Permalink
Implement function
Browse files Browse the repository at this point in the history
  • Loading branch information
kaklakariada committed Sep 20, 2024
1 parent 2e6954a commit bf580de
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 4 deletions.
15 changes: 12 additions & 3 deletions src/main/java/org/itsallcode/jlua/LowLevelLua.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,20 @@ LuaStack stack() {
}

LuaTable table(final int idx) {
assertType(idx, LuaType.TABLE);
return new LuaTable(state, stack, arena, idx);
}

public LuaFunction function(final int idx) {
assertType(idx, LuaType.FUNCTION);
return new LuaFunction(state, stack, arena, idx);
}

private void assertType(final int idx, final LuaType expectedType) {
final LuaType type = stack().getType(idx);
if (type != LuaType.TABLE) {
throw new LuaException("Expected table on the stack but got " + type);
if (type != expectedType) {
throw new LuaException("Expected " + expectedType + " at " + idx + " but got " + type);
}
return new LuaTable(state, stack, arena, idx);
}

boolean isYieldable() {
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/org/itsallcode/jlua/LuaFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.itsallcode.jlua;

import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;

import org.itsallcode.jlua.ffi.Lua;

public class LuaFunction {

private final MemorySegment state;
private final LuaStack stack;
private final Arena arena;
private final int idx;

LuaFunction(final MemorySegment state, final LuaStack stack, final Arena arena, final int idx) {
this.state = state;
this.stack = stack;
this.arena = arena;
this.idx = idx;
}

public void addArgInteger(final int value) {
stack.pushInteger(value);
}

public void call(final int nargs, final int nresults) {
call(nargs, nresults, 0, 0, Lua.NULL());
}

private void call(final int nargs, final int nresults, final int errfunc, final long ctx, final MemorySegment k) {
final int status = Lua.lua_pcallk(state, nargs, nresults, errfunc, ctx, k);
if (status != Lua.LUA_OK()) {
final String errorMessage = stack.toString(-1);
stack.pop(1);
throw new FunctionCallException("lua_pcallk", status, errorMessage);
}
}

public long getIntegerResult() {
final long value = stack.toInteger(-1);
stack.pop(1);
return value;
}
}
5 changes: 5 additions & 0 deletions src/main/java/org/itsallcode/jlua/LuaInterpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public LuaTable getGlobalTable(final String name) {
return lua.table(-1);
}

public LuaFunction getGlobalFunction(final String name) {
lua.getGlobal(name);
return lua.function(-1);
}

public void setGlobalString(final String name, final String value) {
lua.stack().pushString(value);
lua.setGlobal(name);
Expand Down
21 changes: 20 additions & 1 deletion src/test/java/org/itsallcode/jlua/LuaInterpreterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,25 @@ void setGetGlobalBoolean(final boolean value) {
assertThat(globalBoolean, equalTo(value));
}

@Test
void getCallGlobalFunction() {
lua.exec("function increment(x) return x+1 end");
final LuaFunction function = lua.getGlobalFunction("increment");
function.addArgInteger(42);
function.call(1, 1);
assertThat(function.getIntegerResult(), equalTo(43L));
}

@Test
void getCallGlobalFunctionFails() {
lua.exec("function increment(x) error('failure') end");
final LuaFunction function = lua.getGlobalFunction("increment");
function.addArgInteger(42);
final LuaException exception = assertThrows(LuaException.class, () -> function.call(1, 1));
assertThat(exception.getMessage(), equalTo(
"Function 'lua_pcallk' failed with error 2: [string \"function increment(x) error('failure') end\"]:1: failure"));
}

@Test
void getTableStringValue() {
lua.exec("result = { key = 'value' }");
Expand Down Expand Up @@ -139,7 +158,7 @@ void getTableValueWrongType() {
void getTableStringFailsWrongType() {
lua.exec("result = 'not a table'");
final LuaException exception = assertThrows(LuaException.class, () -> lua.getGlobalTable("result"));
assertThat(exception.getMessage(), equalTo("Expected table on the stack but got STRING"));
assertThat(exception.getMessage(), equalTo("Expected TABLE at -1 but got STRING"));
}


Expand Down

0 comments on commit bf580de

Please sign in to comment.