Ast.fs 4.9 KB

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