Search code examples
lualuasocket

Read lua interface


In lua, is there any way to read an interface file to extract name/methods/args?

I have an .idl file like this:

interface
{
    name = myInterface,
    methods = {
        testing = {
            resulttype = "double",
            args = {{direction = "in",
            type = "double"},
        }
    }
}

This is equal to the code bellow (easier to read):

interface myInterface {
  double testing (in double a);
};

I can read file, load as string and parse with gmatch for example to extract information, but is there any easy mode to parse this info?

At the end i want something (a table for example) with the interface name, their methods, result types and args. Just to know the interface that i`m working.


Solution

  • Lua has several facilities to interpret chunks of code. Namely, dofile, loadfile and loadstring. Luckily, your input file is almost valid Lua code (assuming those braces were matched). The only thing that is problematic is interface {.

    All of the above functions effectively create a function object with a file's or a string's contents as their code. dofile immediately executes that function, while the others return a function, which you can invoke whenever you like. Therefore, if you're free to change the files, replace interface in the first line with return. Then you can do:

    local interface = dofile("input.idl")
    

    And interface will be a nice table, just as you have specified it in the file. If you cannot change those files to your liking, you will have to load the file into the string, perform some string manipulation (specifically, replace the first interface with return) and then use loadstring instead:

    io.input("input.idl")
    local input = io.read("*all")
    input = string.gsub(input, "^interface", "return") -- ^ marks beginning of string
    local f = loadstring(input)
    local interface = f()
    

    In both cases this is what you will get:

    > require"pl.pretty".dump(interface)
    {
      name = "myInterface",
      methods = {
        testing = {
          args = {
            {
              type = "double",
              direction = "in"
            }
          },
          resulttype = "double"
        }
      }
    }    
    
    > print(interface.methods.testing.args[1].type)
    double
    

    EDIT:

    I just realised, in your example input myInterface is not enclosed in " and therefore not a proper string. Is that also a mistake in your input file or is that what your files actually look like? In the latter case, you would need to change that as well. Lua is not going to complain if it's a name it doesn't know, but you also won't get the field in that case.