// $Source$ // $Revision$ // $Date$ $use Apply Box Class Convert StdIO Table; $use "rfpc"; $use "rfp_helper"; $box Func-Names; $table Func-Table; $box Var-Names; $table Var-Table; $func ASAIL-To-CPP e.body = e.cpp-code; // Constructs legal C++ name from e.Name and stores it in the appropriate box // and table $func Name-To-CPP t.Name = e.legal-cpp-name; $func Build-CPP-Name e.words = e.cpp-chars; $func Find-Unused-Name (e.used-names) e.name = e.unused-name; $func Word-To-CPP-Chars s.word = e.cpp-chars; $func Chars-To-CPP-Chars e.chars = e.cpp-chars; $func Expr-To-CPP (e.ASAIL-Expr-init ) e.ASAIL-Expr-rest = e.ASAIL-Expr; $func Expr-Ref-To-CPP s.inner-call? e.ASAIL-Expr-Ref = e.CPP-Expr-Ref; $func Expr-Int-To-CPP e.ASAIL-Expr-Int = e.CPP-Expr-Int; $func Step-To-CPP e.step-operators = e.cpp-step-operators; $func Const-Expr-To-CPP e.ASAIL-const-expr = e.CPP-const-expr; $func Args-To-CPP (e.Arg-Res-Tag) e.ASAIL-Args = e.CPP-Args; $func Symbol-To-CPP s.RFP-Symbol = e.CPP-String; $func Chars-To-CPP e.expr = e.CPP-String; $func Cond-To-CPP e.cond = e.CPP-Cond; $func Infix-To-CPP s.func-for-converting-args-to-cpp s.op e.args = e.cpp-expr; $func Op-Arg-To-CPP s.op = s.func-for-converting-args-to-cpp; RFP-ASAIL-To-CPP e.asail = , , ; ASAIL-To-CPP e.asail, { e.asail : t.item e.rest, t.item : { (FUNC t.name (e.args) (e.ress) e.body) = , , ('RF_FUNC (' ', ' '(' '), ' '(' '))' () 'RF_END'); (IF (e.cond) e.body) = ('if (' ')') ('{' () '}'); (FOR (e.label) (e.cond) (e.step) e.body) = { e.label : t = (LABEL ': {}');; } :: e.label, ('for ( ; ' '; ' ')') ('{' () e.label '}'); (LABEL t.label e.body) = ('{' () '}') (LABEL ': {}'); (TRY e.body) = ('try {' () '}'); (CATCH-ERROR e.body) = ('with {' () '}'); RETURN = ('return true;'); RETFAIL = ('retfail;'); FATAL = ('error ("Unexpected fail");'); (LSPLIT e.expr (e.min) t.var1 t.var2) = ('lsplit (' ', ' ', ' ', ' ');'); (RSPLIT e.expr (e.min) t.var1 t.var2) = ('rsplit (' ', ' ', ' ', ' ');'); (ASSIGN t.var e.expr) = ( ' = ' ';'); (DECL s.type t.var) = (s.type ' ' ';'); (EXPR t.var e.expr) = ('Expr ' ' (' ');'); (DEREF t.var e.expr (e.pos)) = ('Expr ' ' (' ', ' ');'); (SUBEXPR t.var e.expr (e.pos) (e.len)) = ('Expr ' ' (' ', ' ', ' ');'); (DROP t.var) = ( '.drop ();'); (CONTINUE t.label) = ('goto ' ';'); (BREAK t.label) = ('goto ' ';'); (ERROR e.expr) = ('error (' ');'); (CONSTEXPR t.name e.expr) = ('const Expr ' ' = ' ';'); (DECL-FUNC t.name) = ('RF_DECL (' ');'); /* * s.call can be CALL or TAILCALL */ (s.call t.name (e.exprs) (e.ress)) = ('RF_' s.call ' (' ', ' '(' '), (' '));'); } :: e.cpp-item, e.cpp-item ; /*empty*/; }; /* * Determine type of e.expr - int or Refal. */ Expr-To-CPP (e.init) e.expr-all, e.expr-all : { /*empty*/ = ; (VAR (e.QualifiedName)) e.rest = ; s.ObjectSymbol e.rest, { = ; ; }; (PAREN e.expr) e.rest = ; (EXPR e.expr) e.rest = ; (DEREF e.expr) e.rest = ; (SUBEXPR e.expr) e.rest = ; (LENGTH e.expr) e.rest = ; (MAX e.args) e.rest = ; (MIN e.args) e.rest = ; (INFIX s.op e.args) e.rest = ; }; Expr-Ref-To-CPP s.inner-call? e.expr-ref, e.expr-ref : { t.item e.rest = { e.rest : v = ' + '; /*empty*/; } :: e.plus, t.item : { s.ObjectSymbol = ; (PAREN e.expr) = ' ()'; (EXPR e.expr) = 'Expr (' ')'; (DEREF e.expr (e.pos)) = 'Expr (' ', ' ')'; (SUBEXPR e.expr (e.pos) (e.len)) = 'Expr (' ', ' ', ' ')'; (VAR (e.QualifiedName)) = ; ex = $error ("Illegal type ref-expr : " ex ); } :: e.cpp-item, e.cpp-item e.plus ; /*empty*/ = { s.inner-call? : 1 = /*empty*/; 'empty'; }; }; Expr-Int-To-CPP { t.item e.rest = { e.rest : v = ' + '; /*empty*/; } :: e.plus, t.item : { s.ObjectSymbol = { = ; $error ("Illegal type int-symbol: " s.ObjectSymbol); }; (LENGTH e.expr) = '(int) ' '.get_len ()'; (MAX e.args) = 'max (' ')'; (MIN e.args) = 'min (' ')'; (INFIX s.op e.args) = '(' ')'; (VAR (e.QualifiedName)) = ; ex = $error ("Illegal type ref-int : " ex ); } :: e.cpp-item, e.cpp-item e.plus ; /*empty*/ = /*empty*/; }; Cond-To-CPP { /*empty*/ = /*empty*/; t.cond-term e.rest = { e.rest : v = ' && '; /*empty*/; } :: e.and, t.cond-term : { (CALL t.name (e.exprs) (e.ress)) = 'RF_CALL (' ', ' '(' '), ' '(' '))'; (SYMBOL? e.expr (e.pos)) = '.symbol_at (' ')'; (FLAT-SUBEXPR? e.expr (e.pos) (e.len)) = '.flat_at (' ', ' ')'; /* * EQ -> to function eq() with 6 arg. */ (EQ (e.expr1) (e.pos1) (e.len1) (e.expr2) (e.pos2) (e.len2)) = 'eq (' ', ' ', ' ', ' ', ' ', ' ')'; /* * FLAT-EQ -> to function flat_eq() with 5 arg. */ (FLAT-EQ (e.expr1) (e.pos1) (e.expr2) (e.pos2) (e.len)) = 'flat_eq (' ', ' ', ' ', ' ', ' ')'; (NOT e.cond) = '!' ; (INFIX s.op e.args) = '(' s.op e.args> ')'; } :: e.cpp-term, e.cpp-term e.and ; }; Infix-To-CPP s.arg2cpp s.op e.args, { e.args : (e.arg) e.rest = { e.rest : v = ' ' s.op ' '; /*empty*/; } :: e.cpp-op, e.cpp-op ;; }; Op-Arg-To-CPP s.op, { s.op : \{ "&&"; "||"; } = &Cond-To-CPP; s.op : \{ "<"; ">"; "<="; ">="; "=="; "+"; "-"; "%"; "*"; "/"; } = &Expr-Int-To-CPP; }; Step-To-CPP { /*empty*/ = /*empty*/; (INC-ITER t.var) = 'iter(' ')++'; }; Const-Expr-To-CPP { /*empty*/ = 'empty'; e.expr = { e.expr : (e) e = /*empty*/; '(Expr) '; } :: e.cpp-expr, e.expr (e.cpp-expr) $iter { e.expr : t.item e.rest, { e.rest : v = ' + '; /*empty*/; } :: e.plus, t.item : \{ (PAREN e.paren-expr) = '(' ') ()'; (REF (e.QualifiedName s.name)) = ; } :: e.cpp-item = e.rest (e.cpp-expr e.cpp-item e.plus); e.expr : e.chars (e1) e2 = (e1) e2 (e.cpp-expr ' + '); /*empty*/ (e.cpp-expr ); } :: e.expr (e.cpp-expr), e.expr : /*empty*/ = e.cpp-expr; }; /* * Gets function name or variable and returns legal C++ name corresponding to * it. If is called with such parameter at the first time then stores C++ name * in the appropriate table for further using. Also put new name in the * appropriate box. Box and table for variables is updated for each new * function and box and table for functions is updated for each new module. */ Name-To-CPP term = term : { (VAR (e.QualifiedName)) = e.QualifiedName &Var-Names &Var-Table; (LABEL (e.QualifiedName)) = e.QualifiedName &Var-Names &Var-Table; (e.QualifiedName) = e.QualifiedName &Func-Names &Func-Table; // function name } :: e.QualifiedName s.used-names s.table, { ; e.QualifiedName : s.first e.last, :: e.first, { e.first : s.char e, , # \{ s.char : '?'; } = (e.first) e.last; ('R_' e.first) e.last; } :: (e.first) e.last, e.first :: e.name, ) e.name> :: e.name, , , e.name; }; Build-CPP-Name { s.word e.rest = '_' ; /*empty*/ = /*empty*/; }; Find-Unused-Name (e.used-names) e.name, { e.used-names : e1 (e.name) e2 = ; e.name; }; Word-To-CPP-Chars { "+" = '__add__'; "-" = '__sub__'; "*" = '__mult__'; s.word = >; }; Chars-To-CPP-Chars { s.sym e.chars, { s.sym : '?' = '_'; \{ ; ; } = s.sym; '_'; } :: s.sym = s.sym ; /*empty*/ = /*empty*/; }; Args-To-CPP { (e.prefix) Vars /*empty*/ = /*empty*/; (e.prefix) s.tag e.args = e.args () $iter { e.args : (e.arg) e.rest = { e.rest : v = ', '; /*empty*/; } :: e.comma, s.tag : { Vars = e.rest (e.cpp-args e.comma); Exprs = e.rest (e.cpp-args e.comma); Ints = e.rest (e.cpp-args e.comma); }; } :: e.args (e.cpp-args), e.args : /*empty*/, e.prefix e.cpp-args; }; Symbol-To-CPP s.ObjectSymbol, { = s.ObjectSymbol; () $iter { e.symbol : s.char e.rest, s.char : { '\\' = '\\\\'; '\n' = '\\n'; '\t' = '\\t'; // '\v' = '\\v'; // '\b' = '\\b'; '\r' = '\\r'; // '\f' = '\\f'; '\"' = '\\"'; '\'' = '\\\''; s = s.char; } :: e.cpp-char, e.rest (e.cpp-symbol e.cpp-char); } :: e.symbol (e.cpp-symbol), e.symbol : /*empty*/, '\"' e.cpp-symbol '\"'; }; Chars-To-CPP e.expr = >;