python: better syntax trees (flattened)

parent c51e9e11
...@@ -45,18 +45,20 @@ and stmt = { ...@@ -45,18 +45,20 @@ and stmt = {
} }
and stmt_desc = and stmt_desc =
| Sif of expr * stmt * stmt | Sif of expr * block * block
| Sreturn of expr | Sreturn of expr
| Sassign of ident * expr | Sassign of ident * expr
| Sprint of expr | Sprint of expr
| Sblock of stmt list | Swhile of expr * Ptree.loop_annotation * block
| Swhile of expr * Ptree.loop_annotation * stmt | Sfor of ident * expr * block
| Sfor of ident * expr * stmt
| Seval of expr | Seval of expr
| Sset of expr * expr * expr (* e1[e2] = e3 *) | Sset of expr * expr * expr (* e1[e2] = e3 *)
| Sassert of Ptree.term | Sassert of Ptree.term
and def = ident * ident list * stmt and block = stmt list
and def = ident * ident list * block
and file = def list * block
and file = def list * stmt
...@@ -102,16 +102,15 @@ let rec expr env {Py_ast.expr_loc = loc; Py_ast.expr_desc = d } = match d with ...@@ -102,16 +102,15 @@ let rec expr env {Py_ast.expr_loc = loc; Py_ast.expr_desc = d } = match d with
let rec stmt env ({Py_ast.stmt_loc = loc; Py_ast.stmt_desc = d } as s) = let rec stmt env ({Py_ast.stmt_loc = loc; Py_ast.stmt_desc = d } as s) =
match d with match d with
| Py_ast.Sblock sl ->
block env loc sl
| Py_ast.Seval e -> | Py_ast.Seval e ->
expr env e expr env e
| Py_ast.Sprint e -> | Py_ast.Sprint e ->
mk_expr ~loc (Elet (mk_id ~loc "_", Gnone, expr env e, mk_unit ~loc)) mk_expr ~loc (Elet (mk_id ~loc "_", Gnone, expr env e, mk_unit ~loc))
| Py_ast.Sif (e, s1, s2) -> | Py_ast.Sif (e, s1, s2) ->
mk_expr ~loc (Eif (expr env e, stmt env s1, stmt env s2)) mk_expr ~loc (Eif (expr env e, block env ~loc s1, block env ~loc s2))
| Py_ast.Swhile (e, ann, s) -> | Py_ast.Swhile (e, ann, s) ->
mk_expr ~loc (Ewhile (expr env e, loop_annotation env ann, stmt env s)) mk_expr ~loc
(Ewhile (expr env e, loop_annotation env ann, block env ~loc s))
| Py_ast.Sreturn _e -> | Py_ast.Sreturn _e ->
assert false (*TODO*) assert false (*TODO*)
| Py_ast.Sassign (id, e) -> | Py_ast.Sassign (id, e) ->
...@@ -120,7 +119,7 @@ let rec stmt env ({Py_ast.stmt_loc = loc; Py_ast.stmt_desc = d } as s) = ...@@ -120,7 +119,7 @@ let rec stmt env ({Py_ast.stmt_loc = loc; Py_ast.stmt_desc = d } as s) =
let x = let loc = id.id_loc in mk_expr ~loc (Eident (Qident id)) in let x = let loc = id.id_loc in mk_expr ~loc (Eident (Qident id)) in
mk_expr ~loc (Einfix (x, mk_id ~loc "infix :=", e)) mk_expr ~loc (Einfix (x, mk_id ~loc "infix :=", e))
else else
block env loc [s] block env ~loc [s]
| Py_ast.Sfor (_id, _e, _s) -> | Py_ast.Sfor (_id, _e, _s) ->
assert false (*TODO*) assert false (*TODO*)
| Py_ast.Sset (_e1, _e2, _e3) -> | Py_ast.Sset (_e1, _e2, _e3) ->
...@@ -128,7 +127,7 @@ let rec stmt env ({Py_ast.stmt_loc = loc; Py_ast.stmt_desc = d } as s) = ...@@ -128,7 +127,7 @@ let rec stmt env ({Py_ast.stmt_loc = loc; Py_ast.stmt_desc = d } as s) =
| Py_ast.Sassert t -> | Py_ast.Sassert t ->
mk_expr ~loc (Eassert (Aassert, deref env t)) mk_expr ~loc (Eassert (Aassert, deref env t))
and block env loc = function and block env ?(loc=Loc.dummy_position) = function
| [] -> | [] ->
mk_unit ~loc mk_unit ~loc
| { Py_ast.stmt_loc = loc; stmt_desc = Py_ast.Sassign (id, e) } :: sl | { Py_ast.stmt_loc = loc; stmt_desc = Py_ast.Sassign (id, e) } :: sl
...@@ -136,14 +135,16 @@ and block env loc = function ...@@ -136,14 +135,16 @@ and block env loc = function
let e = expr env e in (* check e *before* adding id to environment *) let e = expr env e in (* check e *before* adding id to environment *)
Hstr.add env.vars id.id_str id; Hstr.add env.vars id.id_str id;
let e1 = mk_expr ~loc (Eidapp (Qident (mk_id ~loc "ref"), [e])) in let e1 = mk_expr ~loc (Eidapp (Qident (mk_id ~loc "ref"), [e])) in
mk_expr ~loc (Elet (id, Gnone, e1, block env loc sl)) mk_expr ~loc (Elet (id, Gnone, e1, block env ~loc sl))
| { Py_ast.stmt_loc = loc } as s :: sl -> | { Py_ast.stmt_loc = loc } as s :: sl ->
mk_expr ~loc (Esequence (stmt env s, block env loc sl)) let s = stmt env s in
let sl = block env ~loc sl in
mk_expr ~loc (Esequence (s, sl))
let translate inc (_dl, s) = let translate inc (_dl, s) =
let params = [Loc.dummy_position, None, false, Some (PTtuple [])] in let params = [Loc.dummy_position, None, false, Some (PTtuple [])] in
let env = { vars = Hstr.create 32 } in let env = { vars = Hstr.create 32 } in
let fd = (params, None, stmt env s, empty_spec) in let fd = (params, None, block env s, empty_spec) in
let main = Dfun (mk_id "main", Gnone, fd) in let main = Dfun (mk_id "main", Gnone, fd) in
inc.new_pdecl Loc.dummy_position main inc.new_pdecl Loc.dummy_position main
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
file: file:
| NEWLINE? dl = list(def) b = list(stmt) EOF | NEWLINE? dl = list(def) b = list(stmt) EOF
{ dl, { stmt_desc = Sblock b; stmt_loc = floc $startpos(b) $endpos(b) } } { dl, b }
; ;
def: def:
...@@ -129,13 +129,11 @@ located(X): ...@@ -129,13 +129,11 @@ located(X):
| X { mk_stmt (floc $startpos $endpos) $1 } | X { mk_stmt (floc $startpos $endpos) $1 }
; ;
suite: located(suite_desc) { $1 }; suite:
suite_desc:
| s = simple_stmt NEWLINE | s = simple_stmt NEWLINE
{ s.stmt_desc } { [s] }
| NEWLINE BEGIN l = nonempty_list(stmt) END | NEWLINE BEGIN l = nonempty_list(stmt) END
{ Sblock l } { l }
; ;
stmt: located(stmt_desc) { $1 }; stmt: located(stmt_desc) { $1 };
...@@ -144,13 +142,13 @@ stmt_desc: ...@@ -144,13 +142,13 @@ stmt_desc:
| s = simple_stmt NEWLINE | s = simple_stmt NEWLINE
{ s.stmt_desc } { s.stmt_desc }
| IF c = expr COLON s = suite | IF c = expr COLON s = suite
{ Sif (c, s, mk_stmt (floc $startpos $endpos) (Sblock [])) } { Sif (c, s, []) }
| IF c = expr COLON s1 = suite ELSE COLON s2 = suite | IF c = expr COLON s1 = suite ELSE COLON s2 = suite
{ Sif (c, s1, s2) } { Sif (c, s1, s2) }
| WHILE e = expr COLON s = simple_stmt NEWLINE | WHILE e = expr COLON s = simple_stmt NEWLINE
{ Swhile (e, empty_annotation, s) } { Swhile (e, empty_annotation, [s]) }
| WHILE e = expr COLON NEWLINE BEGIN a=loop_annotation l=nonempty_list(stmt) END | WHILE e = expr COLON NEWLINE BEGIN a=loop_annotation l=nonempty_list(stmt) END
{ Swhile (e, a, mk_stmt (floc $startpos(l) $endpos(l)) (Sblock l)) } { Swhile (e, a, l) }
| FOR x = ident IN e = expr COLON s = suite | FOR x = ident IN e = expr COLON s = suite
{ Sfor (x, e, s) } { Sfor (x, e, s) }
; ;
......
a = 0 a = 0
b = 1 b = 1
l = range(0, 10)
## assert forall i. 0 <= i < 10 -> l[i] >= 0
while b < 100: while b < 100:
## invariant b >= a >= 0 ## invariant b >= a >= 0
## invariant b >= 1 ## invariant b >= 1
...@@ -11,6 +9,8 @@ while b < 100: ...@@ -11,6 +9,8 @@ while b < 100:
b = a+b b = a+b
## assert b >= 1 ## assert b >= 1
a = b-a a = b-a
l = range(0, 10)
## assert forall i. 0 <= i < 10 -> l[i] >= 0
# Local Variables: # Local Variables:
# compile-command: "make -C ../.. && why3 ide test.py" # compile-command: "make -C ../.. && why3 ide test.py"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment