// $Source$ // $Revision$ // $Date$ $use Apply Box Class Compare Convert StdIO Table; $use "rfpc"; $use "rfp_helper"; $use "rfp_list"; $use "rfp_mangle"; $box Module-Name; $box Current-Namespace; $box Entry; $box Entry-Name; $func ASAIL-To-CPP e.body = e.cpp-code; $func Namespace-Control e.qualifiers = e.namespace-control; $func Expr-To-CPP (e.ASAIL-Expr-init ) e.ASAIL-Expr-rest = e.ASAIL-Expr; $func Expr-Ref-To-CPP 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.prefix) s.Arg-Res-Tag e.ASAIL-Args = e.CPP-Args; $func Symbol-To-CPP s.RFP-Symbol = e.CPP-String; $func Name-To-CPP t.name = e.CPP-Name; $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.ModuleName) e.asail = , , , , { : v.cpp, { : v = ('}');; // close last namespace } :: e.close-namespace, , { : v.name = ('rfrt::Entry rf_entry (' v.name ');');; } :: e.entry, ('namespace refal\n{') ('using namespace rfrt;') v.cpp e.close-namespace e.entry ('}');; }; ASAIL-To-CPP e.asail, { e.asail : t.item e.rest, t.item : { (FUNC t.name (e.args) (e.ress) e.body) = { : t.name = >;; }, :: (e.qualifiers) e.name, ('RF_FUNC (' ', ' '(' '), ' '(' '))' () 'RF_END'); (IF (e.cond) e.body) = ('if (' ')') ('{' () '}'); (FOR (e.cont-label) (e.break-label) (e.cond) (e.step) e.body) = { e.cont-label : t = ('{' ('{' () '}') (LABEL ': {}') '}'); ('{' () '}'); } :: e.body, { e.break-label : t = (LABEL ': {}');; } :: e.break, ('for ( ; ' '; ' ')') e.body e.break; (LABEL (e.label) e.body) = { e.label : /*empty*/ = ('{' () '}' ); ('{' () '}') (LABEL ': {}'); }; (TRY e.body) = ('trap {' () '}'); (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 ' ' ';'); (INT t.var e.expr) = ('uintptr_t ' ' = ' ';'); (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 s.linkage t.name (e.comment) e.expr) = { s.linkage : LOCAL = 'static ';; } :: e.linkage, { t.name : (STATIC e) = () t.name; ; } :: (e.qualifiers) e.name, (e.linkage 'const Expr ' ' = ' ';'); (DECL-OBJ s.linkage s.tag t.name) = { s.linkage : LOCAL = 'static ';; } :: e.linkage, : s1 e2, :: (e.qualifiers) e.name, (e.linkage 'const Expr ' ' = new rftype::' s1 ' ();'); (DECL-FUNC s.linkage t.name) = :: (e.qualifiers) e.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*/ = ; // 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 = ; (s.var-tag (e.QualifiedName)) e.rest = ; }; $func Term-Ref-To-CPP e = e; Expr-Ref-To-CPP { /*empty*/ = 'empty'; term = ; expr = '(' > ')'; }; Term-Ref-To-CPP { (PAREN e.expr) = ' ()'; (EXPR e.expr) = 'Expr (' ')'; (DEREF e.expr (e.pos)) = 'Expr (' ', ' ')'; (SUBEXPR e.expr (e.pos) (e.len)) = 'Expr (' ', ' ', ' ')'; (REF t.name) = ; (s.var-tag t.name) = ; }; Expr-Int-To-CPP { /*empty*/ = /*empty*/; s.ObjectSymbol = { = s.ObjectSymbol; $error ("Illegal type int-symbol: " s.ObjectSymbol); }; (LENGTH e.expr) = '.get_len ()'; (MAX e.args) = 'pxx_max (' ')'; (MIN e.args) = 'pxx_min (' ')'; (INFIX s.op e.args) = '(' ')'; (REF t.name) = ; (s.var-tag t.name) = ; expr = '(' > ')'; }; Cond-To-CPP { /*empty*/ = /*empty*/; (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 (' ', ' ')'; (CHECK-ITER t.var) = 'iter(' ')'; (EQ e.expr1 (e.expr2) (e.pos)) = '.eq (' ', ' ')'; (FLAT-EQ e.expr1 (e.expr2) (e.pos)) = '.flat_eq (' ', ' ')'; (NOT e.cond) = '!' ; (INFIX s.op e.args) = '(' s.op e.args> ')'; expr = '(' > ')'; }; Infix-To-CPP s.arg2cpp s.op e.args, { e.args : (e.arg) e.rest = :: e.arg, :: e.rest, { e.arg : v, e.rest : v = e.arg ' ' s.op ' ' e.rest; e.arg e.rest; };; }; 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(' ')++'; }; $func Const-Expr-Aux e.expr = e.cpp-expr; Const-Expr-To-CPP { /*empty*/ = 'empty'; (SUBEXPR t.name s.pos s.len) = 'Expr (' ', ' s.pos ', ' s.len ')'; //FIXME: надо проверять, что s.pos и s.len // не превышают допустимых величин. // Задавать эти величины опциями. e.expr = : { ' + ' e.cpp-expr = e.cpp-expr; e.cpp-expr = e.cpp-expr; }; }; Const-Expr-Aux (e.accum) e.expr, { e.expr : s.sym e.rest, = ) e.rest>; e.accum : v = ' + Char::create_expr ("' e.accum '")' ; e.expr : t.item e.rest, t.item : { (PAREN e.paren-expr) = ' + (' ') ()'; (REF t.name) = ' + ' ; (STATIC e) = ' + ' ; s.sym, { , { <"<" () (2147483648)> = //FIXME: значение должно // задаваться опцией. ' + ShortInt::create_expr (' s.sym ')'; ' + Int::create_expr (' s.sym ')'; }; = ' + Word::create_expr ("' '")'; }; } :: e.cpp-item = e.cpp-item ; = /*empty*/; }; Symbol-To-CPP 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; }; 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; }; Name-To-CPP t.obj-name = :: (e.qualifiers) e.name, :: e.namespace, { e.qualifiers : e.namespace e.cont = ; ; }; Namespace-Control e.qualifiers, { : e.qualifiers; { : v = ('}');; } :: e.close-namespace, , e.close-namespace ('namespace ' '\n{'); };