Search code examples
lua

Lua interpreter works inconsistently with break statement


Hi i am trying to learn Lua, I was playing around with the language and I come accrosed this code block

for i = 1, 4, 1
do
    if(i == 2) then
        break
        undefinedFunction("print 1")
    end

    
    print("print 2")
end

which is fine for the interpreter and did nothing for the undefined function. On the other hand if we make this code block like that

for i = 1, 4, 1
do
    if(i == 2) then
        break
        1
    end

    
    print("Hello World asdasdsad asdasdas")
end

which the lua interpreter throws error unexpected sign '1'.

So i thought that Lua interpreter fines with undefined functions and just ignore them but if i code like that

for i = 1, 4, 1
do
    if(i == 2) then
        break
        
    end

    undefinedFunction("argument 1")
    
    print("print 1")
end

now Lua interpreter gives error. Why there is an inconsistency?


Solution

  • The difference here is "syntax error" vs "runtime error".

    The second snippet has a syntax error: A single literal (such as a number 1 or a string "foo") is not a valid statement. A file needs to be free of syntax errors before Lua can even begin to run it, which is why the second snippet will fail regardless of where you put the line with the 1.

    The third snippet has a runtime error: The file syntax is perfectly fine and Lua can start interpreting it. Only when it reaches the offending line will the VM realize that undefinedFunction == nil and that it can't use that as a function.

    Contrast to the first snippet, where:

    • there is no syntax error
    • the line with a runtime error is "hidden" behind a break and will never be reached, thereby never triggering the error

    And the break is nothing special here, a simple if can show the same behaviour:

    Syntax error:

    if true then
      1
    end
    

    Runtime error:

    if true then
      undefined()
    end
    

    No error:

    if false then
      undefined() -- This line is never reached, and will not cause an error
    end