Files
WoofWare.PrattParser/PrattParser/Domain.fs
2024-01-22 18:37:38 +00:00

93 lines
2.5 KiB
Forth

namespace PrattParser
[<RequireQualifiedAccess>]
type Expr =
| Plus of Expr * Expr
| Times of Expr * Expr
| UnaryMinus of Expr
| Minus of Expr * Expr
| Int of int
| FunctionCall of Expr * Expr
| Var of string
| Factorial of Expr
| Paren of Expr
| IfThenElse of Expr * Expr * Expr
[<RequireQualifiedAccess>]
module Expr =
let plus a b = Expr.Plus (a, b)
let times a b = Expr.Times (a, b)
let unaryMinus a = Expr.UnaryMinus a
let minus a b = Expr.Minus (a, b)
let constInt a = Expr.Int a
let functionCall f x = Expr.FunctionCall (f, x)
let var name = Expr.Var name
let factorial a = Expr.Factorial a
let paren a = Expr.Paren a
let ifThenElse ifClause thenClause elseClause =
Expr.IfThenElse (ifClause, thenClause, elseClause)
[<RequireQualifiedAccess>]
type TokenType =
| Plus
| Minus
| Times
| ConstInt
| LeftBracket
| RightBracket
| Var
| Factorial
| If
| Then
| Else
type Token =
{
Type : TokenType
/// The token is represented in the string as s.[left .. left + len], i.e. inclusive.
Trivia : int * int
}
[<RequireQualifiedAccess>]
module Token =
let standalone (ty : TokenType) (left : int) (len : int) =
{
Type = ty
Trivia = (left, len)
}
let standalone' (ty : TokenType) (singleCharPos : int) =
{
Type = ty
Trivia = (singleCharPos, 1)
}
let (|SingleChar|_|) (i : int, c : char) : Token option =
match c with
| '(' -> standalone' TokenType.LeftBracket i |> Some
| ')' -> standalone' TokenType.RightBracket i |> Some
| '*' -> standalone' TokenType.Times i |> Some
| '+' -> standalone' TokenType.Plus i |> Some
| '-' -> standalone' TokenType.Minus i |> Some
| '!' -> standalone' TokenType.Factorial i |> Some
| _ -> None
let infixPrecedence (token : TokenType) : (int * int) option =
match token with
| TokenType.Plus
| TokenType.Minus -> Some (1, 2)
| TokenType.Times -> Some (3, 4)
| _ -> None
let prefixPrecedence (token : TokenType) : (unit * int) option =
match token with
| TokenType.Plus
| TokenType.Minus -> Some ((), 5)
| _ -> None
let postfixPrecedence (token : TokenType) : (int * unit) option =
match token with
| TokenType.Factorial -> Some (7, ())
| _ -> None