Skip to content

Commit 8944b82

Browse files
committed
Change LexBuffer type from char to uint16
1 parent d44950e commit 8944b82

File tree

11 files changed

+89
-25
lines changed

11 files changed

+89
-25
lines changed

src/absil/illex.fsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ open FSharp.Compiler.AbstractIL.Internal.AsciiParser
1616
open FSharp.Compiler.AbstractIL.Internal.AsciiConstants
1717

1818

19-
let lexeme (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
19+
let lexeme (lexbuf : LexBuffer<_>) = LexBuffer<_>.LexemeString (lexbuf)
2020

2121
let unexpectedChar _lexbuf =
2222
raise Parsing.RecoverableParseError ;;

src/absil/illib.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,9 @@ module String =
571571
else None
572572

573573
let getLines (str: string) =
574+
#if FABLE_COMPILER
575+
System.Text.RegularExpressions.Regex.Split(str, "\r\n|\r|\n");
576+
#else
574577
use reader = new StringReader(str)
575578
[|
576579
let line = ref (reader.ReadLine())

src/fsharp/UnicodeLexing.fs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@ open System.IO
1313

1414
open Internal.Utilities.Text.Lexing
1515

16-
type Lexbuf = LexBuffer<char>
16+
type Lexbuf = LexBuffer<LexBufferChar>
1717

1818
let StringAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, s:string) : Lexbuf =
19+
#if FABLE_COMPILER
20+
LexBuffer<_>.FromString (supportsFeature, s)
21+
#else
1922
LexBuffer<_>.FromChars (supportsFeature, s.ToCharArray())
23+
#endif
2024

21-
let FunctionAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, bufferFiller: char[] * int * int -> int) : Lexbuf =
25+
let FunctionAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, bufferFiller: LexBufferChar[] * int * int -> int) : Lexbuf =
2226
LexBuffer<_>.FromFunction(supportsFeature, bufferFiller)
2327

