language-cil-0.2.0: src/Language/Cil/Syntax.hs
-- |
-- Abstract Syntax Tree for the Common Intermediate Language.
-- Note; currently this is just a subset of CIL.
--
module Language.Cil.Syntax (
keywords
, DottedName
, AssemblyName
, TypeName
, GenParamName
, MethodName
, FieldName
, ParamName
, LocalName
, Version
, PublicKeyToken
, Offset
, Assembly (..)
, AssemblyRef (..)
, TypeDef (..)
, GenParam (..)
, ClassAttr (..)
, ClassDecl (..)
, TypeSpec (..)
, FieldDef (..)
, FieldAttr (..)
, MethodDef (..)
, MethAttr (..)
, Parameter (..)
, ParamAttr (..)
, MethodDecl (..)
, Instr (..)
, Directive (..)
, Local (..)
, Label
, OpCode (..)
, PrimitiveType (..)
, CallConv (..)
) where
keywords :: [String]
keywords = ["add", "mul", "or", "pop", "sub", "value"]
-- | A name in the CIL world.
-- These need to confirm to certain restrictions, altough these aren't
-- currently checked.
type DottedName = String
type AssemblyName = DottedName
type TypeName = DottedName
type GenParamName = DottedName
type MethodName = DottedName
type FieldName = DottedName
type ParamName = DottedName
type LocalName = DottedName
-- | An offset, e.g. for local variables or arguments
type Offset = Int
-- | A Label in CIL.
type Label = String
-- | A Version number in CIL
type Version = (Int, Int, Int, Int)
-- | A public key token
type PublicKeyToken = String
-- | The top level Assembly.
-- This is the root of a CIL program.
data Assembly
= Assembly [AssemblyRef] AssemblyName [TypeDef]
deriving Show
-- | Assembly reference.
data AssemblyRef
= AssemblyRef AssemblyName Version PublicKeyToken
deriving Show
-- | A Type definition in CIL, either a class or a value type.
data TypeDef
= Class [ClassAttr] TypeName (Maybe TypeSpec) [TypeSpec] [ClassDecl]
| GenericClass [ClassAttr] TypeName [GenParam] [ClassDecl]
deriving Show
-- | A parameter to a generic class.
-- Not fully implemented yet, constraints aren't supported.
data GenParam
= GenParam -- constraintFlags :: [ConstraintFlag]
-- constraints :: [DottedName]
{- paramName -} GenParamName
deriving Show
-- | Attribures to class definitions.
data ClassAttr
= CaPrivate
| CaPublic
| CaNestedPublic
| CaNestedPrivate
deriving Show
-- | Class declarations, i.e. the body of a class.
data ClassDecl
= FieldDef FieldDef
| MethodDef MethodDef
| TypeDef TypeDef
deriving Show
-- | Type specification.
data TypeSpec
= TypeSpec TypeName
deriving Show
-- | Field definition.
data FieldDef
= Field [FieldAttr] PrimitiveType FieldName
deriving Show
-- | Attributes to field definitions.
data FieldAttr
= FaStatic
| FaPublic
| FaPrivate
| FaAssembly
deriving Show
-- | Primitive types in CIL.
data PrimitiveType
= Void
| Bool
| Char
| Byte
| Int32
| Int64
| Float32
| Double64
| IntPtr
| String
| Object
| ValueType AssemblyName TypeName
| ReferenceType AssemblyName TypeName
| GenericReferenceType AssemblyName TypeName [GenParamName]
| ByRef PrimitiveType
| GenericType Offset
deriving Show
-- | A Method definition in CIL.
data MethodDef
= Constructor [MethAttr] PrimitiveType [Parameter] [MethodDecl]
| Method [MethAttr] PrimitiveType MethodName [Parameter] [MethodDecl]
deriving Show
-- | Attributes to method definitions.
data MethAttr
= MaStatic
| MaPublic
| MaPrivate
| MaAssembly
| MaVirtual
| MaHidebysig
deriving Show
-- | A formal parameter to a method.
data Parameter
= Param (Maybe ParamAttr) PrimitiveType ParamName
deriving Show
-- | Attributes to parameter definitions.
data ParamAttr
= PaIn
| PaOut
| PaOpt
deriving Show
-- | Method declarations, i.e. the body of a method.
data MethodDecl
= Directive Directive
| Instr Instr
| Comment String
deriving Show
-- | Directive meta data for method definitions.
data Directive
= EntryPoint
| LocalsInit [Local]
| MaxStack Int
deriving Show
-- | Local variables used inside a method definition.
data Local
= Local PrimitiveType LocalName
deriving Show
-- | Single instruction in method definition.
-- Either an OpCode or a labelled OpCode.
data Instr
= LabOpCode Label OpCode
| OpCode OpCode
deriving Show
-- | CIL OpCodes inside a method definition.
-- See <http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes_fields.aspx>
-- for a more complete list with documentation.
data OpCode
= Add -- ^ Pops 2 values, adds the values, pushes result.
| And -- ^ Pops 2 values, do bitwise AND between the values, pushes result.
| Beq Label -- ^ Pops 2 values, if first value is equal to second value, jump to specified label.
| Bge Label -- ^ Pops 2 values, if first value is greater or equal to second value, jump to specified label.
| Bgt Label -- ^ Pops 2 values, if first value is greater than second value, jump to specified label.
| Ble Label -- ^ Pops 2 values, if first value is lesser or equal to second value, jump to specified label.
| Blt Label -- ^ Pops 2 values, if first value is lesser or equal to second value, jump to specified label.
| Box PrimitiveType -- ^ Pops 1 value, boxes value type, pushes object reference.
| Br Label -- ^ Unconditionally jump to specified label.
| Brfalse Label -- ^ Pops 1 value, if value is false, null reference or zero, jump to specified label.
| Brtrue Label -- ^ Pops 1 value, if value is true, not null or non-zero, jump to specified label.
| Call
{ callConv :: [CallConv] -- ^ Method is associated with class or instance.
, returnType :: PrimitiveType -- ^ Return type of the method.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the method resides.
, typeName :: TypeName -- ^ Name of the type of which the method is a member.
, methodName :: MethodName -- ^ Name of the method.
, paramTypes :: [PrimitiveType] -- ^ Types of the formal parameters of the method.
} -- ^ Pops /n/ values, calls specified method, pushes return value. (where /n/ is the number of formal parameters of the method).
| CallVirt
{ returnType :: PrimitiveType -- ^ Return type of the method.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the method resides.
, typeName :: TypeName -- ^ Name of the type of which the method is a member.
, methodName :: MethodName -- ^ Name of the method.
, paramTypes :: [PrimitiveType] -- ^ Types of the formal parameters of the method.
} -- ^ Pops /n/ values, calls specified virtual method, pushes return value. (where /n/ is the number of formal parameters of the method).
| Ceq -- ^ Pops 2 values, if they are equal, pushes 1 to stack; otherwise, pushes 0.
| Cge -- ^ Pops 2 values and compares them.
| Cgt -- ^ Pops 2 values and compares them.
| Cle -- ^ Pops 2 values and compares them.
| Clt -- ^ Pops 2 values and compares them.
| Dup -- ^ Pops 1 value, copies it, pushes the same value twise.
| Isinst TypeName -- ^ Tests if an object reference is an instance of class, returning either a null reference or an instance of that class or interface.
| Ldarg Offset -- ^ Loads /n/-th argument to current method onto stack.
| Ldarg_0 -- ^ Loads 0th argument to current method onto stack.
| Ldarg_1 -- ^ Loads 1th argument to current method onto stack.
| Ldarg_2 -- ^ Loads 2th argument to current method onto stack.
| Ldarg_3 -- ^ Loads 3th argument to current method onto stack.
| LdargN DottedName -- ^ Loads named argument to current method onto stack.
| Ldc_i4 Integer -- ^ Loads the supplied 32-bit integer onto the stack.
| Ldc_i4_0 -- ^ Loads the value 0 onto the stack.
| Ldc_i4_1 -- ^ Loads the value 1 onto the stack.
| Ldc_i4_2 -- ^ Loads the value 2 onto the stack.
| Ldc_i4_3 -- ^ Loads the value 3 onto the stack.
| Ldc_i4_4 -- ^ Loads the value 4 onto the stack.
| Ldc_i4_5 -- ^ Loads the value 5 onto the stack.
| Ldc_i4_6 -- ^ Loads the value 6 onto the stack.
| Ldc_i4_7 -- ^ Loads the value 7 onto the stack.
| Ldc_i4_8 -- ^ Loads the value 8 onto the stack.
| Ldc_i4_m1 -- ^ Loads the value -1 onto the stack.
| Ldc_i4_s Int -- ^ Loads the supplied 8-bit integer onto the stack as 32-bit integer (short form).
| Ldc_i8 Integer -- ^ Loads the supplied 64-bit integer onto the stack.
| Ldc_r4 Float -- ^ Loads the supplied 32-bit float onto the stack.
| Ldc_r8 Double -- ^ Loads the supplied 64-bit double onto the stack.
| Ldfld
{ fieldType :: PrimitiveType -- ^ Type of the field.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the field resides.
, typeName :: TypeName -- ^ Name of the type of which the field is a member.
, fieldName :: FieldName -- ^ Name of the field.
} -- ^ Pops object reference, find value of specified field on object, pushes value to the stack.
| Ldflda
{ fieldType :: PrimitiveType -- ^ Type of the field.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the field resides.
, typeName :: TypeName -- ^ Name of the type of which the field is a member.
, fieldName :: FieldName -- ^ Name of the field.
} -- ^ Pops object reference, find address of specified field on the object, pushes address to the stack.
| Ldftn
{ returnType :: PrimitiveType -- ^ Return type of the method.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the method resides.
, typeName :: TypeName -- ^ Name of the type of which the method is a member.
, methodName :: MethodName -- ^ Name of the method.
, paramTypes :: [PrimitiveType] -- ^ Types of the formal parameters of the method.
} -- ^ Pops object reference, finds address of specified method, pushes address as native int to the stack.
| Ldind_i -- ^ Pops an address, pushes the native integer stored at the address.
| Ldind_i1 -- ^ Pops an address, pushes the 8-bit integer stored at the address as a 32-bit integer.
| Ldind_i2 -- ^ Pops an address, pushes the 16-bit integer stored at the address as a 32-bit integer.
| Ldind_i4 -- ^ Pops an address, pushes the 32-bit integer stored at the address.
| Ldind_i8 -- ^ Pops an address, pushes the 64-bit integer stored at the address as a 64-bit integer.
| Ldind_r4 -- ^ Pops an address, pushes the 32-bit float stored at the address.
| Ldind_r8 -- ^ Pops an address, pushes the 64-bit double stored at the address.
| Ldind_ref -- ^ Pops an address, pushes the object reference specified at the address.
| Ldind_u1 -- ^ Pops an address, pushes the 8-bit unsigned integer stored at the address as a 32-bit integer.
| Ldind_u2 -- ^ Pops an address, pushes the 16-bit unsigned integer stored at the address as a 32-bit integer.
| Ldind_u4 -- ^ Pops an address, pushes the 32-bit unsigned integer stored at the address as a 32-bit integer.
| Ldloc Offset -- ^ Pushes value of local variable, specified by index, to the stack.
| Ldloc_0 -- ^ Pushes 0th local variable to the stack.
| Ldloc_1 -- ^ Pushes 1th local variable to the stack.
| Ldloc_2 -- ^ Pushes 2th local variable to the stack.
| Ldloc_3 -- ^ Pushes 3th local variable to the stack.
| LdlocN DottedName -- ^ Pushes value of local variable, specified by name, to the stack.
| Ldloca Offset -- ^ Pushes address of local variable, specified by index, to the stack.
| LdlocaN DottedName -- ^ Pushes address of local variable, specified by name, to the stack.
| Ldsfld
{ fieldType :: PrimitiveType -- ^ Type of the field.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the field resides.
, typeName :: TypeName -- ^ Name of the type of which the field is a member.
, fieldName :: FieldName -- ^ Name of the field.
} -- ^ Pops type reference, find value of specified field on the type, pushes value to the stack.
| Ldsflda
{ fieldType :: PrimitiveType -- ^ Type of the field.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the field resides.
, typeName :: TypeName -- ^ Name of the type of which the field is a member.
, fieldName :: FieldName -- ^ Name of the field.
} -- ^ Pops type reference, find address of specified field on the type, pushes address to the stack.
| Ldstr String -- ^ Pushes an object reference to the specified string constant.
| Mul -- ^ Pops 2 values, multiplies the values, pushes result.
| Neg -- ^ Pops 1 value, negates the value, pushes the value.
| Newobj
{ returnType :: PrimitiveType -- ^ Return type of the constructor (almost alway Void).
, assemblyName :: AssemblyName -- ^ Name of the assembly where the constructor resides.
, typeName :: TypeName -- ^ Name of the type of which the constructor is a member.
, paramTypes :: [PrimitiveType] -- ^ Types of the formal paramters of the constructor.
} -- ^ Creates a new object or instance of a value type. Pops /n/ values, calls the specified constructor, pushes a new object reference onto the stack (where /n/ is the number of formal parameters of the constructor).
| Nop -- ^ No operation is performed.
| Pop -- ^ Pops the top of the stack.
| Rem -- ^ Pops 2 values, devides the first value by the second value, pushes the remainder.
| Ret -- ^ Returns from the current method. Pushes top of the stack to the top of the callers stack (if stack is not empty).
| Stfld
{ fieldType :: PrimitiveType -- ^ Type of the field.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the field resides.
, typeName :: TypeName -- ^ Name of the type of which the field is a member.
, fieldName :: FieldName -- ^ Name of the field.
} -- ^ Replaces the value stored in the field of an object reference or pointer with a new value.
| Stind_i -- ^ Pops an address and a native integer, stores the integer at the address.
| Stind_i1 -- ^ Pops an address and a 8-bit integer, stores the integer at the address.
| Stind_i2 -- ^ Pops an address and a 16-bit integer, stores the integer at the address.
| Stind_i4 -- ^ Pops an address and a 32-bit integer, stores the integer at the address.
| Stind_i8 -- ^ Pops an address and a 64-bit integer, stores the integer at the address.
| Stind_r4 -- ^ Pops an address and a 32-bit float, stores the float at the address.
| Stind_r8 -- ^ Pops an address and a 64-bit double, stores the double at the address.
| Stind_ref -- ^ Pops an address and an object reference, stores the object reference at the address.
| Stloc Offset -- ^ Pops 1 value, stores it in the local variable specified by index.
| Stloc_0 -- ^ Pops 1 value, stores it in the 0th local variable.
| Stloc_1 -- ^ Pops 1 value, stores it in the 1th local variable.
| Stloc_2 -- ^ Pops 1 value, stores it in the 2th local variable.
| Stloc_3 -- ^ Pops 1 value, stores it in the 3th local variable.
| StlocN DottedName -- ^ Pops 1 value, stores it in the local variable specified by name.
| Stsfld
{ fieldType :: PrimitiveType -- ^ Type of the field.
, assemblyName :: AssemblyName -- ^ Name of the assembly where the field resides.
, typeName :: TypeName -- ^ Name of the type of which the field is a member.
, fieldName :: FieldName -- ^ Name of the field.
} -- ^ Replaces the value stored in the static field of a type with a new value.
| Sub -- ^ Pops 2 values, substracts second value from the first value, pushes result.
| Tail -- ^ Performs subsequent call as a tail call, by replacing current stack frame with callee stack frame.
| Tailcall OpCode -- ^ Performs provided call as a tail call, by replacing current stack frame with callee stack frame.
| Unbox PrimitiveType -- ^ Pops 1 value, unboxes object reference, pushes value type.
deriving Show
-- | Calling convention for method calls.
data CallConv
= CcInstance
deriving Show