Ast.fs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. module Qsp.Ast
  2. open FsharpMyExtension
  3. open Qsp
  4. [<Struct>]
  5. type Position = { StreamName:string; Index:int64; Line:int64; Column:int64 }
  6. let positionCreate streamName index line column =
  7. { StreamName = streamName; Index = index; Line = line; Column = column }
  8. let positionEmpty =
  9. positionCreate "" 0L 0L 0L
  10. type NoEqualityPosition(pos:Position) =
  11. member __.Pos = pos
  12. override __.ToString() = pos.ToString()
  13. override __.Equals _ = true
  14. override __.GetHashCode() = 0
  15. let test () =
  16. let x = NoEqualityPosition(positionCreate "" 0L 0L 0L)
  17. let y = NoEqualityPosition(positionCreate "" 0L 0L 1L)
  18. x = y
  19. [<Struct>]
  20. type Op =
  21. /// `+`
  22. | Plus
  23. /// `-`
  24. | Minus
  25. /// `*`
  26. | Times
  27. /// `/`
  28. | Divide
  29. /// `mod`
  30. | Mod
  31. /// `=`
  32. | Eq
  33. /// `>`
  34. | Gt
  35. /// `>=`
  36. | Ge
  37. /// `&lt;`
  38. | Lt
  39. /// `&lt;=`
  40. | Le
  41. /// `!` — то же самое, что и `&lt;>`
  42. | Bang
  43. /// `&lt;>`
  44. | Ne
  45. /// `=&lt;`
  46. | El
  47. /// `=>`
  48. | Eg
  49. /// `and`
  50. | And
  51. /// `or`
  52. | Or
  53. type IsBinOpSymbolic = bool
  54. [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  55. [<RequireQualifiedAccess>]
  56. module Op =
  57. [<ReflectedDefinition>]
  58. let toString = function
  59. | Times -> "*"
  60. | Divide -> "/"
  61. | Mod -> "mod"
  62. | Plus -> "+"
  63. | Minus -> "-"
  64. | Lt -> "<"
  65. | Gt -> ">"
  66. | Le -> "<="
  67. | Eg -> "=>"
  68. | Ge -> ">="
  69. | El -> "=<"
  70. | Ne -> "<>"
  71. | And -> "and"
  72. | Or -> "or"
  73. | Eq -> "="
  74. | Bang -> "!"
  75. let ops =
  76. Reflection.Reflection.unionEnum<Op>
  77. |> Array.map (fun x ->
  78. let IsBinOpSymbolic opName =
  79. not <| String.exists System.Char.IsLetter opName
  80. : IsBinOpSymbolic
  81. let y = toString x
  82. x, (y, IsBinOpSymbolic y) )
  83. let fromString =
  84. let m = Array.map (fun (a, b) -> b, a) ops |> Map.ofArray
  85. fun x -> match Map.tryFind x m with Some x -> x | None -> failwithf "not found %A" x
  86. [<Struct>]
  87. type UnarOp =
  88. /// `-`
  89. | Neg
  90. /// `obj`
  91. | Obj
  92. /// `no`
  93. | No
  94. /// `loc`
  95. | Loc
  96. [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  97. [<RequireQualifiedAccess>]
  98. module UnarOp =
  99. [<ReflectedDefinition>]
  100. let toString = function | Obj -> "obj" | Neg -> "-" | No -> "no" | Loc -> "loc"
  101. let ops =
  102. Reflection.Reflection.unionEnum<UnarOp>
  103. |> Array.map (fun x -> x, toString x)
  104. let fromString =
  105. let m = Array.map (fun (a, b) -> b, a) ops |> Map.ofArray
  106. fun x -> match Map.tryFind x m with Some x -> x | None -> failwithf "not found %A" x
  107. module Precedences =
  108. type T = OpB of Op | PrefB of UnarOp
  109. // &
  110. // OR
  111. // AND
  112. // OBJ, NO
  113. // =, <, >, !, <>, <=, >=, =<, =>
  114. // +, -
  115. // MOD
  116. // *, /
  117. // +, - (унарные)
  118. let prec = function
  119. | OpB Or -> 1
  120. | OpB And -> 2
  121. | PrefB No -> 3
  122. | PrefB Loc | PrefB Obj -> 4 // `no obj 'apple'` equal `no (obj 'apple')`
  123. // = | < | > | ! | <> | <= | >= | => | =<
  124. | OpB Eq | OpB Lt | OpB Gt | OpB Bang | OpB Ne | OpB Le | OpB Ge | OpB Eg | OpB El-> 5
  125. | OpB Plus | OpB Minus -> 6
  126. | OpB Mod -> 7
  127. | OpB Times | OpB Divide -> 8
  128. | PrefB Neg -> 9
  129. [<Struct>]
  130. type VarType =
  131. /// `varName`
  132. | NumericType
  133. /// `$varName`
  134. | StringType
  135. type 'Predef PredefUndef =
  136. | Predef of 'Predef
  137. | Undef of string
  138. type VarName = string
  139. type Var = VarType * VarName
  140. type StmtsOrRaw =
  141. | Raw of string
  142. | StaticStmts of PosStatement list
  143. and LineKind =
  144. | StringKind of string
  145. /// Это то, что заключено между `&lt;&lt; >>`
  146. | ExprKind of Expr
  147. /// `&lt;a href="exec: ...">some text&lt;/a>`
  148. | HyperLinkKind of StmtsOrRaw * Line list
  149. /// Без переносов
  150. and Line = LineKind list
  151. and Value =
  152. | Int of int
  153. | String of Line list
  154. and Expr =
  155. | Val of Value
  156. | Var of var:Var
  157. | Func of Defines.PredefFunc PredefUndef * Expr list
  158. | Arr of var:Var * Expr list
  159. | UnarExpr of UnarOp * Expr
  160. | Expr of Op * Expr * Expr
  161. and AssignWhat =
  162. | AssignVar of var:Var
  163. /// Ключом массива может быть значение любого типа
  164. | AssignArr of var:Var * key:Expr
  165. | AssignArrAppend of var:Var
  166. and PosStatement = NoEqualityPosition * Statement
  167. and Statement =
  168. | Assign of isLocal:bool * AssignWhat * Expr
  169. | AssignCode of AssignWhat * PosStatement list
  170. | Proc of string * Expr list
  171. | If of Expr * PosStatement list * PosStatement list
  172. | Act of Expr list * PosStatement list
  173. | Label of string
  174. | Comment of string
  175. | Exit
  176. type LocationName = string
  177. /// ```qsp
  178. /// # location name
  179. /// 'asdf'
  180. /// - произвольный набор символов
  181. /// ```
  182. type Location = Location of LocationName * PosStatement list