2428
let SourceTextAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, sourceText) =
@@ -69,5 +73,9 @@ let UnicodeFileAsLexbuf (supportsFeature: Features.LanguageFeature -> bool, file
6973
else
7074
reraise()
7175
let source = getSource 0
76+
#if FABLE_COMPILER
77+
let lexbuf = LexBuffer<_>.FromString (supportsFeature, source)
78+
#else
7279
let lexbuf = LexBuffer<_>.FromChars(supportsFeature, source.ToCharArray())
80+
#endif
7381
lexbuf

src/fsharp/UnicodeLexing.fsi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ open FSharp.Compiler.Text
77
open Microsoft.FSharp.Text
88
open Internal.Utilities.Text.Lexing
99

10-
type Lexbuf = LexBuffer<char>
10+
type Lexbuf = LexBuffer<LexBufferChar>
1111
val internal StringAsLexbuf: (Features.LanguageFeature -> bool) * string -> Lexbuf
12-
val public FunctionAsLexbuf: (Features.LanguageFeature -> bool) * (char [] * int * int -> int) -> Lexbuf
12+
val public FunctionAsLexbuf: (Features.LanguageFeature -> bool) * (LexBufferChar[] * int * int -> int) -> Lexbuf
1313
val public UnicodeFileAsLexbuf: (Features.LanguageFeature -> bool) * string * int option * (*retryLocked*) bool -> Lexbuf
1414
val public SourceTextAsLexbuf: (Features.LanguageFeature -> bool) * ISourceText -> Lexbuf

src/fsharp/fsi/fsi.fs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,7 @@ type internal FsiStdinLexerProvider
16191619

16201620
let LexbufFromLineReader (fsiStdinSyphon: FsiStdinSyphon) readf =
16211621
UnicodeLexing.FunctionAsLexbuf
1622-
(isFeatureSupported, (fun (buf: char[], start, len) ->
1622+
(isFeatureSupported, (fun (buf, start, len) ->
16231623
//fprintf fsiConsoleOutput.Out "Calling ReadLine\n"
16241624
let inputOption = try Some(readf()) with :? EndOfStreamException -> None
16251625
inputOption |> Option.iter (fun t -> fsiStdinSyphon.Add (t + "\n"))
@@ -1633,7 +1633,11 @@ type internal FsiStdinLexerProvider
16331633
if ninput > len then fprintf fsiConsoleOutput.Error "%s" (FSIstrings.SR.fsiLineTooLong())
16341634
let ntrimmed = min len ninput
16351635
for i = 0 to ntrimmed-1 do
1636+
#if FABLE_COMPILER
1637+
buf.[i+start] <- uint16 input.[i]
1638+
#else
16361639
buf.[i+start] <- input.[i]
1640+
#endif
16371641
ntrimmed
16381642
))
16391643

src/fsharp/lex.fsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ let shouldStartFile args lexbuf (m:range) err tok =
147147
else tok
148148

149149
let evalIfDefExpression startPos isFeatureSupported args (lookup:string->bool) (lexed:string) =
150+
#if FABLE_COMPILER
151+
let lexbuf = LexBuffer<_>.FromString (isFeatureSupported, lexed)
152+
#else
150153
let lexbuf = LexBuffer<char>.FromChars (isFeatureSupported, lexed.ToCharArray ())
154+
#endif
151155
lexbuf.StartPos <- startPos
152156
lexbuf.EndPos <- startPos
153157
let tokenStream = FSharp.Compiler.PPLexer.tokenstream args

src/fsharp/service/ServiceLexing.fsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace FSharp.Compiler.SourceCodeServices
44

55
open FSharp.Compiler
6+
open Internal.Utilities.Text.Lexing
67

78
type Position = int * int
89
type Range = Position * Position
@@ -237,7 +238,7 @@ type FSharpLineTokenizer =
237238
type FSharpSourceTokenizer =
238239
new : conditionalDefines:string list * fileName:string option -> FSharpSourceTokenizer
239240
member CreateLineTokenizer : lineText:string -> FSharpLineTokenizer
240-
member CreateBufferTokenizer : bufferFiller:(char[] * int * int -> int) -> FSharpLineTokenizer
241+
member CreateBufferTokenizer : bufferFiller:(LexBufferChar[] * int * int -> int) -> FSharpLineTokenizer
241242

242243
module internal TestExpose =
243244
val TokenInfo : Parser.token -> (FSharpTokenColorKind * FSharpTokenCharKind * FSharpTokenTriggerClass)

src/utils/prim-lexing.fs

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ type ISourceText =
3131
type StringText(str: string) =
3232

3333
let getLines (str: string) =
34+
#if FABLE_COMPILER
35+
System.Text.RegularExpressions.Regex.Split(str, "\r\n|\r|\n");
36+
#else
3437
use reader = new StringReader(str)
3538
[|
3639
let mutable line = reader.ReadLine()
@@ -42,6 +45,7 @@ type StringText(str: string) =
4245
// http://stackoverflow.com/questions/19365404/stringreader-omits-trailing-linebreak
4346
yield String.Empty
4447
|]
48+
#endif
4549

4650
let getLines =
4751
// This requires allocating and getting all the lines.
@@ -169,6 +173,12 @@ namespace Internal.Utilities.Text.Lexing
169173
0,
170174
0)
171175

176+
#if FABLE_COMPILER
177+
type internal LexBufferChar = uint16
178+
#else
179+
type internal LexBufferChar = char
180+
#endif
181+
172182
type internal LexBufferFiller<'Char> = (LexBuffer<'Char> -> unit)
173183

174184
and [<Sealed>]
@@ -217,6 +227,8 @@ namespace Internal.Utilities.Text.Lexing
217227
and set b = endPos <- b
218228

219229
member lexbuf.Lexeme = Array.sub buffer bufferScanStart lexemeLength
230+
member lexbuf.LexemeChar(n) = buffer.[n+bufferScanStart]
231+
220232
member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>)
221233
member lexbuf.LexemeLength with get() : int = lexemeLength and set v = lexemeLength <- v
222234
member lexbuf.Buffer with get() : 'Char[] = buffer and set v = buffer <- v
@@ -225,8 +237,14 @@ namespace Internal.Utilities.Text.Lexing
225237
member lexbuf.BufferScanStart with get() : int = bufferScanStart and set v = bufferScanStart <- v
226238
member lexbuf.BufferAcceptAction with get() = bufferAcceptAction and set v = bufferAcceptAction <- v
227239
member lexbuf.RefillBuffer () = filler lexbuf
228-
static member LexemeString(lexbuf:LexBuffer<char>) =
229-
new System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength)
240+
241+
static member LexemeString (lexbuf: LexBuffer<LexBufferChar>) =
242+
#if FABLE_COMPILER
243+
let chars = Array.init lexbuf.LexemeLength (lexbuf.LexemeChar >> char)
244+
new System.String(chars)
245+
#else
246+
new System.String(lexbuf.Buffer, lexbuf.BufferScanStart, lexbuf.LexemeLength)
247+
#endif
230248

