// $Source$ // $Revision$ // $Date$ $use Access Arithm Box Compare Convert List StdIO Table; $use "rfpc"; $use "rfp_err"; $use "rfp_compile"; $use "rfp_format"; $use "rfp_helper"; $use "rfp_vars"; // verifies that all constructions in e.Sentence have right formats $func? Satisfies-Format? (e.InFormat) (e.OutFormat) e.Sentence = ; // verifies that all function calls found in e.expr have appropriate input // formats $func Check-Inputs e.Sentence = ; // verifies that all vars in e.Sentence are defined for the moment of use and // that there aren't repeated indexes in hard expressions $func Check-Vars (e.vars) e.Sentence = ; // for each new var verifies that it is realy new (then adds it to the var // list) or that it has right type $func Update-Vars s.format (e.vars) e.new-vars = e.updated-vars; // returns the maximum (by length) sequence of cuts contained in the argument $func? Get-Cuts t.Branch-or-Block = e.cuts-sequence; // Print error or warning message $func Print-Error s.warning-or-error? e.description t.pragma = ; $func Print-Pragma s.channel t.Pragma = ; $func AS-To-Ref e.AS-Expr = e.Refal-Expr; RFP-Check e.Items, { e.Items : e t.item e, { : v.targets = v.targets : e t.name e, t.item : (t t t t.name e);; }, t.item : (s.linkage s.tag t.pragma t.name (e.in) (e.out) t.branch), s.tag : \{ FUNC; FUNC?; TFUNC; }, { ) () t.branch>;; }, ) t.branch>, { >>;; }, $fail;; }; /* * Verifies that: * 1) Result of e.Sentence computing has format not wider than e.OutFormat. * 2) All constructions in e.Sentence returns expressions of right formats. * 3) e.Sentence deals with expressions with format under e.InFormat only. * 4) All function calls are performed with expressions of right formats. */ Satisfies-Format? (e.InFormat) (e.OutFormat) e.Sentence, { e.Sentence : $r e.Snt (ERROR t) e.queue = , ; e.Sentence (e.OutFormat) $iter { e.Sentence : e.Snt t.Statement, t.Statement : { (RESULT t.Pragma e.ResultExpression) = { e.ResultExpression : (s.block e), s.block : \{ BLOCK; BLOCK?; } = , e.Snt (); )> = , e.Snt (); = $fail; /* * So in the case of an error we can only return * coordinates of the whole result expression, but * not the concrete position of the error in a * block if the later has place. */ }; (FORMAT t.Pragma e.HardExpression) = // \{ // = e.Snt (); // , $fail; // }; (s.block t e.Branches), s.block : \{ BLOCK; BLOCK?; } = { e.Snt : /*empty*/ = /*empty*/; (Comp Branch); } :: e.pref, { e.Branches : e (BRANCH t e.Snt1) e, , $fail; e.Snt ((EVAR)); }; (NOT (BRANCH t e.Snt1)) = \{ , e.Snt e.Snt1 (); , $fail; }; (ITER (BRANCH t e.Snt1) (FORMAT t.Pragma e.HardExp) (BRANCH t e.Snt2)) = :: e.HardFormat, , e.Snt (FORMAT t.Pragma e.HardExp) e.Snt2 (e.OutFormat); (TRY (BRANCH t e.Snt1) e.NOFAIL t.CatchBlock) = , , e.Snt (); (s.tag t.Pragma e.PatternExpression), s.tag : \{ LEFT; RIGHT; } = // { // , { e.Snt : /*empty*/ = :: e.PatternFormat, { = /*empty*/ (); = $fail; }; e.Snt ((EVAR)); }; // \! $fail; // }; NOFAIL = e.Snt (); (FAIL t) = e.Snt (); (CUTALL t) = e.Snt (); (CUT t) = e.Snt (); (STAKE t) = e.Snt (); (BRANCH t e.Snt1) = (); (Comp Branch) = /*empty*/ (); }; } :: e.Sentence (e.OutFormat), e.Sentence : /*empty*/; }; /* * Verifies that all function calls found in e.expr have appropriate input * formats. */ Check-Inputs { t.first e.rest, t.first : { (CALL t.Pragma t.Fname e.ResultExpression), { > : (e.Fin), # )> = ;; }, ; (PAREN e.paren-expr) = ; t.var-or-symbol = /*empty*/; }, ; /*empty*/ = /*empty*/; }; /* * Verifies that all vars in e.Sentence are defined for the moment of use and * that there are not repeated indexes in hard expressions. * e.vars are known variables for the moment we have e.Sentence to dial with. */ Check-Vars (e.vars) e.Sentence = (e.vars) e.Sentence $iter \{ e.Sentence : t.Statement e.Snt, t.Statement : { (RESULT t e.Re) = , e.vars; (PAREN e.Re) = , e.vars; (CALL t t e.Re) = , e.vars; (s.type t.Pragma e.name), s.type : \{ EVAR; SVAR; TVAR; VVAR; } = { e.vars : e (s.t t.p e.name) e, { s.t : s.type; ; }; ; }, e.vars; (FORMAT t e.He) = : e.He-vars, { \? e.He-vars : e (s1 t.p1 e3) e (s2 t.p2 e3) e4, { s1 : s2; ; }, , e4 : /*empty*/ \! $fail; >; }; (LEFT t e.Pe) = >; (RIGHT t e.Pe) = >; (s.block t e.Branches), s.block : \{ BLOCK; BLOCK?; } = { e.Branches : e t.branch e, , $fail; e.vars; }; (BRANCH t e.Snt1) = , e.vars; (ITER t.IterBody t.IterVars t.IterCondition) = , t.IterVars : (FORMAT t e.He), > :: e.vars, , e.vars; (TRY t.TryBranch e.NOFAIL t.CatchBlock) = , , e.vars; t.any-other = e.vars; } :: e.vars, (e.vars) e.Snt; } :: (e.vars) e.Sentence, e.Sentence : /*empty*/; /* * For each new var verifies that it is realy new (then adds it to the var * list) or that it has right type. Returns updated list of variables. */ Update-Vars s.format? (e.vars) e.new-vars = (e.vars) e.new-vars $iter { e.new-vars : (s.type t.p2 e.name) e.rest, e.vars : { e (s.type t e.name) e = (e.vars) e.rest; e1 (s.t t.p1 e.name) e2, { s.format? : Format = (e1 e2 (s.type t.p2 e.name)) e.rest; , (e.vars) e.rest; }; e = (e.vars (s.type t.p2 e.name)) e.rest; }; } :: (e.vars) e.new-vars, e.new-vars : /*empty*/, e.vars; /* * Returns the maximum (by length) sequence of cuts contained in t.arg. * Cuts are represented by their pragmas. * Fails and prints error message if there are unbalanced cuts after '=' or * after $error. Prints error message, but not fails if there are unbalanced * cuts in negation or trap-sentence. */ Get-Cuts t.arg, t.arg : { (BRANCH t e.Sentence) = () e.Sentence; t.Block = () t.Block; } $iter { e.Sentence : e.Snt t.Statement, { t.Statement : \{ (CUTALL t); (ERROR t); } = { > = $fail; () e.Snt; }; t.Statement : { (CUT t.Pragma) = e.cuts t.Pragma; (STAKE t) = { ;; }; (NOT t.Branch) = { >>;; }, e.cuts; (s.block t e.Branches), s.block : \{ BLOCK; BLOCK?; } = () e.Branches $iter { e.Branches : t.Branch e.rest = { ;; } :: e.branch-cuts, { <">" () ()> = (e.branch-cuts) e.rest; (e.longest-cuts) e.rest; }; } :: (e.longest-cuts) e.Branches, e.Branches : /*empty*/ = { <">" () ()> = e.cuts; e.longest-cuts; }; (ITER t.IterBody t.IterVars t.IterCond) = :: e.cuts, :: e.body-cuts, { <">" () ()> = e.cuts; e.body-cuts; }; (TRY t.TryBranch e.NOFAIL t.CatchBlock) = { >>;; }, ; // :: e.catch-cuts, // { // <">" () ()> = // e.cuts; // e.catch-cuts; // }; t.any-other = e.cuts; } :: e.cuts, (e.cuts) e.Snt; }; } :: (e.cuts) e.Sentence, e.Sentence : /*empty*/, e.cuts; Print-Error s.WE e.Descrip t.Pragma = : s.n, >, , , s.WE e.Descrip : { Error! Re = ; Error! Call = ; Error! Pattern = ; Warning! Pattern = ; Error! Var-Re t.var = "' in result expression">; Error! Var-Hard t.var = "' in hard expression">; Error! Var-Type t.var s.type = "' of the variable '" "'">; Error! Cut = ; }; Print-Pragma s.channel (PRAGMA e.pragmas), e.pragmas : { e (FILE e.file-name) e, , $fail; e (LINE s.line s.col) e, , $fail; e = ; }; AS-To-Ref { SVAR = 's'; TVAR = 't'; VVAR = 'v'; EVAR = 'e'; (s.tag t (e.name)) = '.' ; };