$use Access Apply Arithm Box Class Compare Convert CppMangle List StdIO Table; $use "org.refal.plus.compiler.rfpc"; $use "org.refal.plus.compiler.rfp_helper"; $use "org.refal.plus.compiler.rfp_vars"; $box Int; $box Module_Name; $box Current_Namespace; $box Current_Func; $box Current_Trace; $box Entry; $box Entry_Name; $box Const_Exprs; $table Externs; $table Unavailable_Imports; $table Used_Unavailable_Imports; $table Decls; $table Locals; $table Used_Consts; $func ASAIL_To_CPP e.body = e.cpp_code; $func Open_Namespace e.name = e; $func Close_Namespace e.name = e; $func Namespace_Control e.qualifiers = e.namespace_control; $func Expr_Ref_To_CPP s.tvars_box e.ASAIL_Expr_Ref = e.CPP_Expr_Ref; $func Term_Ref_To_CPP s.tvars e = e; $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 QName_To_Cpp e.name = e.cpp_name; $func Name_To_CPP s.decl_type t.name e.args = e.CPP_Name; $func Cond_To_CPP t.cond = e.CPP_Cond; $func Infix_To_CPP (e.box) s.func_for_converting_args_to_cpp s.op e.args = e.cpp_expr; $func Trace_Enter e.name (e.args) = e.trace; $func Trace_Exit e.name (e.ress) = e.trace; $func Trace_Fail e.name = e.trace; $func Extract_Qualifiers t.name = (e.qualifiers) e.name; RFP_ASAIL_To_TPP (MODULE (e.ModuleName) e.asail) = { >; ; }, , , { >; ; }, , , , , , , , , { : v.cpp, v.cpp )> :: v.cpp, , > :: e.imp, e.imp )> v.cpp :: v.cpp, , { : v.name = ('rfrt::Entry rf_entry (' v.name ');');; } :: e.entry, { : v.c_exprs = > :: e.nc, (/*e.init_consts*/) (/*e.decl_consts*/) v.c_exprs $iter { e.c_exprs : (t.name (e.value) e.decl) e.rest = { = { t.name : (STATIC e) = ; ; } :: e.name, (e.init_consts (e.name ' = new TExpr;') (e.value ';')) (e.decl_consts e.decl) e.rest; (e.init_consts) (e.decl_consts) e.rest; }; } :: (e.init_consts) (e.decl_consts) e.c_exprs, e.c_exprs : /*empty*/ = e.nc ('static void init_ () {' (e.init_consts) '}') ('static AtStart init_registrator_ (&init_);') )> ( > e.decl_consts )> ); (); } :: e.init (e.decl_consts), , ('#include ') ('using namespace rfrt;') ) >> )> e.decl_consts v.cpp e.init e.entry;; }; ASAIL_To_CPP e.asail, { e.asail : t.item e.rest, t.item : { (s.tag UNDEF e) = ; (LINENUMBER sN) = ; (NATIVE s.linkage s.tag (e.name) (e.in) (e.out) e.native) = ) 'arg'>> : e.rfArg s, ) 'res'>> : e.rfRes s, ; (s.tag IMPORT (e.name) t.args t.ress e.body), s.tag : \{ FUNC; "FUNC?"; }, e.name : "org" "refal" "plus" "wrappers" e.n = >) t.args t.ress (ERROR e.n "Not available"))>; (TFUNC s.linkage t.name (e.args) (e.ress) e.body), , { : e t.name e = >>;; }, { \{ ; ; } = > :: e.name, , () (); , () (); } :: (e.trace_enter) (e.trace_exit), )> :: e.args, :: e.args, ('TExpr')> :: e.proto_args, )> :: e.ress, :: e.ress, ('tout Expr')> :: e.proto_ress, > :: e.args, > :: e.proto_args, :: (e.qualifiers) e, ('tfun int '' ('e.args') {' (e.trace_enter e.trace_exit ('return 0;')) '}'); (s.tag s.linkage t.name (e.args) (e.ress) e.body), s.tag : \{ FUNC; "FUNC?"; } = , { : e t.name e = >>;; }, { \{ ; ; } = > :: e.name, , () (); , () (); } :: (e.trace_enter) (e.trace_exit), )> :: e.args, ('Expr&')> :: e.proto_args, >> :: e.args, :: (e.qualifiers) e, //T/ ('RF_FUNC (' ', ' //T/ ', ' //T/ ')' //T/ (e.trace_enter e.trace_exit) //T/ 'RF_END'); ('int '' ('e.args') {' (e.trace_enter e.trace_exit ('return 0;')) '}'); (TRACE t.name) = ; ("IF-INT-CMP" s.op (e.arg1) (e.arg2) e.body) = ('if (' ' 's.op' ' ')') ('{' () '}'); (IF t.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) = ('{' () '}') (LABEL ': {}'); (TRY e.body) = ('RF_TRAP') ('{' () '}'); ("CATCH-ERROR" e.body) = ('RF_WITH') ('{' (('RF_CLEANUP;') ) '}'); RETFAIL = { : e.name (e.ress) = ; /*empty*/; } :: e.trace_exit, e.trace_exit ('return 1;'); FATAL = // : (e.name), ('{' (('TExpr ex;') ('((Expr&)ex).init_str("Unexpected fail", 15);') ('throw ex;')) '}'); //T/ ('RF_FUNC_ERROR (unexpected_fail);'); (LSPLIT e.expr (e.min) t.var1 t.var2) = :: s.tvars, :: e.expr, ('RF_lsplit ('e.expr', ' ', ' ', '');'); (RSPLIT e.expr (e.min) t.var1 t.var2) = :: s.tvars, :: e.expr, ('RF_rsplit ('e.expr', '', ' ', '');'); (ASSIGN t.var e.expr), t.var : (INT e) = ( ' = ' ';'); (ASSIGN t.var e.expr) = :: s.tvars, :: e.expr, ( ' = 'e.expr';'); (DECL t.var e.expr), t.var : (INT e) = ('int ' ' = '';'); (DECL s.type t.var) = ('TExpr ' ';'); (DECL s.type t.var (SUBEXPR e.expr (e.pos) (e.len))) = :: s.tvars, : 'TExpr ' e.constr, ('TExpr ' e.constr';'); (DECL s.type t.var (DEREF e.expr (e.pos))) = :: s.tvars, ('TExpr '' = ' '((Expr&)'')' '[''].e;'); (DECL s.type t.var e.expr) = :: s.tvars, :: e.expr, ('TExpr ' ' ('e.expr');'); (DROP t.var) = ( '.drop ();'); (CONTINUE t.label) = ('goto ' ';'); (BREAK t.label) = ('goto ' ';'); (ERROR e.expr) = :: s.tvars, :: e.expr, ('RF_ERROR ('e.expr');'); (CONSTEXPR IMPORT (e.name) (e.comment) e.expr) = e.name : "org" "refal" "plus" "wrappers" e.n, >) () e.expr)>; (CONSTEXPR s.linkage t.name (e.comment) e.expr) = { s.linkage : LOCAL = 'static ';; } :: e.linkage, { t.name : (STATIC e) = () (&Rfp2Cpp t.name); (&Name_To_CPP "DECL-OBJ" t.name); } :: (e.qualifiers) e (s.name_producer e.name_arg), ) /*e.qualifiers*/ (e.linkage 'TExpr* ' ';'))>; (OBJ s.linkage s.tag t.name) = , { s.linkage : LOCAL = 'static ';; } :: e.linkage, : s1 e2, :: (e.qualifiers) e.n, { s.tag : BOX = >(' 'L"'e.n'")'))>; // s.tag : VECTOR = // >(' // 'L"'e.n'")'))>; '>(L"'e.n'")'))>; }, (e.linkage 'Expr ' ';'); ("DECL-OBJ" t.name) = :: (e.qualifiers) e, ('extern Expr ' ';'); ("DECL-TFUNC" t.name e.args) = :: (e.qualifiers) e, ('tfun int '' 'e.args';'); ("DECL-FUNC" t.name e.args) = :: (e.qualifiers) e, ('int '' 'e.args';'); (EXTERN t.name) = , :: (e.qualifiers) e, ('RF_DECL (' ');'); /* * s.call can be CALL or TAILCALL or TAILCALL? */ (s.call t.name (e.exprs) (e.ress)) = { # \{ s.call : CALL; }, : e.full_name (e.ress) = ('if (RF_CALL (' ', ' ', ' '))') ('{' ( ('return true;')) '}') ('else RF_RETFAIL;'); //T/ { //T/ s.call : "TAILCALL?" = TAILCALL; //T/ s.call; //T/ } :: s.call, //T/ ('RF_' s.call ' (' ', ' //T/ ', ' ');'); > ('Expr&')> :: e.proto_args, ('(' ) )>>> ');'); }; } :: e.cpp_item, e.cpp_item ; /*empty*/; }; Expr_Ref_To_CPP s.tvars e.expr = e.expr : { /*empty*/ = 'empty'; term = ; expr = '(' > ')'; }; Term_Ref_To_CPP s.tvars e.arg = e.arg : { (PAREN e.expr) = ' ()'; (DEREF e.expr (e.pos)) = 'TExpr (' ', ' ')'; (SUBEXPR e.expr (e.pos) (e.len)) = 'TExpr (' ', ' ', ' ')'; (REF t.name) = ; "ERROR-EXPR" = 'err'; (STATIC t.name) = , :: e.namespace, { : e.namespace = /*empty*/; '::'; } :: e.prefix, '*' e.prefix ; (s.var_tag e.ns t.name) = ; s.sym, { = 'Expr::create<' '>("' s.sym '")'; = 'Expr::create("' '")'; }; }; Expr_Int_To_CPP { /*empty*/ = /*empty*/; s.ObjectSymbol = { = s.ObjectSymbol; $error ("Illegal type int-symbol: " s.ObjectSymbol); }; (LENGTH e.expr) = '((Expr&)' 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 { ("CALL-FAILS" (CALL t.name (e.exprs) (e.ress))) = > ('Expr&')> :: e.proto_args, '!RF_CALL (' ', ' ', ' ')'; ("SYMBOL?" e.expr (e.pos)) = '((Expr&)' e.expr> ').symbol_at(' ')'; ("FLAT-SUBEXPR?" e.expr (e.pos) (e.len)) = e.expr> '.flat_at (' ', ' ')'; ("ITER-FAILS" e.expr) = '!RF_iter(' e.expr> ')'; (EQ e.expr1 (e.expr2) (e.pos)) = e.expr1> '.eq (' e.expr2> ', ' ')'; ("TERM-EQ" e.expr1 (e.expr2) (e.pos)) = '((Expr&)' e.expr1>')[0] == ' '((Expr&)' e.expr2>')['']'; //T/ e.expr1> '.term_eq (' //T/ e.expr2> ', ' ')'; (NOT t.cond) = '!' ; }; Infix_To_CPP (e.box) 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; };; }; Step_To_CPP { /*empty*/ = /*empty*/; ("INC-ITER" e.expr) = 'RF_iter(' e.expr> ')++'; ("DEC-ITER" e.expr) = 'RF_iter(' e.expr> ')--'; }; $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: It is needed to check that s.pos and s.len // are in allowable bounds. // Set this bounds by options. 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 = '"'e.accum'"' ; //T/ { //T/ : e s.c e, //T/ = //T/ ' + rftype::Char::create_expr ("' e.accum '")' ; //T/ //' + Expr::create_seq (L"' e.accum '")' ; //T/ ' + rftype::Char::create_expr (L"' e.accum '")' ; //T/ }; e.expr : t.item e.rest, t.item : { (PAREN e.paren_expr) = ' + (' ') ()'; (REF t.name) = ' + ' ; // ' + Expr::create(' ')'; (STATIC e) = , ' + ' '*' ; (s.FUNC t.name), s.FUNC : \{ FUNC; "FUNC?"; TFUNC; } = ' + Expr::create_sym (' ')'; s.sym, { = ' + Expr::create<' '>("' s.sym '")'; = ' + Expr::create("' '")'; }; } :: 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 { (v.prefix) Vars /*empty*/ = 'RF_VOID'; ( ) Vars /*empty*/ = '/*void*/'; ( ) Vars (e.arg) = ; (e.prefix) Exprs /*empty*/ = '/*void*/'; (e.prefix) Exprs (e.arg) = e.arg>; (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.arg> e.comma); Ints = e.rest (e.cpp_args e.comma); }; } :: e.args (e.cpp_args), e.args : /*empty*/, (e.prefix) s.tag : { t Exprs = '(' e.cpp_args ')'; ( ) Vars = '(' e.cpp_args ')'; (v) Vars = '(' e.prefix e.cpp_args ';;)'; e = e.prefix e.cpp_args; }; }; Name_To_CPP s.decl_type (e.name) e.args = { e.name : "org" "refal" "plus" "wrappers" e.cont = ) ()>, >>; e.name : "refal" "plus" e.cont = { : e; ; }, ; :: e.namespace, , { e.name : e.namespace e.cont = ; ; }; }; QName_To_Cpp e.name = ; Open_Namespace e.name = ('namespace ' e.name ' {'); Close_Namespace e.name = ('}'); Namespace_Control e.qualifiers = { e.qualifiers : /*empty*/ = ; e.qualifiers : () = /*empty*/; e.qualifiers; } :: e.qualifiers, { : e.qualifiers; )> :: e.close_namespace, , e.close_namespace ; }; Trace_Enter e.name (e.args) = e.args 1 () $iter { e.args : t.arg e.rest = { \{ e.rest : v; ; } = 'printf("%2d: ", 's.n');'; 'printf(" : ");'; } :: e.num, e.rest (e.pr_args ('printf (" argument "); 'e.num' ('').writeln(stdout);')); } :: e.args s.n (e.pr_args), e.args : /*empty*/ = ('printf ("+ %5u: enter >>> 'e.name' <<<\\n", rfrt::stack->get_depth());') e.pr_args; Trace_Exit e.name (e.args) = e.args 1 () $iter { e.args : t.arg e.rest = { \{ e.rest : v; ; } = 'printf("%2d: ", 's.n');'; 'printf(" : ");'; } :: e.num, e.rest (e.pr_args ('printf (" result "); 'e.num' ('').to_Expr().writeln(stdout);')); } :: e.args s.n (e.pr_args), e.args : /*empty*/ = ('printf ("- %5u: exit >>> 'e.name' <<<\\n", rfrt::stack->get_depth());') e.pr_args; Trace_Fail e.name = ('printf ("- %5u: fail >>> 'e.name' <<<\\n", rfrt::stack->get_depth());'); Extract_Qualifiers t.name, { = t.name : (e.n), (()) e.n; ; };