OpenCOBOL Lua Interface

Author:

Brian Tiffin

Date:

28-Oct-2008

Purpose:

interface to Lua scripting

Rights:
Copyright 2008 Brian Tiffin
Licensed under the GNU General Public License
No warranty expressed or implied
Tectonics:
cobc -c -I/usr/include/lua5.1/ oclua.c
cobc -x -llua5.1 luacaller.cob oclua.o
./ocdoc luacaller.cob oclua.rst oclua.html ocfaq.css
Requires:

lua5.1, liblua5.1, liblua5.1-dev

Link:

http://www.lua.org

Thanks to:

The Lua team, Pontifical Catholic University of Rio de Janeiro in Brazil. http://www.lua.org/authors.html

Sources:

Overview

The OpenCOBOL Lua interface is defined at a very high level.

The objective is to provide easy access to Lua through script files or strings to be evaluated.

Command strings and script file names passed to Lua MUST be terminated with a null byte, as per C Language conventions.

A Lua engine is started with a call to OCLUA_OPEN, which returns an OpenCOBOL POINTER that is used to reference the Lua state for all further calls.

A Lua engine is run down with a call to OCLUA_CLOSE.

Attention!

Calls to Lua without a valid state will cause undefined behaviour and crash the application.

Lua uses a stack and results of the Lua RETURN reserved word are placed on this stack. Multiple values can be returned from Lua.

The developer is responsible for stack overflow conditions and the size of the stack (default 20 elements) is controlled with OCLUA_STACK using an integer that determines the numbers of slots to reserve.

Requires package installs of:

OpenCOBOL Lua API

OCLUA_OPEN

Initialize the Lua engine.

01 luastate USAGE POINTER.

CALL "OCLUA_OPEN" RETURNING luastate END-CALL

OCLUA_STACK

Check and possibly resize the Lua data stack. Returns 0 if Lua cannot expand the stack to the requested size.

01 elements USAGE BINARY-LONG VALUE 32.
01 result   USAGE BINARY-LONG.

CALL "OCLUA_STACK"
    USING
        BY VALUE luastate
        BY VALUE elements
    RETURNING result
END-CALL

OCLUA_DOSTRING

Evaluate a null terminated alphanumeric field as a Lua program producing any top of stack entry and returning the depth of stack after evaluation.

Takes a luastate, a null terminated command string, a result field and length and returns an integer depth.

Attention!

The Lua stack is NOT popped while returning the top of stack entry.

01 luacommand pic x(64).
01 luaresult  pic x(32).
01 depth      usage binary-long.

move 'return "OpenCOBOL " .. 1.0 + 0.1' & x"00" to luacommand
call "OCLUA_DOSTRING"
    using
        by value luastate
        by reference luacommand
        by reference luaresult
        by value function length(luaresult)
    returning depth
end-call
display
    "OpenCOBOL displays: " depth " |" luaresult "|"
end-display

Outputs:

OpenCOBOL displays: +0000000001 |OpenCOBOL 1.1                   |

OCLUA_DOFILE

Evaluate a script using a null terminated alphanumeric field naming a Lua program source file, retrieving any top of stack entry and returning the depth of stack after evaluation.

Takes a luastate, a null terminated filename, a result field and length and returns an integer depth.

Attention!

The Lua stack is NOT popped while returning the top of stack entry.

01 luascript  pic x(10) value 'oclua.lua' & x"00".
01 luaresult  pic x(32).

call "OCLUA_DOFILE"
    using
        by value luastate
        by reference luascript
        by reference luaresult
        by value function length(luaresult)
    returning depth
end-call
display
    "OpenCOBOL displays: " depth " |" luaresult "|"
end-display

Given oclua.lua:

-- Start
-- Script: oclua.lua
print("Lua prints hello")

hello = "Hello OpenCOBOL from Lua"
return math.pi, hello
-- End

Outputs:

Lua prints hello
OpenCOBOL displays: +0000000002 |Hello OpenCOBOL from Lua        |

and on return from Lua, there is math.pi and the Hello string remaining on the Lua state stack.

OCLUA_DEPTH

Returns the current number of elements on the Lua stack.

call "OCLUA_DEPTH"
    using
        by value luastate
    returning depth
end-call
display "Lua depth: " depth end-display

OCLUA_GET

Retrieves values from the Lua stack, returning the length of the retrieved item.

An example that populates and displays an OpenCOBOL table:

01 items                pic 9 usage computational-5.
01 luastack.
   03 luaitem           pic x(32) occurs 5 times.

perform varying items from 1 by 1
    until items > depth
        call "OCLUA_GET"
            using
                by value luastate
                by value items
                by reference luaresult
                by value function length(luaresult)
            returning lualength
        end-call
        move luaresult to luaitem(items)
end-perform

perform varying items from 1 by 1
    until items > depth
        display
           "Item " items ": " luaitem(items)
        end-display
end-perform

Lua numbers the indexes of stacked items from 1, first item to n, last item (current top of stack). Negative indexes may also be used as documented by Lua, -1 being top of stack.

Sample output:

Item 1: OpenCOBOL 1.1
Item 2: 3.1415926535898
Item 3: Hello OpenCOBOL from Lua
Item 4: 3.1415926535898
Item 5: Hello OpenCOBOL from Lua

OCLUA_POP

Pops the given number of elements off of the Lua stack returning the depth of the stack after the pop.

Example that empties the Lua stack:

call "OCLUA_POP"
    using
        by value luastate
        by value depth
    returning depth
end-call

OCLUA_CLOSE

Close and free the Lua engine.

!DANGER!

Further calls to Lua are unpredictable and may well lead to a SIGSEGV crash.

call "OCLUA_CLOSE" using by value luastate end-call