Advertisement
Fel1x

F# PC NuML

Dec 1st, 2023
1,117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 7.64 KB | None | 0 0
  1. namespace FuML.NumlParser
  2.  
  3. open System
  4. open System.IO
  5. open FParsec
  6.  
  7. type num =
  8.     | Int of int32
  9.     | Float of double
  10.  
  11.  
  12. type Atom =
  13.     | Number of num
  14.     | String of string
  15.     | Bool of bool
  16.     | Nil of unit
  17.  
  18. type Type =
  19.     | Flat of string
  20.     | TypeTuple of Type list
  21.     | TypeArray of Type
  22.  
  23. type Exp =
  24.     | Atom of Atom
  25.     | ExpTuple of Exp list
  26.     | Where of Exp * Bind list
  27.     | Lambda of Arg list * Exp
  28.     | Variable of string
  29.     | Infix of Infix
  30.     | Call of Call
  31.     | Branch of Branch
  32.     | ExpArray of Exp list
  33.  
  34. and Bind = {name: string;exp: Exp}
  35.  
  36. and Arg =
  37.     {name: string
  38.      _type: Type option}
  39.  
  40.     override this.ToString() = $"{this.name}:{this._type}"
  41.  
  42. and Infix = {left: Exp;op: string;right: Exp}
  43. and Branch = {pred: Exp;_then: Exp;_else: Exp}
  44.  
  45. and Call =
  46.     {is_native: bool
  47.      name: string
  48.      args: Exp list}
  49.  
  50. type Stat =
  51.     | Decl of Decl
  52.     | Bind of Bind
  53.  
  54. and Decl =
  55.     | VarDecl of Bind
  56.     | FunctDecl of FunctDecl
  57.  
  58. and FunctDecl =
  59.     {name: string
  60.      args: Arg list
  61.      _type: Type option
  62.      body: Stat list * Exp}
  63.  
  64. type NumlParser() =
  65.     static let concat(str1: string,str2: string) = str1 + str2
  66.     static let concatList(values: Collections.Generic.IEnumerable<'t>) = String.Concat values
  67.    static let digitWithoutZero = regex "[1-9]"
  68.    static let blank opt = opt |> Option.defaultValue ""
  69.    static let NativeVarPrefix = pstring "$$"
  70.    static let Comma = pstring ","
  71.    static let KW_Else = pstring "else"
  72.    static let KW_End = pstring "end"
  73.    static let KW_Funct = pstring "funct"
  74.    static let KW_If = pstring "if"
  75.    static let KW_Let = pstring "let"
  76.    static let KW_Then = pstring "then"
  77.    static let KW_Where = pstring "where"
  78.    static let Id = regex "[a-zA-Z_]+[a-zA-Z0-9_]*"
  79.    static let Ws = regex "[ \t\n\r]+"
  80.  
  81.    static let FComment =
  82.        (choice
  83.            [pstring "//|" >>. restOfLine true
  84.             pstring "/|" >>. (charsTillString "|\\" true Int32.MaxValue)
  85.             Ws ]
  86.         |>> ignore)
  87.  
  88.    static let ntoa(n: num) =
  89.        match n with
  90.        | Int i -> Convert.ToString i
  91.        | Float f -> Convert.ToString f
  92.  
  93.  
  94.    static let TTrue = (pstring "true" |>> fun _ -> true)
  95.  
  96.    static let TFalse = (pstring "false" |>> fun _ -> false)
  97.  
  98.    static let TNil = (pstring "nil" |>> fun _ -> ())
  99.  
  100.    static member Stat = (NumlParser.Decl |>> Decl) <|> (NumlParser.Bind |>> Bind)
  101.  
  102.    static member Block = ((many NumlParser.Stat) .>>. NumlParser.PExp)
  103.  
  104.    static member Decl = (NumlParser.VarDecl <|> NumlParser.FunctDecl)
  105.  
  106.    static member VarDecl = (KW_Let >>. NumlParser.Bind |>> VarDecl)
  107.  
  108.    static member FunctDecl =
  109.        (((KW_Let >>. Id
  110.           .>>. NumlParser.FunctArgs
  111.           .>>. opt(pstring "==>" >>. NumlParser.Type)
  112.           .>> pstring "="
  113.           .>>. NumlParser.Block)
  114.          |>> (fun (((name,args),_type),body) ->
  115.              {name = name
  116.               args = args
  117.               _type = _type
  118.               body = body}))
  119.         |>> FunctDecl)
  120.  
  121.    static member Bool = (TTrue <|> TFalse)
  122.  
  123.    static member IntMod = (NumlParser.FSign .>>. NumlParser.FIntPos |>> concat |>> int)
  124.  
  125.    static member TFloat =
  126.        let dotPart = (pstring "." .>>. NumlParser.FIntPos) |>> concat
  127.  
  128.        let exponent =
  129.            (opt(
  130.                NumlParser.FExponent
  131.                <|> (dotPart .>>. (opt NumlParser.FExponent |>> blank) |>> concat)
  132.             )
  133.             |>> blank)
  134.  
  135.        ((NumlParser.IntMod |>> Int |>> ntoa) .>>. exponent |>> concat |>> double)
  136.  
  137.    static member PNumber = (NumlParser.IntMod |>> Int) <|> (NumlParser.TFloat |>> Float)
  138.  
  139.    static member PString = NumlParser.TString
  140.    static member PNil = TNil
  141.  
  142.    static member POpInfix = regex "[+\\-*/<>]|[<=>]=|[<>]"
  143.  
  144.    member this.readFile(path: string) =
  145.        File.ReadAllTextAsync path |> Async.AwaitTask |> Async.RunSynchronously
  146.  
  147.    static member FSign =
  148.        (opt(regex "[+~]")
  149.         |>> fun sign ->
  150.             match sign with
  151.             | Some "~" -> "-"
  152.             | Some "+"
  153.             | _ -> "+")
  154.  
  155.    static member FExponent =
  156.        (regex "[Ee]" .>>. NumlParser.FSign |>> concat .>>. NumlParser.FIntPos |>> concat)
  157.  
  158.  
  159.    static member TString =
  160.        let quote = pstring "\"" in
  161.  
  162.        (quote >>. many(regex "[^\"]" <|> pstring "\\\"") .>> quote |>> concatList)
  163.  
  164.  
  165.    static member FIntPos =
  166.        (choice
  167.            [pstring "0"
  168.             digitWithoutZero .>>. many digit |>> fun (first,rest) -> first + concatList rest ])
  169.  
  170.    static member PAtom =
  171.        (choice
  172.            [NumlParser.PNumber |>> Atom.Number
  173.             NumlParser.PString |>> Atom.String
  174.             NumlParser.Bool |>> Atom.Bool
  175.             NumlParser.PNil |>> Atom.Nil ])
  176.        |>> Exp.Atom
  177.  
  178.    static member PTuple = (pstring "(" >>. NumlParser.PExpList .>> pstring ",)") |>> Exp.ExpTuple
  179.  
  180.    static member PExpList =
  181.        ((NumlParser.PExp .>>. many(Comma >>. NumlParser.PExp)) |>> fun (a,b) -> a :: b)
  182.  
  183.    static member PExp =
  184.        (choice
  185.            [NumlParser.PAtom
  186.             NumlParser.PTuple
  187.             NumlParser.PWhere
  188.             NumlParser.PLambda
  189.             (Id |>> Variable)
  190.             NumlParser.PInfixOp
  191.             NumlParser.PInfixOp
  192.             NumlParser.PCall
  193.             NumlParser.PBranch
  194.             NumlParser.PArray
  195.             (pstring "(" >>. NumlParser.PExp .>> pstring ")") ])
  196.  
  197.    static member PInfixOp =
  198.        ((NumlParser.PExp .>>. NumlParser.POpInfix) .>>. NumlParser.PExp
  199.         |>> fun ((a,op),b) -> {left = a;op = op;right = b})
  200.        |>> Exp.Infix
  201.  
  202.    static member Bind =
  203.        ((Id .>> pstring "=") .>>. NumlParser.PExp)
  204.        |>> fun (name,exp) -> {name = name;exp = exp}
  205.  
  206.    static member PWhere =
  207.        let binds =
  208.            (((NumlParser.Bind |>> fun b -> [b])
  209.              .>>. (opt(many(Comma >>. NumlParser.Bind) .>> KW_End) |>> Option.defaultValue []))
  210.             |>> fun (a,b) -> a @ b) in
  211.  
  212.        ((NumlParser.PExp .>> KW_Where) .>>. binds) |>> Exp.Where
  213.  
  214.    static member PLambda =
  215.        (((KW_Funct >>. NumlParser.FunctArgs) .>> pstring "==>") .>>. NumlParser.PExp)
  216.        |>> Exp.Lambda
  217.  
  218.    static member FunctArgs = many1 NumlParser.Arg
  219.  
  220.    static member Arg: Parser<Arg,unit> =
  221.        (Id .>>. opt(pstring ":" >>. NumlParser.Type))
  222.        |>> fun (name,_type) -> {name = name;_type = _type}
  223.  
  224.    static member Type =
  225.        choice
  226.            [Id |>> Type.Flat
  227.             NumlParser.TupleType |>> Type.TypeTuple
  228.             NumlParser.ArrayType |>> Type.TypeArray ]
  229.  
  230.  
  231.  
  232.    //'(' type (',' type)* ',)'
  233.    static member TupleType =
  234.        (((pstring "(" >>. NumlParser.Type) .>>. many(Comma >>. NumlParser.Type))
  235.         .>> pstring ",)"
  236.         |>> fun (a,b) -> a :: b)
  237.  
  238.  
  239.    static member ArrayType = (pstring "[" >>. NumlParser.Type .>> pstring "]" |>> Type.TypeArray)
  240.  
  241.    static member PCall =
  242.        (((opt(NativeVarPrefix |>> fun _ -> true) |>> Option.defaultValue false)
  243.          .>>. Id
  244.          .>>. (many1 NumlParser.PExp))
  245.         |>> fun ((is_native,name),args) ->
  246.             {is_native = is_native
  247.              name = name
  248.              args = args})
  249.        |>> Exp.Call
  250.  
  251.  
  252.    static member PBranch =
  253.        ((KW_If >>. NumlParser.PExp .>> KW_Then .>>. NumlParser.PExp .>> KW_Else
  254.          .>>. NumlParser.PExp)
  255.         |>> fun ((pred,_then),_else) ->
  256.             {pred = pred
  257.              _then = _then
  258.              _else = _else})
  259.        |>> Exp.Branch
  260.  
  261.  
  262.    static member PArray = (pstring "[" >>. NumlParser.PExpList .>> pstring "]") |>> Exp.ExpArray
  263.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement