QS.fs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. module QS
  2. type value =
  3. | Int of int
  4. | Float of float
  5. | String of string
  6. type Ops =
  7. | Plus | Minus | Times | Divide | Mod
  8. | Eq | Gt | Ge | Lt | Le | Ne // =, >, >=, <, <=, (!, <>)
  9. | And | Or
  10. type UnarOp = Obj | No
  11. type Expr =
  12. | Val of value
  13. | Var of string
  14. | Func of string * Expr list
  15. | UnarExpr of UnarOp * Expr
  16. | Expr of Ops * Expr * Expr
  17. //and Call = { FunName: string; Args: Expr list }
  18. // cond не покрывает случай когда в выражении стоит переменная типа bool или же напрямую
  19. // одно из значений данного типа. К примеру: let var = true in if var then true else false
  20. //type If = { Cond:Expr; IfTrue:Statements list; Else: Statements list }
  21. //and Act = { Loc:string; ImagePath:string; Body: Statements list }
  22. type Statements =
  23. | Assert of Expr * Expr
  24. | AssertCode of Expr * Statements list
  25. | ExprS of Expr // вообще, достаточно какой-нибудь функции с побочным действием.
  26. | FuncS of string * Expr list
  27. | StringS of string
  28. | If of Expr * Statements list * Statements list
  29. | Act of Expr list * Statements list
  30. | Sign of string
  31. | Comment of string
  32. | Constr of string * Expr list * Statements list
  33. type Location = Location of string * Statements list
  34. let join s (xs:seq<string>) = System.String.Join(s, xs)
  35. let nl = "\r\n"
  36. let printState =
  37. let brake s = "[" + s + "]"
  38. let paren s = "(" + s + ")"
  39. let value = function
  40. | Int x -> x.ToString() | Float x -> x.ToString()
  41. | String x -> "'" + x + "'"
  42. let ops = function
  43. | Plus -> "+" | Minus -> "-" | Times -> "*" | Divide -> "/"
  44. | Eq -> "=" | Gt -> ">" | Ge -> ">=" | Lt -> "<" | Le -> "<" | Ne -> "!" // =, >, >=, <, <=, !
  45. | And -> "and" | Or -> "or" | Mod -> "mod"
  46. let unar = function No -> "no" | Obj -> "obj"
  47. let rec expr = function
  48. | Val v -> value v
  49. | Var v -> v
  50. | Func("idx", (Var x)::t) -> x + (List.map expr t |> join ", " |> brake)
  51. //| Func(x, [Func("idx", xs)]) -> x + (List.map expr xs |> join ", " |> brake)
  52. | Func(x, xs) -> x + (List.map expr xs |> join ", " |> paren)
  53. | UnarExpr(op, e) -> unar op + expr e |> paren
  54. | Expr(op, e1, e2) -> expr e1 + " " + ops op + " " + expr e2 |> paren
  55. let tabss n = String.replicate n "\t"
  56. let rec state tabs xs =
  57. let f = function [] -> "(NEWLINE)" | xs -> nl + join nl (List.map (state (tabs + 1)) xs)
  58. //let f' = function [] -> "(NEWLINE)" | xs -> " " + join "&" (List.map (state 0) xs)
  59. let rec f' = function
  60. | Assert(e1, e2) -> expr e1 + " = " + expr e2
  61. | AssertCode(e, xs) -> expr e + " = " + "{" + f xs + "}"
  62. | ExprS e -> expr e
  63. | Sign s -> ": " + s
  64. | StringS x -> "'" + x + "'"
  65. | If(e, [FuncS _ as x], []) -> "if " + expr e + ":" + " " + f' x
  66. | If(e, [FuncS _ as x], [FuncS _ as y]) -> "if " + expr e + ":" + " " + f' x + " else " + f' y
  67. | If(e, [Assert _ as x], []) -> "if " + expr e + ":" + " " + f' x
  68. | If(e, xs, ys) ->
  69. let rec els = function
  70. | [] -> ""
  71. | [If(e, xs, ys)] -> nl + tabss tabs + "elseif " + expr e + ":" + f xs + els ys
  72. | ys -> nl + tabss tabs + "else" + f ys
  73. "if " + expr e + ":" + f xs + els ys
  74. | Act(es, [FuncS _ as x]) -> "act " + join ", " (List.map expr es) + ":" + " " + f' x
  75. | Act(es, xs) -> "act " + join ", " (List.map expr es) + ":" + f xs
  76. | Comment s -> "! " + s
  77. | FuncS(name, xs) -> name + " " + (List.map expr xs |> join ", ")
  78. | x -> failwithf "%A absent" x
  79. tabss tabs + f' xs
  80. state 0
  81. let printLoc (Location(name, statements)) =
  82. sprintf "# %s" name + nl +
  83. join nl (List.map printState statements) + nl +
  84. sprintf "--- %s ----------" name
  85. let printLocs xs = List.map printLoc xs |> join nl
  86. assert
  87. let sample =
  88. If
  89. (Var "v1",
  90. [FuncS ("gs",[]);
  91. If
  92. (Var "v2",
  93. [If
  94. (Var "v3",[Act ([Var "v4"],[FuncS ("gt",[])])],
  95. [If
  96. (Var "v5",[Act ([Var "v6"],[FuncS ("gt",[])])],
  97. [If
  98. (Var "v7",
  99. [Act
  100. ([Var "v8"],
  101. [Act ([Var "v9"],[FuncS ("gt",[])]);
  102. Act
  103. ([Var "v10"],
  104. [If
  105. (Var "v",[Act ([Var "v"],[FuncS ("gt",[])])],
  106. [If
  107. (Var "v",
  108. [Act ([Var "v"],[FuncS ("gt",[])])],[])])])])],
  109. [])])])],[]);
  110. If
  111. (Var "v",
  112. [If
  113. (Var "v",
  114. [If
  115. (Var "v",
  116. [If
  117. (Var "v",
  118. [Act
  119. ([Var "v"],
  120. [FuncS ("gs",[]); Act ([Var "v"],[FuncS ("gt",[])])])],
  121. [])],
  122. [If
  123. (Var "v",
  124. [If
  125. (Var "v",
  126. [Act
  127. ([Var "v"],
  128. [FuncS ("gs",[]);
  129. Act ([Var "v"],[FuncS ("gt",[])])])],[])],
  130. [If
  131. (Var "v",
  132. [If
  133. (Var "v",
  134. [Act
  135. ([Var "v"],
  136. [FuncS ("gs",[]);
  137. Act ([Var "v"],[FuncS ("gt",[])])])],[])],
  138. [])])])],[])],[]); Act ([Var "v"],[FuncS ("gt",[])])],
  139. [])
  140. printState sample |> ignore
  141. true