luachunk-0.1.0.0: src/Scripting/Lua/Chunk/Types.hs
-- Lua Chunk AST
-- Lua 5.1 Only
module Scripting.Lua.Chunk.Types
( Chunk(..)
, Header(..)
, Func(..)
, FuncHeader(..)
, Instruction(..)
, FA, FB, FC, FBx, FsBx, FAx
, Constant(..)
, Line
, Local(..)
, Upval
) where
import CustomPrelude
import qualified Data.Text as T
-----------------------------------
-- D A T A S T R U C T U R E S --
-----------------------------------
-- | A Parsed chunk
data Chunk = Chunk
{ chunkHeader :: Header -- ^ Parsed Header
, chunkFunc :: Func -- ^ Parsed Main Function
} deriving Show
-- | A Parsed Header
data Header = Header
{ versionMajor :: Int -- ^ Major version number (5)
, versionMinor :: Int -- ^ Minor version number (1)
, formatVersion :: Int -- ^ 0 = Official Format
, bigEndian :: Bool -- ^ Default : False (little endian)
, sizeOfInt :: Int -- ^ In Bytes (4)
, sizeOfSizeT :: Int -- ^ In Bytes (4)
, sizeOfInstruction :: Int -- ^ In Bytes (4)
, sizeOfNumber :: Int -- ^ In Bytes (8)
, intMath :: Bool -- ^ Number Type is Integral. Default : False (Floating Point Math)
} deriving Show
-- | A Parsed Function
data Func = Func
{ fHeader :: FuncHeader -- ^ Header Data
, fInstrs :: [Instruction] -- ^ List of instructions (code)
, fConsts :: [Constant] -- ^ List of constants
, fNested :: [Func] -- ^ List of function prototypes
, fLines :: [Line] -- ^ Source line positions (optional debug data)
, fLocals :: [Local] -- ^ List of locals (optional debug data)
, fUpvals :: [Upval] -- ^ List of upvalues (optional debug data)
}
deriving Show
-- | A Parsed Function Header
data FuncHeader = FuncHeader
{ sourceName :: Maybe T.Text -- ^ Name of SourceFile
, lineStart :: Int -- ^ Line number where the function starts
, lineEnd :: Int -- ^ Line number where the function ends
, numOfUpvalues :: Int -- ^ Number of upvalues
, numOfParams :: Int -- ^ Number of parameters
, isVararg :: Bool -- ^ Whether this is vararg (Default : False)
, isCompatVararg :: Bool -- ^ Whether LUA_COMPAT_VARARG is defined
, needsArg :: Bool -- ^ Whether it uses old style arguments i.e. arg instead of ... (Default :: False)
, stackSize :: Int -- ^ Maximum number of registers used
} deriving Show
-- | A Parsed VM Instruction
-- ** R(x) - register
-- ** Kst(x) - constant (in constant table)
-- ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
data Instruction
= OP_MOVE FA FB -- ^ R(A) := R(B)
| OP_LOADK FA FBx -- ^ R(A) := Kst(Bx)
| OP_LOADBOOL FA FB FC -- ^ R(A) := (Bool)B; if (C) pc++
| OP_LOADNIL FA FB -- ^ R(A), R(A+1), ..., R(A+B) := nil
| OP_GETUPVAL FA FB -- ^ R(A) := UpValue[B]
| OP_GETGLOBAL FA FBx -- ^ R(A) := Gbl[Kst(Bx)]
| OP_GETTABLE FA FB FC -- ^ R(A) := R(B)[RK(C)]
| OP_SETGLOBAL FA FBx -- Gbl[Kst(Bx)] := R(A)
| OP_SETUPVAL FA FB -- ^ UpValue[B] := R(A)
| OP_SETTABLE FA FB FC -- ^ R(A)[RK(B)] := RK(C)
| OP_NEWTABLE FA FB FC -- ^ R(A) := {} (size = B,C)
| OP_SELF FA FB FC -- ^ R(A+1) := R(B); R(A) := R(B)[RK(C)]
| OP_ADD FA FB FC -- ^ R(A) := RK(B) + RK(C)
| OP_SUB FA FB FC -- ^ R(A) := RK(B) - RK(C)
| OP_MUL FA FB FC -- ^ R(A) := RK(B) * RK(C)
| OP_DIV FA FB FC -- ^ R(A) := RK(B) / RK(C)
| OP_MOD FA FB FC -- ^ R(A) := RK(B) % RK(C)
| OP_POW FA FB FC -- ^ R(A) := RK(B) ^ RK(C)
| OP_UNM FA FB -- ^ R(A) := -R(B)
| OP_NOT FA FB -- ^ R(A) := not R(B)
| OP_LEN FA FB -- ^ R(A) := length of R(B)
| OP_CONCAT FA FB FC -- ^ R(A) := R(B).. ... ..R(C)
| OP_JMP FsBx -- ^ pc+=sBx
| OP_EQ FA FB FC -- ^ if ((RK(B) == RK(C)) ~= A) then pc++
| OP_LT FA FB FC -- ^ if ((RK(B) < RK(C)) ~= A) then pc++
| OP_LE FA FB FC -- ^ if ((RK(B) <= RK(C)) ~= A) then pc++
| OP_TEST FA FC -- ^ if not (R(A) <=> C) then pc++
| OP_TESTSET FA FB FC -- ^ if (R(B) <=> C) then R(A) := R(B) else pc++
| OP_CALL FA FB FC -- ^ R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))
| OP_TAILCALL FA FB FC -- ^ return R(A)(R(A+1), ... ,R(A+B-1))
| OP_RETURN FA FB -- ^ return R(A), ... ,R(A+B-2) (see note)
| OP_FORLOOP FA FsBx -- ^ R(A)+=R(A+2); if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }
| OP_FORPREP FA FsBx -- ^ R(A)-=R(A+2); pc+=sBx
| OP_TFORLOOP FA FC -- ^ R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++
| OP_SETLIST FA FB FC -- ^ R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B
| OP_CLOSE FA -- ^ close all variables in the stack up to (>=) R(A)
| OP_CLOSURE FA FBx -- ^ R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))
| OP_VARARG FA FB -- ^ R(A), R(A+1), ..., R(A+B-2) = vararg
deriving Show
-- | Parsed opcode fields
type FA = Int
-- | Parsed opcode fields
type FB = Int
-- | Parsed opcode fields
type FC = Int
-- | Parsed opcode fields
type FBx = Int
-- | Parsed opcode fields
type FsBx = Int
-- | Parsed opcode fields
type FAx = Int
-- | Parsed Constants
data Constant
= CNil -- ^ Nil Value
| CBool Bool -- ^ Boolean Value
| CNum Double -- ^ Numeric Value
| CStr T.Text -- ^ String Value
deriving Show
-- DEBUG information present in chunks
-- | Line Numbers for each instruction
type Line = Int
-- | Local variables = Local <VarName> <StartPC> <EndPC>
-- where StartPC and EndPC denote the scope in which the local is active
data Local = Local T.Text Int Int deriving Show
-- | Upvalue names used in the function
type Upval = T.Text