Files
WoofWare.PrattParser/PrattParser/Lexer.fs
2024-01-22 00:21:14 +00:00

48 lines
1.6 KiB
Forth

namespace PrattParser
[<RequireQualifiedAccess>]
module Lexer =
let private (|Digit|_|) (c : char) : byte option =
if '0' <= c && c <= '9' then
Some (byte c - byte '0')
else
None
let lex (s : string) : Token seq =
seq {
let mutable i = 0
while i < s.Length do
match i, s.[i] with
| Token.SingleChar token ->
i <- i + 1
yield token
| startI, Digit _ ->
i <- i + 1
let mutable shouldBreak = false
while not shouldBreak do
match s.[i] with
| Digit _ -> i <- i + 1
| _ -> shouldBreak <- true
yield Token.standalone TokenType.ConstInt startI (i - startI)
| _, ' ' -> i <- i + 1
| startI, c ->
if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') then
i <- i + 1
let mutable shouldBreak = false
while not shouldBreak do
let c = s.[i]
if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') then
i <- i + 1
else
shouldBreak <- true
yield Token.standalone TokenType.Var startI (i - startI)
else
failwithf "Could not tokenize, char %c, at position %i" c startI
}