diff --git a/stdlib/Expr.expr b/stdlib/Expr.expr new file mode 100644 index 000000000..3d8d1c476 --- /dev/null +++ b/stdlib/Expr.expr @@ -0,0 +1,73 @@ +import Ostap; +import List; +import Fun; + +--- ops -> fun (x, y) {x `op` y} +fun altl (ps) { + case ps of + p : ps -> foldl (infix |, p, ps) + esac +} + +public fun expr (ops, opnd) { + fun inner (ops) { + case ops of + {} -> opnd + | level : tl -> + local lops = altl (level), + next = inner (tl); + + fun this (k) { + next |> fun (l) {lops |> fun (op) {this @ fun (r) {op (l, r)}}} + | next + $ k + } + + this + esac + } + + inner (ops) +} + +(* +Just some memo from OCaml's Ostap. Will be removed when done. + +let left f c x a y = f (c x) a y + let right f c x a y = c (f x a y) + +fun expr (ops, opnd, atr) { +} + + + ops = [is_nona, (atrs, alt_parser at the level), + ... + ] + let expr f ops opnd atr = + let ops = + Array.map + (fun (assoc, (atrs, list)) -> + let g = match assoc with `Lefta | `Nona -> left | `Righta -> right in + assoc = `Nona, (atrs, altl (List.map (fun (oper, sema) -> ostap (!(oper) {g sema})) list)) + ) + ops + in + let atrr i atr = snd (fst (snd ops.(i)) atr) in + let atrl i atr = fst (fst (snd ops.(i)) atr) in + let n = Array.length ops in + let op i = snd (snd ops.(i)) in + let nona i = fst ops.(i) in + let id x = x in + let ostap ( + inner[l][c][atr]: f[ostap ( + {n = l } => x:opnd[atr] {c x} + | {n > l && not (nona l)} => (-x:inner[l+1][id][atrl l atr] -o:op[l] y:inner[l][o c x atr][atrr l atr] | + x:inner[l+1][id][atr] {c x}) + | {n > l && nona l} => (x:inner[l+1][id][atrl l atr] o:op[l] y:inner[l+1][id][atrr l atr] {c (o id x atr y)} | + x:inner[l+1][id][atr] {c x}) + )] + ) + in + ostap (inner[0][id][atr])d + +*) \ No newline at end of file diff --git a/stdlib/regression/orig/test11.log b/stdlib/regression/orig/test11.log new file mode 100644 index 000000000..49b855cac --- /dev/null +++ b/stdlib/regression/orig/test11.log @@ -0,0 +1,6 @@ +Succ ("a") +Succ (Add ("a", "a")) +Succ (Sub ("a", "a")) +Succ (Add ("a", Sub ("a", "a"))) +Succ (Add ("a", Mul ("a", "a"))) +Succ (Sub (Mul ("a", "a"), Div ("a", "a"))) diff --git a/stdlib/regression/test11.expr b/stdlib/regression/test11.expr new file mode 100644 index 000000000..dab275c4d --- /dev/null +++ b/stdlib/regression/test11.expr @@ -0,0 +1,16 @@ +import Ostap; +import Expr; + +local a = token ("a"), + add = token ("+") @ lift (fun (l, r) {Add (l, r)}), + sub = token ("-") @ lift (fun (l, r) {Sub (l, r)}), + mul = token ("*") @ lift (fun (l, r) {Mul (l, r)}), + div = token ("/") @ lift (fun (l, r) {Div (l, r)}), + exp = expr ({{add, sub}, {mul, div}}, a); + +printf ("%s\n", parseString (exp |> bypass (eof), "a").string); +printf ("%s\n", parseString (exp |> bypass (eof), "a+a").string); +printf ("%s\n", parseString (exp |> bypass (eof), "a-a").string); +printf ("%s\n", parseString (exp |> bypass (eof), "a+a-a").string); +printf ("%s\n", parseString (exp |> bypass (eof), "a+a*a").string); +printf ("%s\n", parseString (exp |> bypass (eof), "a*a-a/a").string)