namespace trans_crack int factor( Factor: indep::factor ) { if match Factor [`first_token_char] { send Out "data\[ts\]" } else if match Factor [tk_ident `[ expr `]] { send Out "[$Factor.tk_ident]\[ [expr(Factor.expr)] \] } else if match Factor [tk_ident `( expr `)] { send Out "[$Factor.tk_ident]( [expr(Factor.expr)] ) } elsif match Factor [`< type `> `( expr `)] { send Out "( [type(Factor.type)] ( [expr(Factor.expr)] ) ) } elsif match Factor [`( expr `)] { send Out "( [expr(Factor.expr)] ) } elsif match Factor ['true'] { send Out '1' } elsif match Factor ['false'] { send Out '0' } elsif match Factor [`buffer] { send Out "buffer" } elsif match Factor [`blen] { send Out "buffer.size" } else { send Out [$Factor] } } void type( Type: indep::type ) { switch Type case [`int] { send Out "int" } case [`bool] { send Out "int" } case [`char] { send Out "byte" } case [`ptr] { send Out "int } case [`byte] { send Out "byte" } } void abs_expr( Expr: indep::abs_expr ) { if ( Expr.Op ) { send Out "[abs_expr(Expr.E1)] [$Expr.Op] [abs_expr( Expr.E2 )]" } else { factor( Expr.factor ) } } void expr( Expr: indep::expr ) { AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) abs_expr( AbsExpr ) } void array_init( Size: int ) { while ( Size > 1 ) { send Out "0, " Size = Size - 1 } if ( Size > 0 ) { send Out "0" } } int var_decl( VarDecl: indep::var_decl ) { if VarDecl.opt_arr.expr { send Out "array\[[type( VarDecl.type )]\] [VarDecl.tk_ident] = " "\[ [array_init( atoi($VarDecl.opt_arr.expr) )] \]; } else { send Out "[type( VarDecl.type )] [VarDecl.tk_ident]; } } void opt_sub( OptSub: indep::opt_sub ) { if ( OptSub.expr ) send Out "\[[expr(OptSub.expr)]\]" } int expr_stmt( ExprStmt: indep::expr_stmt ) { if match ExprStmt [tk_ident opt_sub `= expr `;] { send Out "[$ExprStmt.tk_ident opt_sub(ExprStmt.opt_sub)] = [expr(ExprStmt.expr)]; } else if match ExprStmt [expr `;] { send Out "[expr(ExprStmt.expr)]; } } int if_stmt( IfStmt: indep::if_stmt ) { send Out "if ( [expr( IfStmt.expr )] ) "{ " [stmt_list( IfStmt._repeat_stmt )] "} if ( IfStmt.opt_else._repeat_stmt ) { send Out "else { " [stmt_list( IfStmt.opt_else._repeat_stmt )] "} } } int print_stmt( Stmt: indep::print_stmt ) { switch Stmt case [`print_int expr `;] { send Out "cout.format( [expr(Stmt.expr)] ); } case [`print_buf E1: expr `, E2: expr `;] { send Out "print!( \"{}\", buffer ); } case [`print_str expr `;] { send Out "cout.format( [expr( Stmt.expr )] ); } case [`print_token `;] { send Out "int len = uintz(te) - uintz(ts); "cout.write( Buffer(data + uintz(ts), len) ); } } void buf_stmt( BufStmt: indep::buf_stmt ) { switch BufStmt case [`buf_clear `( `) `;] { send Out " buffer = \"\"; } case [`buf_append `( `) `;] { send Out " buffer = buffer + fc; } } int ragel_stmt( Stmt: indep::ragel_stmt ) { send Out [$Stmt] } int stmt( Stmt: indep::stmt ) { switch Stmt case [var_decl] var_decl( Stmt.var_decl ) case [expr_stmt] expr_stmt( Stmt.expr_stmt ) case [if_stmt] if_stmt( Stmt.if_stmt ) case [print_stmt] print_stmt( Stmt.print_stmt ) case [buf_stmt] buf_stmt( Stmt.buf_stmt ) case [ragel_stmt] ragel_stmt( Stmt.ragel_stmt ) } void stmt_list( StmtList: indep::stmt* ) { for Stmt: indep::stmt in repeat( StmtList ) stmt( Stmt ) } int action_block( ActionBlock: indep::action_block ) { Out = new parser() if match ActionBlock [`{ stmt* `}] { send Out "{[stmt_list( ActionBlock._repeat_stmt )]} } else if match ActionBlock [`{ expr `}] { send Out "{[expr( ActionBlock.expr )]} } send Out [] eos } void crack( Output: stream ) { # Translate action blocks. Section: indep::section = RagelTree.section for Action: ragel::action_block in Section { # Reparse as lang-independent code. parse IndepActionBlock: indep::action_block[$Action] if ( !IndepActionBlock ) { print( error, '\n', Action ) exit(1) } action_block( IndepActionBlock ) # Reparse back to ragel action block. Action = parse ragel::action_block[$Out->tree] if ( !Action ) { print( error, '\n' ) exit(1) } } send Output "// "// @LANG: crack "// @GENERATED: true if ProhibitGenflags { send Output "// @PROHIBIT_GENFLAGS:[ProhibitGenflags] } send Output "// " "import crack.io cout; "import crack.lang Buffer; " Init: indep::stmt* = RagelTree.Init for Stmt: indep::stmt in Init { if match Stmt [Decl: var_decl] { Out = new parser() var_decl( Decl ) send Out [] eos send Output [Out->tree] } } send Output " "[@Section] " "%% write data; " "void m( String s ) "{ " byteptr data = s.buffer; " int p = 0; " int pe = s.size; " int cs; " String buffer; if NeedsEof { send Output " int eof = pe; } for Stmt: indep::stmt in Init { if match Stmt [ExprStmt: expr_stmt] { Out = new parser() expr_stmt( ExprStmt ) send Out [] eos send Output [Out->tree] } } send Output " " %% write init; " %% write exec; " " if ( cs >= [MachineName.word]_first_final ) { " cout `ACCEPT\\n`; " } " else { " cout `FAIL\\n`; " } "} send Output ~ ~void main() ~{ for InputString: indep::input_string in RagelTree { send Output " m( [^InputString] ); } send Output ~} ~ ~main(); } end