// $Source$ // $Revision$ // $Date$ $use Class StdIO Arithm Compare Box Table; // Stack for optimization of expr-int: (s.flag s.int)...()... $box Stack-Int; // table of used label (break, continue) $table Used-Label; $func Optim-Int e.int = e.expr-int; $func Optim-Expr (e.init) e.rest = e.expr-optim; $func Optim-Ref e.expr = e.expr-ref; $func Optim-MAX (e.work-int) (e.res) e.rest = e.expr-max; $func Optim-MIN e.x = e.y; // $func Optim-MIN (e.work-int) (e.res) e.rest = e.expr-min; $func Optim-Add (s.res) (e.expr) e.expr-int = e.add; $func Optim-Minus (e.first) (e.expr) (s.int) e.expr-int = e.res; $func Optim-Mult (s.res) (e.expr) e.expr-int = e.mult; $func Optim-Div e.expr-int = e.res; $func Optim-Rem e.rest = e.res; $func Optim-Cond-Int s.op e.args = e.res; $func Optim-Cond (e.init) e.cond = e.res; $func Optim-Log-Args e.args = e.res; $func Optim-Cond-Log s.op e.args = e.res; $func AND-Args e.args = e.res; $func OR-Args e.args = e.res; $func Optim-Int-Args e.args = e.optim-args; $func Optim-Log-Expr e.log-expr = e.res; // function for Stack-Int $func Push = ; $func Pop = e.int; $func Add-Stack-Int s.int = ; $func Add-Stack-Flag = ; $func Args-Paren (e.init) e.rest = (e.res); $func Int-Paren e.init = e.res; $func Neg-Sign e.int = s.sign; $func Del-Neg e.int = e.res; $func Neg-Optim e.int = e.optim; // Deleting of unused label on level of function $func Correct-Label e.func-body = e.body; // Clear of table $func Clear-Table s.table e.key = ; $func Label-In-Table e.label = e.maybe-empty ; ASAIL-Optim e.asail, e.asail: { /*empty*/ = /*empty*/; t.item e.rest = t.item : { (FUNC t.name t.args t.ress e.body) = >, :: e.body, :: e.body, (FUNC t.name t.args t.ress e.body); (IF (e.cond) e.body) = :: e.res-cond, { e.res-cond: (0) = /*empty*/; :: e.body, { e.res-cond : (1) = (LABEL () e.body); (IF (e.res-cond) e.body); }; }; (FOR (e.cont-label) (e.break-label) (e.cond) (e.step) e.body) = :: e.body, (FOR (e.cont-label) (e.break-label) (e.cond) (e.step) e.body); (LABEL t.label e.body) = :: e.body, (LABEL t.label e.body) ; (TRY e.body) = :: e.body, (TRY e.body); (CATCH-ERROR e.body) = :: e.body, (CATCH-ERROR e.body); (LSPLIT e.expr (e.min) t.var1 t.var2) = :: e.expr, :: e.min, (LSPLIT e.expr (e.min) t.var1 t.var2) ; (RSPLIT e.expr (e.min) t.var1 t.var2) = :: e.expr, :: e.min, (RSPLIT e.expr (e.min) t.var1 t.var2) ; (ASSIGN t.var e.expr) = :: e.expr, (ASSIGN t.var e.expr); (INT t.var e.expr) = :: e.expr, (INT t.var e.expr); (EXPR t.var e.expr) = :: e.expr, (EXPR t.var e.expr); (DEREF t.var e.expr (e.pos)) = :: e.expr, (DEREF t.var e.expr ( )); (SUBEXPR t.var e.expr (e.pos) (e.len)) = :: e.expr, (SUBEXPR t.var e.expr ( ) ( ) ) ; // RETURN=RETURN; // RETFAIL=RETFAIL; // FATAL=FATAL; // (DECL e1) = (DECL e1); // (DROP e1) = (DROP e1); (CONTINUE t.label) = (CONTINUE t.label ) ; (BREAK t.label ) = (BREAK t.label ) ; // (ERROR e1) = (ERROR e1); // (CONSTEXPR e1) = (CONSTEXPR e1); // (DECL-CONST t.name) = (DECL-CONST t.name); // (DECL-OBJ e.obj) = (DECL-OBJ e.obj); // (DECL-FUNC e1) = (DECL-FUNC e1); // (s.call t.name (e.exprs) (e.ress)) = (s.call t.name (e.exprs)(e.ress)); t.item = t.item ; } :: e.cpp-item, e.cpp-item ; }; Optim-Expr (e.init) e.expr-all, e.expr-all : { /*empty*/ = e.init; s.ObjectSymbol e.rest, { = ; ; }; (LENGTH e.expr) e.rest = ; (MAX e.args) e.rest = ; (MIN e.args) e.rest = ; (INFIX s.op e.args) e.rest = ; (PAREN e.expr) e.rest = ; (EXPR e.expr) e.rest = ; (DEREF e.expr) e.rest = ; (SUBEXPR e.expr) e.rest = ; t.var e.rest = ; }; Optim-Ref { /*empty*/ = /*empty*/; t.item e.rest = t.item : { s.ObjectSymbol = s.ObjectSymbol; (PAREN e.expr) = (PAREN ); (EXPR e.expr) = (EXPR ); (DEREF e.expr (e.pos)) = (DEREF ( )); (SUBEXPR e.expr (e.pos) (e.len)) = (SUBEXPR ( ) ( )) ; t.var = t.var ; } :: e.cpp-item, e.cpp-item ; }; Optim-Int { /*empty*/ = ; t.item e.rest = t.item : { s.ObjectSymbol = s.ObjectSymbol; (LENGTH e.expr) = (LENGTH ); (MAX e.args) = :: e.args, ; (MIN e.args) = :: e.args, ; (INFIX s.op e.args ) = s.op: { "+" = :: e.args, ; "-" = :: e.args, ; "*" = :: e.args, ; "/" = :: e.args, ; "%" = :: e.args, ; }; t.var = t.var; } :: e.int-item, { e.int-item : s.numb = ; e.int-item ; }; }; Optim-Int-Args { /*empty*/ = /*empty*/; (s.int) e.rest = (s.int) ; (e.arg) e.rest = , :: e.res, ; }; Args-Paren { (e.init) = (e.init); (e.init) (()) e.rest = ; (e.init ) ((e.expr)) e.rest = ; (e.init)() e.rest = ; (e.init) t.expr e.rest = ; }; Optim-MAX (e.work) (e.res) e.rest, e.rest: { /*empty*/ = { e.work : 0 = { e.res: /*empty*/ = 0; :: s.sign, s.sign : { 1 = 0; 0 = (MAX (e.work) ); }; }; e.work : /*empty*/ = :: e.arg, e.arg : { (e.max) = (e.max); e.max = (MAX e.max); }; (MAX (e.work) ) ; }; (t.item) e.args = { t.item : s.IntSymbol = e.work : { /*empty*/ = ; s.Int = { <">" (s.IntSymbol) (s.Int)> = ; ; }; }; e.res : e.1 (t.item) e.2 = ; ; }; }; Neg-Sign { /*empty*/ = 1; ((INFIX "-" (0) e.int)) e.rest = ; e.int = 0; }; Del-Neg { /*empty*/ = /*empty*/; ((INFIX "-" (0) e.int)) e.rest = ; t.int e.rest = t.int ; }; Neg-Optim e.int = :: s.sign, { s.sign : 1 = e.int; ; }; Optim-MIN (e.work) (e.res) e.rest, e.rest: { /*empty*/ = e.work : { /*empty*/ = (MIN e.res); s.int = (MIN (s.int) e.res ) ; }; (t.item) e.args, t.item : { s.IntSymbol = e.work : { /*empty*/ = ; s.Int = { <"<" (s.IntSymbol) (s.Int)> = ; ; }; }; t.item = { e.res : e.1 (t.item) e.2 = ; ; }; }; }; Optim-Add (s.res) (e.expr) e.expr-int, e.expr-int : { /*empty*/ = { e.expr : /*empty*/ = s.res ; s.res : 0 = ; (INFIX "+" ( s.res e.expr) ) ; }; (0) e.rest = ; (s.Int) e.rest = ) (e.expr) e.rest>; t.int e.rest = ; }; Optim-Minus { ( )(e.expr)(s.int) = /*empty*/; ( )(e.expr)(s.int) t.term-int e.rest = ; ((e.first)) (e.expr) (s.int) e.expr-int = e.expr-int : { /*empty*/ = { e.first : s.first-int = { s.int : 0 = (INFIX "-" (s.first-int) e.expr); (INFIX "-" ( <"-" s.first-int s.int>) e.expr); }; e.expr : /*empty*/ = { s.int : 0 = ; (INFIX "-" (e.first) (s.int) ); }; s.int : 0 = (INFIX "-" (e.first) e.expr); (INFIX "-" (e.first) e.expr (s.int) ); }; e.first e.rest = ; (e.1 e.first e.2) e.rest = ; (0) e.rest = ; (s.new) e.rest = ) e.rest>; t.new e.rest = ; }; }; Optim-Mult (s.res) (e.expr) e.expr-int, e.expr-int : { /*empty*/ = { e.expr : /*empty*/ = s.res ; s.res : 1 = ; (INFIX "*" ( s.res) e.expr ) ; }; (0) e.rest = 0 ; (1) e.rest = ; (s.Int) e.rest = ) (e.expr) e.rest>; t.int e.rest = ; }; Optim-Div { /*empty*/ = /*empty*/; (0) e.expr = 0; t.int e.expr = :: e.znam, e.znam: { 1 = ; 1 e.rest = (INFIX "/" t.int e.rest ); e.znam = (INFIX "/" e.znam ); }; }; Optim-Rem { (0) e.int = 0; e.expr1 (0) e.expr2 = $error ("Int-operation Mod for zero"); t.int t.int e.expr = 0; t.int e.expr1 (1) e.expr2 = 0; (s.int1) (s.int2) e.expr = :: s.res, { s.res : 0 = 0; ; }; e.expr = (INFIX "%" e.expr); }; Optim-Cond (e.init) e.cond, e.cond: { /*empty*/ = { e.init : /*empty*/ = (1); e.init : ((e.res)) = (e.res) ; e.init; }; e.cond1 (0) e.cond2 = (0); e.cond1 (s.int) e.cond2 = ; t.cond-term e.rest = t.cond-term : { (CALL e.call) = ; (SYMBOL? e.expr (e.pos)) = :: e.expr, :: e.pos, ; (FLAT-SUBEXPR? e.expr (e.pos) (e.len)) = :: e.expr, :: e.pos, :: e.len, ; (EQ e.expr1 (e.expr2) (e.pos)) = :: e.expr1, :: e.expr2, :: e.pos, ; (FLAT-EQ e.expr1 (e.expr2) (e.pos)) = :: e.expr1, :: e.expr2, :: e.pos, ; (CHECK-ITER t.var) = ; (NOT e.cond-new) = :: e.res, e.res: { 0 = ; 1 = 0; e.res = ; }; (INFIX s.op e.args) = { s.op : \{ "&&"; "||"; } = :: e.args, ; s.op : \{ "<"; ">"; "<="; ">="; "=="; "!="; } = :: e.args, ; s.op : \{ "%"; "/";"*";"-";"+";} = ( ); } :: e.res, ; (s.int) = ; (e.expr-int) = )) e.rest>; }; }; Optim-Log-Args { /*empty*/ = /*empty*/; (s.int) e.rest = (s.int) ; (e.arg) e.rest = :: e.res, ; }; Optim-Cond-Log s.op e.res = // :: e.res, // { { e.res : t.result = t.result; { s.op : "&&" = { e.res : e.log1 0 e.log2 = (0); :: e.log, { e.log: /*empty*/ = (1); (INFIX "&&" e.log); }; }; s.op : "||" = { e.res : e.log1 1 e.log2 = (1); :: e.log, { e.log : /*empty*/ = (0); e.log : e.log1 s.int e.log2 = (1); (INFIX "||" e.log); }; }; }; }; AND-Args { /*empty*/ = /*empty*/; s.log e.args = ; t.log e.args = t.log ; }; OR-Args { /*empty*/ = /*empty*/; (0) e.args = ; s.log e.args = (1); t.log e.args = t.log ; }; Optim-Cond-Int s.op e.args, { e.args : (s.1) (s.2) = s.op : { "==" = { <"=" (s.1) (s.2) > = (1); (0); }; "!=" = { <"/=" (s.1) (s.2) > = (1); (0); }; "<" = { <"<" (s.1) (s.2)> = (1); (0); }; ">" = { <">" (s.1) (s.2)> = (1); (0); }; ">=" = { <">=" (s.1) (s.2)> = (1); (0); }; "<=" = { <"<=" (s.1) (s.2)> = (1); (0); }; }; // e.args : (0) (e.arg2) = s.op : { // "<=" = 1; // ">" = 0; // s.op = (INFIX s.op e.args); // }; // e.args : (e.arg1) (0) = s.op : { // "<" = 0; // ">=" = 1; // s.op = (INFIX s.op e.args); // }; e.args : (e.arg1)(e.arg1) = s.op:{ "==" = (1); "!=" = (0); "<=" = (1); ">=" = (1); "<" = (0); ">" = (0); }; (INFIX s.op e.args); }; Push /*empty*/ = >; Pop /*empty*/ = :: e.stack, e.stack : (s.flag e.int) e.rest, , e.int : { /*empty*/ = ; 0 = s.flag : { 0 = 0; 1 = ; }; s.res = s.res; }; Add-Stack-Int s.int = :: e.stack, e.stack : (s.flag e.res) e.rest, e.res : { /*empty*/ = ; s.old = ) e.rest>; }; Add-Stack-Flag /*empty*/ = :: e.stack, e.stack : (s.flag e.res) e.rest, ; Int-Paren { /*empty*/ = /*empty*/; ((e.int)) e.tail = (e.int) ; t.int e.tail = t.int ; }; Clear-Table { s.table = ; s.table (e.key) e.rest = ; }; Correct-Label e.asail, e.asail: { /*empty*/ = /*empty*/; t.item e.rest = t.item : { (IF (e.cond) e.body) = :: e.body, (IF (e.cond) e.body); (FOR (e.cont-label) (e.break-label) (e.cond) (e.step) e.body) = :: e.cont-label, :: e.break-label, :: e.body, (FOR (e.cont-label) (e.break-label) (e.cond) (e.step) e.body); (LABEL (e.label) e.body) = :: e.maybe-empty, :: e.body, (LABEL (e.maybe-empty) e.body) ; (TRY e.body) = :: e.body, (TRY e.body); (CATCH-ERROR e.body) = :: e.body, (CATCH-ERROR e.body); t.item = t.item ; } :: e.cpp-item, e.cpp-item ; }; Label-In-Table { /*empty*/ = ; t.label = { = t.label; ; }; }; Optim-Log-Expr { /*empty*/ = /*empty*/ ; t.term e.rest = t.term : { (CALL e.call) = (CALL e.call) ; (SYMBOL? e.expr (e.pos)) = :: e.expr, :: e.pos, (SYMBOL? e.expr (e.pos)); (FLAT-SUBEXPR? e.expr (e.pos) (e.len)) = :: e.expr, :: e.pos, :: e.len, (FLAT-SUBEXPR? e.expr (e.pos)(e.len)); (EQ e.expr1 (e.expr2) (e.pos) ) = :: e.expr1, :: e.expr2, :: e.pos, (EQ e.expr1 (e.expr2) (e.pos)); (FLAT-EQ e.expr1 (e.expr2) (e.pos)) = :: e.expr1, :: e.expr2, :: e.pos, (FLAT-EQ e.expr1 (e.expr2) (e.pos)); (CHECK-ITER t.var) = (CHECK-ITER t.var); (NOT e.cond-new) = :: e.res, e.res: { 0 = /*empty*/; 1 = (0) ; e.res = (NOT e.res) ; }; (INFIX s.op e.args) = { s.op : \{ "&&"; "||"; } = :: e.args, ; s.op : \{ "<"; ">"; "<="; ">="; "=="; "!="; } = :: e.args, ; s.op : \{ "%"; "/";"*";"-";"+";} = ( ); }; (s.int) = /*empty*/; (e.expr-int) = ( ); } :: e.res, e.res ; };