通常,Lua带有两个二进制文件:
lua -独立的解释器和交互式外壳
luac -字节码编译器
假设我们有一个示例程序(bottles_of_mate.lua),如下所示:
local string = require "string" function bottle_take(bottles_available) local count_str = "%d bottles of mate on the wall." local take_str = "Take one down, pass it around, " .. count_str local end_str = "Oh noes, " .. count_str local buy_str = "Get some from the store, " .. count_str local bottles_left = 0 if bottles_available > 0 then print(string.format(count_str, bottles_available)) bottles_left = bottles_available - 1 print(string.format(take_str, bottles_left)) else print(string.format(end_str, bottles_available)) bottles_left = 99 print(string.format(buy_str, bottles_left)) end return bottles_left end local bottle_count = 99 while true do bottle_count = bottle_take(bottle_count) end
可以通过在Shell上执行以下命令来运行程序本身:
$ lua bottles_of_mate.lua
输出应如下所示,在无限循环中运行:
Get some from the store, 99 bottles of mate on the wall. 99 bottles of mate on the wall. Take one down, pass it around, 98 bottles of mate on the wall. 98 bottles of mate on the wall. Take one down, pass it around, 97 bottles of mate on the wall. 97 bottles of mate on the wall. ... ... 3 bottles of mate on the wall. Take one down, pass it around, 2 bottles of mate on the wall. 2 bottles of mate on the wall. Take one down, pass it around, 1 bottles of mate on the wall. 1 bottles of mate on the wall. Take one down, pass it around, 0 bottles of mate on the wall. Oh noes, 0 bottles of mate on the wall. Get some from the store, 99 bottles of mate on the wall. 99 bottles of mate on the wall. Take one down, pass it around, 98 bottles of mate on the wall. ...
您可以通过在Shell上执行以下命令,将程序编译为Lua的字节码:
$ luac bottles_of_mate.lua -o bottles_of_mate.luac
还可以通过执行以下命令来列出字节码:
$ luac -l bottles_of_mate.lua main <./bottles.lua:0,0> (13 instructions, 52 bytes at 0x101d530) 0+ params, 4 slots, 0 upvalues, 2 locals, 4 constants, 1 function 1 [1] GETGLOBAL 0 -1 ; require 2 [1] LOADK 1 -2 ; "string" 3 [1] CALL 0 2 2 4 [22] CLOSURE 1 0 ; 0x101d710 5 [22] MOVE 0 0 6 [3] SETGLOBAL 1 -3 ; bottle_take 7 [24] LOADK 1 -4 ; 99 8 [27] GETGLOBAL 2 -3 ; bottle_take 9 [27] MOVE 3 1 10 [27] CALL 2 2 2 11 [27] MOVE 1 2 12 [27] JMP -5 ; to 8 13 [28] RETURN 0 1 function <./bottles.lua:3,22> (46 instructions, 184 bytes at 0x101d710) 1 param, 10 slots, 1 upvalue, 6 locals, 9 constants, 0 functions 1 [5] LOADK 1 -1 ; "%d bottles of mate on the wall." 2 [6] LOADK 2 -2 ; "Take one down, pass it around, " 3 [6] MOVE 3 1 4 [6] CONCAT 2 2 3 5 [7] LOADK 3 -3 ; "Oh noes, " 6 [7] MOVE 4 1 7 [7] CONCAT 3 3 4 8 [8] LOADK 4 -4 ; "Get some from the store, " 9 [8] MOVE 5 1 10 [8] CONCAT 4 4 5 11 [9] LOADK 5 -5 ; 0 12 [11] EQ 1 0 -5 ; - 0 13 [11] JMP 16 ; to 30 14 [12] GETGLOBAL 6 -6 ; print 15 [12] GETUPVAL 7 0 ; string 16 [12] GETTABLE 7 7 -7 ; "format" 17 [12] MOVE 8 1 18 [12] MOVE 9 0 19 [12] CALL 7 3 0 20 [12] CALL 6 0 1 21 [13] SUB 5 0 -8 ; - 1 22 [14] GETGLOBAL 6 -6 ; print 23 [14] GETUPVAL 7 0 ; string 24 [14] GETTABLE 7 7 -7 ; "format" 25 [14] MOVE 8 2 26 [14] MOVE 9 5 27 [14] CALL 7 3 0 28 [14] CALL 6 0 1 29 [14] JMP 15 ; to 45 30 [16] GETGLOBAL 6 -6 ; print 31 [16] GETUPVAL 7 0 ; string 32 [16] GETTABLE 7 7 -7 ; "format" 33 [16] MOVE 8 3 34 [16] MOVE 9 0 35 [16] CALL 7 3 0 36 [16] CALL 6 0 1 37 [17] LOADK 5 -9 ; 99 38 [18] GETGLOBAL 6 -6 ; print 39 [18] GETUPVAL 7 0 ; string 40 [18] GETTABLE 7 7 -7 ; "format" 41 [18] MOVE 8 4 42 [18] MOVE 9 5 43 [18] CALL 7 3 0 44 [18] CALL 6 0 1 45 [21] RETURN 5 2 46 [22] RETURN 0 1