Skip to content

Parser notes

Dibyendu Majumdar edited this page Jun 23, 2021 · 9 revisions

Lua Parser Notes

Handling multiple return values from function calls

Lua functions return multiple values. The caller has to decide how many values to accept.

  1. If the function call is the last expression in a function argument list, or in a return statement, or in a table constructor then we have to allow unlimited values.

  2. If the function call is in an assignment statement (including local declaration) and is the last expression, then the number of return values to accept is equal to corresponding variable plus any excess variables.

  3. A function call in the expression list of generic call is adjusted so that ultimately 3 values are generated by the expression list. This is the same as assignment statement with 3 variables being assigned to.

  4. The iterator function call in a generic for loop is adjusted so that 2 results are expected. This is required by iterator semantics.

  5. In all other cases the function return values are truncated to 1 result.

  6. If a function call is surrounded by parenthesis then it truncates result to 1 value.

handling _ENV

Normally up-values reference local variables in an enclosing function. However _ENV is a special case as it doesn't exist as a local variable in any scope and yet we need to create an up-value for it when globals are accessed. We also need to allow for the user defining a local _ENV in some scope, which would then override the default _ENV.

The special case handling of _ENV was addressed in issue #35.

String concatenation

Lua's string concatenation has an optimization, when facing an expression such as a .. b .. c - all three items are pushed onto the stack registers and a single concatenation takes place. The Lua string concat opcode expects the values to be concatenated to be presented in this way.

generic for statements

The generic for statement in Lua has an oddity in that the expression in the for statement is expected to return three values:

  • An iterator function
  • A state
  • A variable value

The variable value is also expected to be produced by the iterator function and assigned to the first variable in the for statement at every iteration.

From Lua 5.3 manual:

The generic for statement works over functions, called iterators. On each iteration, the iterator function is called to produce a new value, stopping when this new value is nil. The generic for loop has the following syntax:

	stat ::= for namelist in explist do block end
	namelist ::= Name {‘,’ Name}

A for statement like

     for var_1, ···, var_n in explist do block end

is equivalent to the code:

     do
       local f, s, var = explist
       while true do
         local var_1, ···, var_n = f(s, var)
         if var_1 == nil then break end
         var = var_1
         block
       end
     end

Note the following:

  • explist is evaluated only once. Its results are an iterator function, a state, and an initial value for the first iterator variable.
  • f, s, and var are invisible variables. The names are here for explanatory purposes only.
  • You can use break to exit a for loop.
  • The loop variables var_i are local to the loop; you cannot use their values after the for ends. If you need these values, then assign them to other variables before breaking or exiting the loop.

The expression list in the for statement must be treated as an assignment statement with 3 variables.

The call to iterator function must be treated as assignment statement with 2 variables.