Converted repeat .. until .. -> do .. while .. od

This commit is contained in:
Dmitry Boulytchev 2021-01-31 19:27:00 +03:00
parent 297139c72a
commit 919cda5556
7 changed files with 17 additions and 18 deletions

View file

@ -1,6 +1,6 @@
local n = read ();
repeat
do
if n == 1 then write (0)
elif n == 2 then write (1)
@ -13,4 +13,4 @@ elif n == 4 then write (3)
n := n - 1
until (n == 0)
while n != 0 od

View file

@ -4,11 +4,11 @@ n := read ();
s := 1;
repeat
do
s := s * n;
n := n - 1
until (n == 0);
while n != 0 od;
write (s)

View file

@ -2,9 +2,9 @@ local s, n;
s := 0;
repeat
do
n := read ();
s := s + n
until (n == 0);
while n != 0 od;
write (s)

View file

@ -1,8 +1,8 @@
local x;
repeat
do
local n = read ();
x := n
until n > 0;
while n <= 0 od;
write (x)

View file

@ -377,7 +377,7 @@ module Expr =
(* empty statement *) | Skip
(* conditional *) | If of t * t * t
(* loop with a pre-condition *) | While of t * t
(* loop with a post-condition *) | Repeat of t * t
(* loop with a post-condition *) | DoWhile of t * t
(* pattern-matching *) | Case of t * (Pattern.t * t) list * Loc.t * atr
(* ignore a value *) | Ignore of t
(* unit value *) | Unit
@ -537,8 +537,8 @@ module Expr =
eval conf k (schedule_list [e; Control (fun (st, i, o, e::vs) -> (if Value.to_int e <> 0 then s1 else s2), (st, i, o, vs))])
| While (e, s) ->
eval conf k (schedule_list [e; Control (fun (st, i, o, e::vs) -> (if Value.to_int e <> 0 then seq s expr else Skip), (st, i, o, vs))])
| Repeat (s, e) ->
eval conf (seq (While (Binop ("==", e, Const 0), s)) k) s
| DoWhile (s, e) ->
eval conf (seq (While (e, s)) k) s
| Case (e, bs, _, _)->
let rec branch ((st, i, o, v::vs) as conf) = function
| [] -> failwith (Printf.sprintf "Pattern matching failed: no branch is selected while matching %s\n" (show(Value.t) (fun _ -> "<expr>") (fun _ -> "<state>") v))
@ -768,7 +768,7 @@ module Expr =
| _ -> Seq (i, While (c, Seq (b, s))))
}
| %"repeat" s:scope[infix][Void] %"until" e:basic[infix][Val] => {isVoid atr} => {
| %"do" s:scope[infix][Void] %"while" e:parse[infix][Val] => {isVoid atr} => %"od" {
materialize atr @@
match s with
| Scope (defs, s) ->
@ -781,8 +781,8 @@ module Expr =
defs
([], s)
in
Scope (defs, Repeat (s, e))
| _ -> Repeat (s, e)
Scope (defs, DoWhile (s, e))
| _ -> DoWhile (s, e)
}
| %"case" l:$ e:parse[infix][Val] %"of" bs:!(Util.listBy)[ostap ("|")][ostap (!(Pattern.parse) -"->" scope[infix][atr])] %"esac"{Case (e, bs, l#coord, atr)}
| l:$ %"lazy" e:basic[infix][Val] => {notRef atr} :: (not_a_reference l) => {env#add_import "Lazy"; ignore atr (Call (Var "makeLazy", [Lambda ([], e)]))}
@ -1265,7 +1265,6 @@ let run_parser cmd =
"skip";
"if"; "then"; "else"; "elif"; "fi";
"while"; "do"; "od";
"repeat"; "until";
"for";
"fun"; "local"; "public"; "external"; "import";
"length";

View file

@ -862,12 +862,12 @@ let compile cmd ((imports, infixes), p) =
let env, _ , s = compile_expr false cond env s in
env, false, [JMP cond; FLABEL loop] @ s @ [LABEL cond] @ se @ (if fe then [LABEL lexp] else []) @ [CJMP ("nz", loop)]
| Expr.Repeat (s, c) -> let lexp , env = env#get_label in
| Expr.DoWhile (s, c) -> let lexp , env = env#get_label in
let loop , env = env#get_label in
let check, env = env#get_label in
let env, fe , se = compile_expr false lexp env c in
let env, flag, body = compile_expr false check env s in
env, false, [LABEL loop] @ body @ (if flag then [LABEL check] else []) @ se @ (if fe then [LABEL lexp] else []) @ [CJMP ("z", loop)]
env, false, [LABEL loop] @ body @ (if flag then [LABEL check] else []) @ se @ (if fe then [LABEL lexp] else []) @ [CJMP ("nz", loop)]
| Expr.Leave -> env, false, []

View file

@ -1 +1 @@
let version = "Version 1.10, 7eb3e223b, Mon Jan 25 01:38:59 2021 +0300"
let version = "Version 1.10, 297139c72, Sun Jan 31 19:11:03 2021 +0300"