123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- module Qsp.Ast
- open FsharpMyExtension
- type Op =
- /// `+`
- | Plus
- /// `-`
- | Minus
- /// `*`
- | Times
- /// `/`
- | Divide
- /// `mod`
- | Mod
- /// `=`
- | Eq
- /// `>`
- | Gt
- /// `>=`
- | Ge
- /// `<`
- | Lt
- /// `<=`
- | Le
- /// `!` — то же самое, что и `<>`
- | Bang
- /// `<>`
- | Ne
- /// `=<`
- | El
- /// `=>`
- | Eg
- /// `and`
- | And
- /// `or`
- | Or
- type IsBinOpSymbolic = bool
- [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
- [<RequireQualifiedAccess>]
- module Op =
- [<ReflectedDefinition>]
- let toString = function
- | Times -> "*"
- | Divide -> "/"
- | Mod -> "mod"
- | Plus -> "+"
- | Minus -> "-"
- | Lt -> "<"
- | Gt -> ">"
- | Le -> "<="
- | Eg -> "=>"
- | Ge -> ">="
- | El -> "=<"
- | Ne -> "<>"
- | And -> "and"
- | Or -> "or"
- | Eq -> "="
- | Bang -> "!"
- let ops =
- Reflection.Reflection.unionEnum<Op>
- |> Array.map (fun x ->
- let IsBinOpSymbolic opName =
- not <| String.exists FParsec.CharParsers.isLetter opName
- : IsBinOpSymbolic
- let y = toString x
- x, (y, IsBinOpSymbolic y) )
- let fromString =
- let m = Array.map (fun (a, b) -> b, a) ops |> Map.ofArray
- fun x -> match Map.tryFind x m with Some x -> x | None -> failwithf "not found %A" x
- type UnarOp =
- /// `-`
- | Neg
- /// `obj`
- | Obj
- /// `no`
- | No
- /// `loc`
- | Loc
- [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
- [<RequireQualifiedAccess>]
- module UnarOp =
- [<ReflectedDefinition>]
- let toString = function | Obj -> "obj" | Neg -> "-" | No -> "no" | Loc -> "loc"
- let ops =
- Reflection.Reflection.unionEnum<UnarOp>
- |> Array.map (fun x -> x, toString x)
- let fromString =
- let m = Array.map (fun (a, b) -> b, a) ops |> Map.ofArray
- fun x -> match Map.tryFind x m with Some x -> x | None -> failwithf "not found %A" x
- module Precedences =
- type T = OpB of Op | PrefB of UnarOp
- // &
- // OR
- // AND
- // OBJ, NO
- // =, <, >, !, <>, <=, >=, =<, =>
- // +, -
- // MOD
- // *, /
- // +, - (унарные)
- let prec = function
- | OpB Or -> 1
- | OpB And -> 2
- | PrefB No -> 3
- | PrefB Loc | PrefB Obj -> 4 // `no obj 'apple'` equal `no (obj 'apple')`
- // = | < | > | ! | <> | <= | >= | => | =<
- | OpB Eq | OpB Lt | OpB Gt | OpB Bang | OpB Ne | OpB Le | OpB Ge | OpB Eg | OpB El-> 5
- | OpB Plus | OpB Minus -> 6
- | OpB Mod -> 7
- | OpB Times | OpB Divide -> 8
- | PrefB Neg -> 9
- type VarType =
- /// `varName`, если к такой присвоить строковое значение, то интерпретатор попытается преобразовать ее в число. Если не получится, выбьет ошибку.
- | ImplicitNumericType
- /// `#varName`, если к такой присвоить строковое значение, то интерпретатор попытается преобразовать ее в число. Если не получится, выбьет ошибку.
- | ExplicitNumericType
- /// `$varName`, к такой переменной можно смело присваивать и число, и строку
- | StringType
- type Var = VarType * string
- type StmtsOrRaw =
- | Raw of string
- | StaticStmts of Statement list
- and LineKind =
- | StringKind of string
- /// Это то, что заключено между `<< >>`
- | ExprKind of Expr
- /// `<a href="exec: ...">some text</a>`
- | HyperLinkKind of StmtsOrRaw * Line list
- /// Без переносов
- and Line = LineKind list
- and Value =
- | Int of int
- | String of Line list
- and Expr =
- | Val of Value
- | Var of var:Var
- | Func of string * Expr list
- | Arr of var:Var * Expr list
- | UnarExpr of UnarOp * Expr
- | Expr of Op * Expr * Expr
- and AssignWhat =
- | AssignVar of var:Var
- /// Ключом массива может быть значение любого типа
- | AssignArr of var:Var * key:Expr
- | AssignArrAppend of var:Var
- and Statement =
- | Assign of AssignWhat * Expr
- | AssignCode of AssignWhat * Statement list
- | CallSt of string * Expr list
- /// Вычисляется `expr` и посылается в `*pl`
- | StarPl of Expr
- | If of Expr * Statement list * Statement list
- | Act of Expr list * Statement list
- | For of var:Var * from:Expr * to':Expr * step:Expr option * body:Statement list
- | Label of string
- | Comment of string
- | Exit
- type LocationName = string
- /// ```qsp
- /// # location name
- /// 'asdf'
- /// - произвольный набор символов
- /// ```
- type Location = Location of LocationName * Statement list
|