231249
member lexbuf.IsPastEndOfStream
232250
with get() = eof
@@ -266,9 +284,13 @@ namespace Internal.Utilities.Text.Lexing
266284
LexBuffer<'Char>.FromArrayNoCopy(supportsFeature, buffer)
267285

268286
// Important: This method takes ownership of the array
269-
static member FromChars (supportsFeature:LanguageFeature -> bool, arr:char[]) = LexBuffer.FromArrayNoCopy (supportsFeature, arr)
287+
static member FromChars (supportsFeature:LanguageFeature -> bool, arr:LexBufferChar[]) = LexBuffer.FromArrayNoCopy (supportsFeature, arr)
270288

271289
static member FromSourceText (supportsFeature: LanguageFeature -> bool, sourceText: ISourceText) =
290+
#if FABLE_COMPILER
291+
let arr = Array.init sourceText.Length (fun i -> uint16 (sourceText.Item i))
292+
LexBuffer.FromArrayNoCopy (supportsFeature, arr)
293+
#else
272294
let mutable currentSourceIndex = 0
273295
LexBuffer<char>.FromFunction(supportsFeature, fun (chars, start, length) ->
274296
let lengthToCopy =
@@ -283,16 +305,25 @@ namespace Internal.Utilities.Text.Lexing
283305
currentSourceIndex <- currentSourceIndex + lengthToCopy
284306
lengthToCopy
285307
)
308+
#endif
309+
310+
static member FromString (supportsFeature: LanguageFeature -> bool, s: string) =
311+
#if FABLE_COMPILER
312+
let arr = Array.init s.Length (fun i -> uint16 s.[i])
313+
LexBuffer.FromArrayNoCopy (supportsFeature, arr)
314+
#else
315+
LexBuffer.FromArrayNoCopy (supportsFeature, s.ToCharArray())
316+
#endif
286317

287318
module GenericImplFragments =
288-
let startInterpret(lexBuffer:LexBuffer<char>) =
319+
let startInterpret(lexBuffer:LexBuffer<LexBufferChar>) =
289320
lexBuffer.BufferScanStart <- lexBuffer.BufferScanStart + lexBuffer.LexemeLength;
290321
lexBuffer.BufferMaxScanLength <- lexBuffer.BufferMaxScanLength - lexBuffer.LexemeLength;
291322
lexBuffer.BufferScanLength <- 0;
292323
lexBuffer.LexemeLength <- 0;
293324
lexBuffer.BufferAcceptAction <- -1;
294325

295-
let afterRefill (trans: uint16[][],sentinel,lexBuffer:LexBuffer<char>,scanUntilSentinel,endOfScan,state,eofPos) =
326+
let afterRefill (trans: uint16[][],sentinel,lexBuffer:LexBuffer<LexBufferChar>,scanUntilSentinel,endOfScan,state,eofPos) =
296327
// end of file occurs if we couldn't extend the buffer
297328
if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then
298329
let snew = int trans.[state].[eofPos] // == EOF
@@ -306,9 +337,9 @@ namespace Internal.Utilities.Text.Lexing
306337
else
307338
scanUntilSentinel lexBuffer state
308339

309-
let onAccept (lexBuffer:LexBuffer<char>,a) =
310-
lexBuffer.LexemeLength <- lexBuffer.BufferScanLength;
311-
lexBuffer.BufferAcceptAction <- a;
340+
let onAccept (lexBuffer:LexBuffer<LexBufferChar>, a) =
341+
lexBuffer.LexemeLength <- lexBuffer.BufferScanLength
342+
lexBuffer.BufferAcceptAction <- a
312343

313344
open GenericImplFragments
314345

@@ -333,12 +364,16 @@ namespace Internal.Utilities.Text.Lexing
333364
// ways
334365
let baseForUnicodeCategories = numLowUnicodeChars+numSpecificUnicodeChars*2
335366
let unicodeCategory =
367+
#if FABLE_COMPILER
368+
System.Char.GetUnicodeCategory(char inp)
369+
#else
336370
System.Char.GetUnicodeCategory(inp)
371+
#endif
337372
//System.Console.WriteLine("inp = {0}, unicodeCategory = {1}", [| box inp; box unicodeCategory |]);
338373
int trans.[state].[baseForUnicodeCategories + int32 unicodeCategory]
339374
else
340375
// This is the specific unicode character
341-
let c = char (int trans.[state].[baseForSpecificUnicodeChars+i*2])
376+
let c = trans.[state].[baseForSpecificUnicodeChars+i*2]
342377
//System.Console.WriteLine("c = {0}, inp = {1}, i = {2}", [| box c; box inp; box i |]);
343378
// OK, have we found the entry for a specific unicode character?
344379
if c = inp
@@ -360,7 +395,7 @@ namespace Internal.Utilities.Text.Lexing
360395
afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,eofPos)
361396
else
362397
// read a character - end the scan if there are no further transitions
363-
let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos]
398+
let inp = uint16 lexBuffer.Buffer.[lexBuffer.BufferScanPos]
364399

