Search code examples
lualuac

Lua - why is string after function call allowed?


I'm trying to implement a simple C++ function, which checks a syntax of Lua script. For that I'm using Lua's compiler function luaL_loadbufferx() and checking its return value afterwards.

Recently, I have ran into a problem, because the code, that I thought should be marked invalid, was not detected and instead the script failed later at a runtime (eg. in lua_pcall()).

Example Lua code (can be tested on official Lua demo):

function myfunc()
   return "everyone"
end

-- Examples of unexpected behaviour:
-- The following lines pass the compile time check without errors.
print("Hello " .. myfunc() "!") -- Runtime error: attempt to call a string value
print("Hello " .. myfunc() {1,2,3}) -- Runtime error: attempt to call a string value

-- Other examples:
-- The following lines contain examples of invalid syntax, which IS detected by compiler.
print("Hello " myfunc() .. "!") -- Compile error: ')' expected near 'myfunc'
print("Hello " .. myfunc() 5) -- Compile error: ')' expected near '5'
print("Hello " .. myfunc() .. ) -- Compile error: unexpected symbol near ')'

The goal is obviously to catch all syntax errors at compile time. So my questions are:

  1. What exactly is meant by calling a string value?
  2. Why is this syntax allowed in the first place? Is it some Lua feature I'm unaware of, or the luaL_loadbufferx() is faulty in this particular example?
  3. Is it possible to detect such errors by any other method without running it? Unfortunately, my function doesn't have access to global variables at compile time, so I can't just just run the code directly via lua_pcall().

Note: I'm using Lua version 5.3.4 (manual here).

Thank you very much for your help.


Solution

  • Both myfunc() "!" and myfunc(){1,2,3} are valid Lua expressions.

    Lua allows calls of the form exp string. See functioncall and prefixexp in the Syntax of Lua.

    So myfunc() "!" is a valid function call that calls whatever myfunc returns and call it with the string "!".

    The same thing happens for a call of the form exp table-literal.