$use Apply Arithm Box Class Compare Convert CppMangle List StdIO Table; $use "rfpc"; $use "rfp_helper"; $use "rfp_compile"; $box Int; $box Module-Name; $box Current-Namespace; $box Current-Func; $box Entry; $box Entry-Name; $box Const-Exprs; $box Const-Local; $box Param; $func ASAIL-To-TPP e.body = e.cpp-code; // $func Namespace-Control e.qualifiers = e.namespace-control; $func Expr-To-TPP (e.ASAIL-Expr-init) e.ASAIL-Expr-rest = e.ASAIL-Expr; $func Expr-Ref-To-TPP e.ASAIL-Expr-Ref = e.CPP-Expr-Ref; $func Expr-Int-To-TPP e.ASAIL-Expr-Int = e.CPP-Expr-Int; $func Step-To-TPP e.step-operators = e.cpp-step-operators; $func Const-Expr-To-TPP e.ASAIL-const-expr = e.CPP-const-expr; $func Args-To-TPP (e.prefix) s.Arg-Res-Tag e.ASAIL-Args = e.CPP-Args; $func Symbol-To-TPP s.RFP-Symbol = e.CPP-String; $func Name-To-TPP t.name = e.CPP-Name; $func Cond-To-TPP e.cond = e.CPP-Cond; $func Infix-To-TPP s.func-for-converting-args-to-cpp s.op e.args = e.cpp-expr; $func Op-Arg-To-TPP s.op = s.func-for-converting-args-to-cpp; $func TPP-Param e.cpp-param = e.tpp-param; $func Func-Const (e.const) (e.local-const) = e.local; $func Add s.box e.const = ; $func Term-Ref-To-TPP e = e; $func Punct e.param = e.text; $func Func-Prototype (e.type) e.param = e.res; RFP-ASAIL-To-TPP (e.ModuleName) e.asail = { >; ; }, , // , , , , { : v.cpp, // { // : v = ('}');; // close last namespace // } :: e.close-namespace, // , // { // : v.name = ('rfrt::Entry rf_entry (' v.name ');');; // } :: e.entry, // { // : v.c-exprs = // (/*e.init-consts*/) $iter { // e.c-exprs : (e.cpp-name (e.value)) e.rest = // (e.init-consts (e.cpp-name ' = ' e.value ';')) e.rest; // } :: (e.init-consts) e.c-exprs // , // e.c-exprs : /*empty*/ = // > // ('static void init_ ()\n{' (e.init-consts) '}') // ('static AtStart init_registrator_ (&init_);') // ('}') // ;; // } :: e.init, // ('namespace refal\n{') // ('using namespace rfrt;') v.cpp // e.close-namespace // e.init // e.entry // ('}') ;; }; ASAIL-To-TPP e.asail, { e.asail : t.item e.end = t.item : { (s.tag t.name (e.args) (e.ress) e.body), s.tag : \{ FUNC = ('tfun int') /*empty*/; FUNC? = ('boolean') ('return true;'); TFUNC = ('tfun int') /*empty*/; } :: (e.return-type) e.return, , { : t.name = >;; }, :: (e.qualifiers) e.name, > :: e.tval, > :: e.tout, { e.tval : /*empty*/ = e.tout; e.tout : /*empty*/ = e.tval; e.tval ',' e.tout; } :: e.tparam, , :: e.body, ) ()> :: e.const, { () e.const $iter { e.result : (e.cpp-name (e.value)) e.rest = (e.init-consts ('tval Expr ' e.cpp-name ' = ' e.value ';')) e.rest; } :: (e.init-consts) e.result, e.result : /*empty*/ = e.init-consts; } :: e.const, ('tfun int ' '( 'e.tparam ')' ('{' ('tval Expr empty;') (e.const) (e.body) '}')); (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) = ('RF_TRAP') ('{' () '}'); (CATCH-ERROR e.body) = ('RF_WITH') ('{' (('RF_CLEANUP;') ) '}'); RETURN = ('return true;'); RETFAIL = ('RF_RETFAIL;'); FATAL = // : (e.name), ('RF_FUNC_ERROR (unexpected_fail);'); (LSPLIT e.expr (e.min) t.var1 t.var2) = ('lsplit (' ',' ', (Expr&) ' ',(Expr&) ' ');'); (RSPLIT e.expr (e.min) t.var1 t.var2) = ('rsplit (' ',' ', (Expr&) ' ',(Expr&)' ');'); (ASSIGN t.var e.expr) = ( ' = ' ';'); (DECL s.type t.var) = ('tval Expr ' ';'); (INT t.var e.expr) = ('tval Expr ' ' = ' ';'); (EXPR t.var e.expr) = ('tval Expr ' ' (' ');'); (DEREF t.var e.expr (e.pos)) = ('tval Expr ' ' (' ', ' ');'); (SUBEXPR t.var e.expr (e.pos) (e.len)) = ('tval Expr ' ' (' ', ' ', ' ');'); (DROP t.var) = ('((Expr&)' ').drop ();'); (CONTINUE t.label) = ('goto ' ';'); (BREAK t.label) = ('goto ' ';'); (ERROR e.expr) = ('RF_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.cpp-name, ))>; // // (e.linkage 'tval Expr ' e.cpp-name ';'); (OBJ s.linkage s.tag t.name) = { s.linkage : LOCAL = 'static ';; } :: e.linkage, : s1 e2, :: (e.qualifiers) e.name, :: e.cpp-name, { s.tag : BOX = >(L"'e.name'")'))>; '>(L"'e.name'")'))>; }, // (e.linkage 'Expr ' e.cpp-name ';'); (DECL-OBJ t.name) = :: (e.qualifiers) e.name, // ('extern Expr ' ';'); (DECL-FUNC t.fname) = :: (e.qualifiers) e.name, , : e.expr (e.Fin)(e.Fout), ::e.fin, ::e.fout, :: e.param, // ('tfun int ' ' (' e.param ');'); /* * s.call can be CALL or TAILCALL */ (s.call t.name (e.exprs) (e.ress)) = :: e.tval, :: e.tout, { e.tval : /*empty*/ = e.tout; e.tout : /*empty*/ = e.tval; e.tval ',' e.tout; } :: e.tparam, ( '(' e.tparam ');'); } :: e.cpp-item, e.cpp-item ; /*empty*/; }; /* * Determine type of e.expr - int or Refal. */ Expr-To-TPP (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 = ; }; Expr-Ref-To-TPP { /*empty*/ = /*empty*/; term = ; expr = ' concat(' > ')'; }; Term-Ref-To-TPP { (PAREN e.expr) = 'tval Expr ' ' ()'; (EXPR e.expr) = ' tval Expr(' ')'; (DEREF e.expr (e.pos)) = 'tval Expr(' ', ' ')'; (SUBEXPR e.expr (e.pos) (e.len)) = 'tval Expr(' ', ' ', ' ')'; (REF t.name) = ; ERROR-EXPR = 'err'; (s.var-tag t.name) = { s.var-tag : STATIC = :: e.var, >, e.var; ; }; }; Expr-Int-To-TPP { /*empty*/ = /*empty*/; s.ObjectSymbol = { = s.ObjectSymbol; $error ("Illegal type int-symbol: " s.ObjectSymbol); }; (LENGTH e.expr) = '((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) = { s.var-tag : STATIC = :: e.var, >, e.var; ; }; // (s.var-tag t.name) = ; expr = '(' > ')'; }; Cond-To-TPP { /*empty*/ = /*empty*/; (CALL t.name (e.exprs) (e.ress)) = // e.exprs () $iter { // e.tmp : (exp) e.r, // e.r // (e.pr-args 'printf (" "); (' // ').writeln(stdout); '); // } :: e.tmp (e.pr-args), // e.tmp : /*empty*/ = // e.ress () $iter { // e.tmp : t.var e.r, { // : '(VAR(res' e = // e.r // (e.pr-ress 'printf (" res-var\\n");'); // e.r // (e.pr-ress 'printf (" "); ' // '.writeln(stdout); '); // }; // } :: e.tmp (e.pr-ress), // e.tmp : /*empty*/ = // '({ printf ("<<<<< ' '\\n"); ' e.pr-args // 'bool res = ' :: e.tval, :: e.tout, { e.tval : /*empty*/ = e.tout; e.tout : /*empty*/ = e.tval; e.tval ',' e.tout; } :: e.tparam, '(' e.tparam ')' ; // '; printf (">>>>> ' '\\n"); ' // 'if (res) { 'e.pr-ress' } else printf (" failed\\n"); res; })' // ; (SYMBOL? e.expr (e.pos)) = '((Expr&)' ').symbol_at (' ')'; (FLAT-SUBEXPR? e.expr (e.pos) (e.len)) = '((Expr&)' ').flat_at (' ', ' ')'; (CHECK-ITER e.expr) = 'iter(' ')'; (EQ e.expr1 (e.expr2) (e.pos)) = '((Expr&)' ').eq (' ', ' ')'; (TERM-EQ e.expr1 (e.expr2) (e.pos)) = '((Expr&)' ').term_eq (' ', ' ')'; (NOT e.cond) = '!' ; (INFIX s.op e.args) = '(' s.op e.args> ')'; expr = '(' > ')'; }; Infix-To-TPP s.arg2cpp s.op e.args, { e.args : (e.arg) e.rest = :: e.arg, :: e.rest, { e.arg : v, e.rest : v = { s.op : "+" = ' concat('e.arg ','e.rest')'; e.arg ' ' s.op ' ' e.rest; }; e.arg e.rest; };; }; Op-Arg-To-TPP s.op, { s.op : \{ "&&"; "||"; } = &Cond-To-TPP; s.op : \{ "<"; ">"; "<="; ">="; "=="; "!="; "+"; "-"; "%"; "*"; "/"; } = &Expr-Int-To-TPP; }; Step-To-TPP { /*empty*/ = /*empty*/; (INC-ITER e.expr) = 'iter(' ')++'; (DEC-ITER e.expr) = 'iter(' ')--'; }; $func Const-Expr-Aux e.expr = e.cpp-expr; Const-Expr-To-TPP { /*empty*/ = 'empty'; (SUBEXPR t.name s.pos s.len) = 'tval 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) = ' + ' ; // ' + Expr::create(' ')'; (STATIC e) = :: e.const, >, ' + ' e.const; (FUNC t.name) = ' + Expr::create_sym (' ')'; s.sym, { = ' + Expr_create_' '("' s.sym '")'; = ' + Expr_create_Word("' '")'; }; } :: e.cpp-item = e.cpp-item ; = /*empty*/; }; Symbol-To-TPP 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-TPP { (v.prefix) Vars /*empty*/ = 'RF_VOID' ; ( ) Vars /*empty*/ = /*empty*/ ; ( ) Vars (e.arg) = ; (e.prefix) Exprs /*empty*/ = /*empty*/ ; (e.prefix) Exprs (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.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-TPP 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{'); }; */ TPP-Param { 'RF_VOID' = /*empty*/; '(RF_ARG' ex ',' ey = 'tval Expr ' ex ; '(RF_ARG' ex ';;)' = 'tval Expr ' ex; '(RF_Res' ex ',' ey = 'tout Expr ' ex ; '(RF_Res' ex ';;)' = 'tout Expr ' ex; }; Add s.box (e.const) e.expr = { e.expr : e1 (e.const) e2 = /*empty*/; ; }; Func-Const (e.all-const) (e.local-const) = ( ) (e.all-const) (e.local-const) $iter { e.local : (e.name) e.rest, e.all : e1 (e.name(e.value)) e2 = (e.res (e.name(e.value))) (e1 e2) (e.rest); } :: (e.res) (e.all) (e.local), e.local : /*empty*/ = e.res; Punct { /*empty*/ = /*empty*/; (e1) = e1; (e1) e2 = e1 ',' ; }; Func-Prototype (e.type) e.param = () e.param $iter { e.list : (e1) e2 = : s.numb, >, (e.init (e.type' Expr var_')) e2; } :: (e.init) e.list, e.list : /*empty*/ = e.init;