Math.NET Numerics
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

240 lines
8.1 KiB

{
// (c) Microsoft Corporation 2005-2009.
module Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiLexer
open Internal.Utilities
open Internal.Utilities.Text
open Internal.Utilities.Text.Lexing
open Microsoft.FSharp.Compiler.AbstractIL
open Microsoft.FSharp.Compiler.AbstractIL.Internal
module Ildiag = Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
module Ilpars = Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiParser
module Ilascii = Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiConstants
open Ildiag
open Ilpars
open Ilascii
let lexeme (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
let unexpected_char lexbuf =
dprintf "Unexpected character '%s'" (lexeme lexbuf);
raise Parsing.RecoverableParseError ;;
let unquote n m s =
String.sub s n (String.length s-(n+m));;
(* --------------------------------------------------------------------
* STRING LITERALS
* -------------------------------------------------------------------- *)
let string_buffer = Buffer.create 256
let reset_string_buffer () = Buffer.clear string_buffer
let store_string_char c = Buffer.add_char string_buffer c
let get_stored_string () =Buffer.contents string_buffer
let escape = function
| 'n' -> '\010'
| 'r' -> '\013'
| 'b' -> '\008'
| 't' -> '\009'
| c -> c
(* --------------------------------------------------------------------
* Keywords
* -------------------------------------------------------------------- *)
let keywords = lazy
[
"void",VOID
; "bool",BOOL
; "bytearray",BYTEARRAY
; "cdecl",CDECL
; "char",CHAR
; "class",CLASS
; "default",DEFAULT
; "explicit",EXPLICIT
; "fastcall",FASTCALL
; "float32",FLOAT32
; "float64",FLOAT64
; "instance",INSTANCE
; "int",INT
; "int16",INT16
; "int32",INT32
; "int64",INT64
; "int8",INT8
; "method",METHOD
; "native",NATIVE
; "object", OBJECT
; "stdcall",STDCALL
; "string",STRING
; "thiscall",THISCALL
; "typedref",TYPEDREF
; "uint",UINT
; "uint16",UINT16
; "uint32",UINT32
; "uint64",UINT64
; "uint8",UINT8
; "unmanaged",UNMANAGED
; "unsigned",UNSIGNED
; "value",VALUE
; "valuetype",VALUETYPE
; "vararg",VARARG
]
(* --------------------------------------------------------------------
* Instructions
* -------------------------------------------------------------------- *)
let addTable t f l = List.iter (fun (x,i) -> Hashtbl.add t (String.concat "." x) (f i)) (Lazy.force l)
let kwd_instr_table =
lazy begin
let t = Hashtbl.create 1000 in
List.iter (fun (x,y) -> Hashtbl.add t x y) (Lazy.force keywords);
addTable t (fun i -> INSTR_NONE i) none_instrs;
addTable t (fun i -> INSTR_ARG i) arg_instrs;
addTable t (fun i -> INSTR_LOC i) loc_instrs;
addTable t (fun i -> INSTR_I i) i32_instrs;
addTable t (fun i -> INSTR_I32_I32 i) i32_i32_instrs;
addTable t (fun i -> INSTR_I8 i) i64_instrs;
addTable t (fun i -> INSTR_R i) real_instrs;
addTable t (fun i -> INSTR_METHOD i) method_instrs;
//addTable t (fun i -> INSTR_FIELD i) field_instrs;
addTable t (fun i -> INSTR_TYPE i) type_instrs;
addTable t (fun i -> INSTR_INT_TYPE i) int_type_instrs;
addTable t (fun i -> INSTR_VALUETYPE i) valuetype_instrs;
addTable t (fun i -> INSTR_STRING i) string_instrs;
//addTable t (fun i -> INSTR_SIG i) sig_instrs;
addTable t (fun i -> INSTR_TOK i) tok_instrs;
//addTable t (fun i -> INSTR_SWITCH i) switch_instrs;
t
end
let kwd_or_instr s = Hashtbl.find (Lazy.force kwd_instr_table) s (* words *)
let eval = function
| '0' -> 0 | '1' -> 1 | '2' -> 2 | '3' -> 3 | '4' -> 4 | '5' -> 5
| '6' -> 6 | '7' -> 7 | '8' -> 8 | '9' -> 9
| 'A' -> 10 | 'B' -> 11 | 'C' -> 12 | 'D' -> 13 | 'E' -> 14 | 'F' -> 15
| 'a' -> 10 | 'b' -> 11 | 'c' -> 12 | 'd' -> 13 | 'e' -> 14 | 'f' -> 15
| _ -> failwith "bad hexbyte"
let kwd_or_instr_or_id s = if Hashtbl.mem (Lazy.force kwd_instr_table) s then kwd_or_instr s else VAL_ID s
}
(* --------------------------------------------------------------------
* The Rules
* -------------------------------------------------------------------- *)
rule token = parse
| "," { COMMA }
| "." { DOT }
| "*" { STAR }
| "!" { BANG }
| "&" { AMP }
| "(" { LPAREN }
| ")" { RPAREN }
| "[" { LBRACK }
| "]" { RBRACK }
| "/" { SLASH }
| "<" { LESS }
| ">" { GREATER }
| "..." { ELIPSES }
| "::" { DCOLON }
| "+" { PLUS }
| (['0'-'9']) | (['0'-'9']['0'-'9']['0'-'9']+)
{ VAL_INT64(int64(lexeme lexbuf)) }
(* 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 *)
| ((['0'-'9']) | (['0'-'9']['0'-'9']['0'-'9']+)) "..."
{ let b = lexeme lexbuf in
VAL_INT32_ELIPSES(int32(String.sub b 0 (String.length b - 3))) }
| ['0'-'9' 'A'-'F' 'a'-'f' ] ['0'-'9' 'A'-'F' 'a'-'f' ]
{ let c1 = String.get (lexeme lexbuf) 0 in
let c2 = String.get (lexeme lexbuf) 1 in
if !lexing_bytearray then
VAL_HEXBYTE (16 * eval c1 + eval c2)
else if c1 >= '0' & c1 <= '9' & c2 >= '0' & c2 <= '9' then
VAL_INT64(int64 (10*eval c1 + eval c2) )
else VAL_ID(lexeme lexbuf) }
| '0' 'x' ['0'-'9' 'a'-'f' 'A'-'F']+
{ VAL_INT64(int64(lexeme lexbuf)) }
| "FFFFFF" ['0'-'9' 'A'-'F' 'a'-'f' ] ['0'-'9' 'A'-'F' 'a'-'f' ]
{ let c1 = (lexeme lexbuf).[6] in
let c2 = (lexeme lexbuf).[7] in
if !lexing_bytearray then
VAL_HEXBYTE (16 * eval c1 + eval c2)
else if c1 >= '0' & c1 <= '9' & c2 >= '0' & c2 <= '9' then
VAL_INT64(int64 (10*eval c1 + eval c2))
else VAL_ID(lexeme lexbuf) }
| '-' ['0'-'9']+
{ VAL_INT64(int64(lexeme lexbuf)) }
| ('+'|'-')? ['0'-'9']+ ('.' ['0' - '9']*)? (('E'|'e') ('-'|'+')? ['0' - '9']+)?
{ VAL_FLOAT64( (float (lexeme lexbuf)) ) }
| '\''
{ reset_string_buffer();
singleQuoteString lexbuf;
VAL_SQSTRING (get_stored_string()) }
| "\""
{ reset_string_buffer();
stringToken lexbuf;
VAL_QSTRING (get_stored_string()) }
| ("ldarg"|"ldc"|"ldloc"|"stloc"|"bne"|"conv"|"ble"|"bgt"|"bge"|"blt"|"cle"|"cgt"|"cge"|"clt"|"ceq"|"brtrue"|"brfalse"|"br"|"add"|"sub"|"div"|"rem"|"mul"|"beq"|"bne"|"cne"|"ldarga"|"ldloca"|"ldind"|"leave"|"newarr"|"shr"|"starg"|"stind"|"ldelem"|"ldelema"|"ldlen"|"stelem"|"unbox"|"box"|"initobj") '.' ['a'-'z' 'A'-'Z' '0'-'9' '.']+
{ let s = (lexeme lexbuf) in kwd_or_instr s }
| [ '`' '\128'-'\255' '@' '?' '$' 'a'-'z' 'A'-'Z' '_'] [ '`' '\128'-'\255' '$' 'a'-'z' 'A'-'Z' '0'-'9' '-' '_' '@' '$' ] *
{ kwd_or_instr_or_id (lexeme lexbuf) }
| [ '`' '\128'-'\255' '@' '?' '$' 'a'-'z' 'A'-'Z' '_'] [ '`' '\128'-'\255' '$' 'a'-'z' 'A'-'Z' '0'-'9' '-' '_' '@' '$' ]+
('.' [ '`' '\128'-'\255' '@' '?' '$' 'a'-'z' 'A'-'Z' '_'] [ '`' '\128'-'\255' '$' 'a'-'z' 'A'-'Z' '0'-'9' '-' '_' '@' '$' ] +)+
{ VAL_DOTTEDNAME(lexeme lexbuf) }
| ".cctor" {DOT_CCTOR}
| ".ctor" {DOT_CTOR}
| [' ' '\t' '\r' '\n']
{ token lexbuf }
| _
{ unexpected_char lexbuf }
| eof
{ EOF }
and singleQuoteString = parse
'\''
{ () }
| '\\' ("\010" | "\013" | "\013\010") [' ' '\009'] *
{ singleQuoteString lexbuf }
| '\\' ['\\' '\'' 'n' 't' 'b' 'r']
{ store_string_char(escape(String.get (lexeme lexbuf) 1));
singleQuoteString lexbuf }
| eof
{ failwith "unterminated string" }
| _
{ store_string_char(String.get (lexeme lexbuf) 0);
singleQuoteString lexbuf }
and stringToken = parse
'"'
{ () }
| '\\' ("\010" | "\013" | "\013\010") [' ' '\009'] *
{ stringToken lexbuf }
| '\\' ['\\' '"' 'n' 't' 'b' 'r']
{ store_string_char(escape(String.get (lexeme lexbuf) 1));
stringToken lexbuf }
| eof
{ failwith "unterminated string" }
| _
{ store_string_char(String.get (lexeme lexbuf) 0);
stringToken lexbuf }