text: // Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
  
  %{
  
  #nowarn "1182"  // the generated code often has unused variable "parseState"
  
  open Internal.Utilities
  open Internal.Utilities.Text
  
  open FSharp.Compiler.AbstractIL 
  open FSharp.Compiler.AbstractIL.Internal 
  open FSharp.Compiler.AbstractIL.Internal.AsciiConstants 
  open FSharp.Compiler.AbstractIL.Diagnostics 
  open FSharp.Compiler.AbstractIL.Extensions.ILX.Types 
  open FSharp.Compiler.AbstractIL.IL 
  open FSharp.Compiler.AbstractIL.Internal.Library 
  
    
  let pfailwith s = 
      stderr.WriteLine ("*** error: "+s); 
      raise Parsing.RecoverableParseError 
  
  type ResolvedAtMethodSpecScope<'T> = 
      ResolvedAtMethodSpecScope of (ILGenericParameterDefs -> 'T)
  
  let noMethodSpecScope x = ResolvedAtMethodSpecScope (fun _cgparams -> x)
  let resolveMethodSpecScope (ResolvedAtMethodSpecScope f) x = f x
  let resolveMethodSpecScopeThen (ResolvedAtMethodSpecScope f) g = 
    ResolvedAtMethodSpecScope (fun x -> resolveMethodSpecScope (g(f x)) x)
  
  let resolveCurrentMethodSpecScope obj = 
      resolveMethodSpecScope obj mkILEmptyGenericParams
  
  
  let findSystemRuntimeAssemblyRef() = 
    match parseILGlobals.primaryAssemblyScopeRef with
    | ILScopeRef.Assembly aref -> aref
    | _ -> pfailwith "systemRuntimeScopeRef not set to valid assembly reference in parseILGlobals"
  
  let findAssemblyRef nm = 
    if nm = "mscorlib" then findSystemRuntimeAssemblyRef() 
    else
    pfailwith ("Undefined assembly ref '" + nm + "'") 
  
  %} 
  
  /*-----------------------------------------------------------------------
   * The YACC Grammar
   *----------------------------------------------------------------------*/
  
  %token <int64> VAL_INT64     /* 342534523534534      0x34FA434644554 */
  %token <int32> VAL_INT32_ELIPSES     /* 342534523534534... */
  %token <double> VAL_FLOAT64        /* -334234 24E-34 */
  %token <Int32Instr> INSTR_I 
  %token <Int32Int32Instr> INSTR_I32_I32
  %token <Int64Instr> INSTR_I8 
  %token <DoubleInstr> INSTR_R 
  %token <NoArgInstr> INSTR_NONE 
  %token <StringInstr> INSTR_STRING 
  %token <TokenInstr> INSTR_TOK 
  %token <TypeInstr> INSTR_TYPE 
  %token <IntTypeInstr> INSTR_INT_TYPE 
  %token <ValueTypeInstr> INSTR_VALUETYPE 
  %token <int>     VAL_HEXBYTE    /* 05 1A FA */
  %token <string>  VAL_ID                 /* testing343 */
  %token <string>  VAL_DOTTEDNAME                 /* testing343.abd */
  %token <string>  VAL_QSTRING    /* "Hello World\n" */
  %token <string>  VAL_SQSTRING   /* 'Hello World\n' */
  %token AMP  
  %token BANG  
  %token BOOL  
  %token BYTEARRAY
  %token CHAR  
  %token CLASS 
  %token COMMA  
  %token DCOLON
  %token DEFAULT  
  %token DOT  
  %token ELIPSES
  %token EOF  
  %token EXPLICIT  
  %token FIELD   
  %token FLOAT32  
  %token FLOAT64  
  %token GREATER  
  %token INSTANCE  
  %token INT  
  %token INT16  
  %token INT32  
  %token INT64  
  %token INT8  
  %token LBRACK  
  %token LESS  
  %token LPAREN  
  %token METHOD   
  %token NATIVE  
  %token OBJECT
  %token PLUS
  %token RBRACK
  %token RPAREN   
  %token SLASH
  %token STAR  
  %token STRING  
  %token UINT  
  %token UINT16  
  %token UINT32  
  %token UINT64  
  %token UINT8  
  %token UNMANAGED  
  %token UNSIGNED  
  %token VALUE  
  %token VALUETYPE
  %token VARARG  
  %token VOID  
  
  %type <string> name1 
  %type <ILType ResolvedAtMethodSpecScope> typ
  %type <ILInstr array> ilInstrs
  %type <ILType> ilType
  %start ilInstrs ilType
  
  /**************************************************************************/
  %%      
  
  /* ENTRYPOINT */
  ilType: typ EOF
         { resolveMethodSpecScope $1 [] }
  
  /* ENTRYPOINT */
  ilInstrs: instrs2 EOF
         { Array.ofList $1 }
  
  
  compQstring: 
       VAL_QSTRING { $1 }
     | compQstring PLUS VAL_QSTRING { $1 + $3 }
  
  methodName:  name1 { $1 }
  
  instrs2: 
     | instr instrs2 
          { $1 :: $2  } 
     | { [] }
  
  instr: 
       INSTR_NONE                                         
          {  ($1 ()) }
     | INSTR_I int32                                      
          {  ($1 $2) }
     | INSTR_I32_I32 int32 int32                                  
          {  ($1 ($2,$3)) }
     | INSTR_I8 int64                                     
          {  ($1 $2) }
     | INSTR_R float64                                    
          {  ($1 (ILConst.R8 $2)) }
     | INSTR_R int64
          {  ($1 (ILConst.R8 (float $2))) }
     | INSTR_TYPE typSpec                                 
          { $1 (resolveCurrentMethodSpecScope $2) }
     | INSTR_INT_TYPE int32 typSpec                               
          { $1 ( $2,resolveCurrentMethodSpecScope $3) }
     | INSTR_VALUETYPE typSpec                            
          { $1 (resolveCurrentMethodSpecScope $2) }
     | INSTR_TOK typSpec                          
          {  ($1 (ILToken.ILType (resolveCurrentMethodSpecScope $2)))  }
   
  /*-----------------------------------------------
   * Type names
   *---------------------------------------------*/
  name1: 
     | id
          { $1 }
     | VAL_DOTTEDNAME     
          { $1 }
     | name1 DOT id       
          { $1 + "." + $3 }
  
  className:
       LBRACK name1 RBRACK slashedName
          { let (enc,nm) = $4 
            let aref = findAssemblyRef $2 
            ILScopeRef.Assembly aref, enc, nm }
     | slashedName
          { let enc, nm = $1 in (ILScopeRef.Local, enc, nm) }
  
  slashedName: 
       name1 
          { ([],$1) } 
     | name1 SLASH slashedName
          { let (enc,nm) = $3 in ($1 :: enc, nm)  } 
  
  typeNameInst:
       className opt_actual_tyargs 
          { let (a,b,c) = $1 
            resolveMethodSpecScopeThen $2 (fun inst -> 
            noMethodSpecScope ( (mkILTySpec ( (mkILNestedTyRef (a,b,c)), inst)))) }
  
  
  typeName:
       className 
          { let (a,b,c) = $1 
            noMethodSpecScope ( (mkILTySpec ( (mkILNestedTyRef (a,b,c)), []))) }
  
  
  typSpec: 
       typeName   
          { resolveMethodSpecScopeThen $1 (fun tref -> 
            noMethodSpecScope (mkILBoxedType tref))  }
     | typ                
          { $1 }
     | LPAREN typ RPAREN  
          { $2 }
  
  
  callConv: 
       INSTANCE callKind 
          { Callconv (ILThisConvention.Instance,$2) }
     | EXPLICIT callKind 
          { Callconv (ILThisConvention.InstanceExplicit,$2) }
     | callKind 
          { Callconv (ILThisConvention.Static,$1) }
  
  callKind: 
       /* EMPTY */  
        { ILArgConvention.Default }
     | DEFAULT          
        { ILArgConvention.Default }
     | VARARG
        { ILArgConvention.VarArg }
                  
  /*-----------------------------------------------
   * The full algebra of types, typically producing results 
   * awaiting further info about how to fix up type
   * variable numbers etc.
   *---------------------------------------------*/
  
  typ: STRING
         { noMethodSpecScope parseILGlobals.typ_String } 
     | OBJECT
         { noMethodSpecScope parseILGlobals.typ_Object } 
     | CLASS typeNameInst
         { resolveMethodSpecScopeThen $2 (fun tspec -> 
            noMethodSpecScope (mkILBoxedType tspec)) } 
     | VALUE CLASS typeNameInst
         { resolveMethodSpecScopeThen $3 (fun tspec -> 
           noMethodSpecScope (ILType.Value tspec)) } 
     | VALUETYPE typeNameInst
         { resolveMethodSpecScopeThen $2 (fun tspec -> 
           noMethodSpecScope (ILType.Value tspec)) } 
     | typ LBRACK RBRACK  
         { resolveMethodSpecScopeThen $1 (fun ty -> noMethodSpecScope (mkILArr1DTy ty)) } 
     | typ LBRACK bounds1 RBRACK 
         { resolveMethodSpecScopeThen $1 (fun ty -> noMethodSpecScope (mkILArrTy (ty,ILArrayShape $3))) }
     | typ AMP
         { resolveMethodSpecScopeThen $1 (fun ty -> noMethodSpecScope (ILType.Byref ty)) }
     | typ STAR
         { resolveMethodSpecScopeThen $1 (fun ty -> noMethodSpecScope (ILType.Ptr ty)) }
     | CHAR
         { noMethodSpecScope parseILGlobals.typ_Char }
     | VOID
         { noMethodSpecScope ILType.Void }
     | BOOL
         { noMethodSpecScope parseILGlobals.typ_Bool }
     | INT8
         { noMethodSpecScope parseILGlobals.typ_SByte }
     | INT16              
         { noMethodSpecScope parseILGlobals.typ_Int16 }
     | INT32              
         { noMethodSpecScope parseILGlobals.typ_Int32 }
     | INT64              
         { noMethodSpecScope parseILGlobals.typ_Int64 }
     | FLOAT32            
         { noMethodSpecScope parseILGlobals.typ_Single }
     | FLOAT64            
         { noMethodSpecScope parseILGlobals.typ_Double }
     | UNSIGNED INT8      
         { noMethodSpecScope parseILGlobals.typ_Byte }
     | UNSIGNED INT16     
         { noMethodSpecScope parseILGlobals.typ_UInt16 }
     | UNSIGNED INT32     
         { noMethodSpecScope parseILGlobals.typ_UInt32 }
     | UNSIGNED INT64     
         { noMethodSpecScope parseILGlobals.typ_UInt64 }
     | UINT8      
         { noMethodSpecScope parseILGlobals.typ_Byte }
     | UINT16     
         { noMethodSpecScope parseILGlobals.typ_UInt16 }
     | UINT32     
         { noMethodSpecScope parseILGlobals.typ_UInt32 }
     | UINT64     
         { noMethodSpecScope parseILGlobals.typ_UInt64 }
     | NATIVE INT         
         { noMethodSpecScope parseILGlobals.typ_IntPtr }
     | NATIVE UNSIGNED INT  
         { noMethodSpecScope parseILGlobals.typ_UIntPtr }
     | NATIVE UINT  
         { noMethodSpecScope parseILGlobals.typ_UIntPtr }
  
     | BANG int32
         { noMethodSpecScope (ILType.TypeVar (uint16 ( $2)))  }
  
  
  bounds1:  
       bound 
         { [$1] }
     | bounds1 COMMA bound
         { $1 @ [$3] }
     
  bound: 
       /*EMPTY*/          
         { (None, None) } 
     | int32
         { (None, Some $1) } 
     | int32 ELIPSES int32
         { (Some $1, Some ($3 - $1 + 1)) }       
     | int32 ELIPSES
         { (Some $1, None) } 
  /* We need to be able to parse all of */
  /* ldc.r8     0. */
  /* float64(-657435.)     */
  /* and int32[0...,0...] */
  /* The problem is telling an integer-followed-by-ellipses from a floating-point-nubmer-followed-by-dots */
     | VAL_INT32_ELIPSES int32
         { (Some $1, Some ($2 - $1 + 1)) }       
     | VAL_INT32_ELIPSES
         { (Some $1, None) } 
                                  
  id: 
       VAL_ID
         { $1 }
     | VAL_SQSTRING
         { $1 }
  
  int32: 
       VAL_INT64
         { int32 $1 }
  
  int64: 
       VAL_INT64
         { $1 }
  
  float64: 
       VAL_FLOAT64
         { $1 }
     | FLOAT64 LPAREN int64 RPAREN
         { System.BitConverter.Int64BitsToDouble $3 }
  
  opt_actual_tyargs: 
        /* EMPTY */ 
          { noMethodSpecScope [] }
     | actual_tyargs 
          { resolveMethodSpecScopeThen $1 (fun res -> 
            noMethodSpecScope  res) }
  
  actual_tyargs:
       LESS actualTypSpecs GREATER 
          { $2 } 
  
  actualTypSpecs: 
       typSpec
          { resolveMethodSpecScopeThen $1 (fun res -> 
            noMethodSpecScope [ res]) }
     | actualTypSpecs COMMA typSpec
          { resolveMethodSpecScopeThen $1 (fun x -> 
            resolveMethodSpecScopeThen $3 (fun y -> 
            noMethodSpecScope (x @ [ y]))) }
  
  