365400
// Find the new state
366401
let snew = lookupUnicodeCharacters state inp
@@ -378,7 +413,7 @@ namespace Internal.Utilities.Text.Lexing
378413
// 30 entries, one for each UnicodeCategory
379414
// 1 entry for EOF
380415

381-
member tables.Interpret(initialState,lexBuffer : LexBuffer<char>) =
416+
member tables.Interpret(initialState, lexBuffer: LexBuffer<LexBufferChar>) =
382417
startInterpret(lexBuffer)
383418
scanUntilSentinel lexBuffer initialState
384419

src/utils/prim-lexing.fsi

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ type internal Position =
8585

8686
static member FirstLine : fileIdx:int -> Position
8787

88+
#if FABLE_COMPILER
89+
type internal LexBufferChar = uint16
90+
#else
91+
type internal LexBufferChar = char
92+
#endif
93+
8894
[<Sealed>]
8995
/// Input buffers consumed by lexers generated by <c>fslex.exe</c>.
9096
/// The type must be generic to match the code generated by FsLex and FsYacc (if you would like to
@@ -100,7 +106,7 @@ type internal LexBuffer<'Char> =
100106
member Lexeme: 'Char []
101107

102108
/// Fast helper to turn the matched characters into a string, avoiding an intermediate array.
103-
static member LexemeString : LexBuffer<char> -> string
109+
static member LexemeString : LexBuffer<LexBufferChar> -> string
104110

105111
/// Dynamically typed, non-lexically scoped parameter table.
106112
member BufferLocalStore : IDictionary<string,obj>
@@ -113,13 +119,16 @@ type internal LexBuffer<'Char> =
113119

114120
/// Create a lex buffer suitable for Unicode lexing that reads characters from the given array.
115121
/// Important: does take ownership of the array.
116-
static member FromChars: (LanguageFeature -> bool) * char[] -> LexBuffer<char>
122+
static member FromChars: (LanguageFeature -> bool) * LexBufferChar[] -> LexBuffer<LexBufferChar>
123+
124+
/// Create a lex buffer suitable for Unicode lexing that reads characters from the given string.
125+
static member FromString: (LanguageFeature -> bool) * string -> LexBuffer<LexBufferChar>
117126

118127
/// Create a lex buffer that reads character or byte inputs by using the given function.
119128
static member FromFunction: (LanguageFeature -> bool) * ('Char[] * int * int -> int) -> LexBuffer<'Char>
120129

121130
/// Create a lex buffer backed by source text.
122-
static member FromSourceText : (LanguageFeature -> bool) * ISourceText -> LexBuffer<char>
131+
static member FromSourceText : (LanguageFeature -> bool) * ISourceText -> LexBuffer<LexBufferChar>
123132

124133
/// The type of tables for an unicode lexer generated by <c>fslex.exe</c>.
125134
[<Sealed>]
@@ -129,5 +138,5 @@ type internal UnicodeTables =
129138
static member Create : uint16[][] * uint16[] -> UnicodeTables
130139

131140
/// Interpret tables for a unicode lexer generated by <c>fslex.exe</c>.
132-
member Interpret: initialState:int * LexBuffer<char> -> int
141+
member Interpret: initialState:int * LexBuffer<LexBufferChar> -> int
133142

src/utils/prim-parsing.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ exception RecoverableParseError
1414
exception Accept of obj
1515

1616
[<Sealed>]
17-
type internal IParseState(ruleStartPoss:Position[], ruleEndPoss:Position[], lhsPos:Position[], ruleValues:obj[], lexbuf:LexBuffer<char>) =
17+
type internal IParseState(ruleStartPoss:Position[], ruleEndPoss:Position[], lhsPos:Position[], ruleValues:obj[], lexbuf:LexBuffer<LexBufferChar>) =
1818
member p.LexBuffer = lexbuf
1919

2020
member p.InputRange n = ruleStartPoss.[n-1], ruleEndPoss.[n-1]

0 commit comments

Comments
 (0)