namespace trans_rust int factor( Factor: indep::factor ) { if match Factor [`first_token_char] { send Out "data\[ts as usize\]" } 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 "( ( [expr(Factor.expr)] ) as [type(Factor.type)] ) } 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.len()" } else { send Out [$Factor] } } void type( Type: indep::type ) { switch Type case [`int] { send Out "i32" } case [`bool] { send Out "i8" } case [`char] { send Out "u8" } case [`ptr] { send Out "i32 } case [`byte] { send Out "unsigned char" } } 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 "static mut [VarDecl.tk_ident] : " "\[ [type( VarDecl.type )] ; [expr( VarDecl.opt_arr.expr )]\] = " "\[ [array_init( atoi($VarDecl.opt_arr.expr) )] \]; } else { send Out "static mut [VarDecl.tk_ident] : [type( VarDecl.type )] = 0; } } 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 "print!( \"{}\", [expr(Stmt.expr)] ); } case [`print_buf E1: expr `, E2: expr `;] { send Out "print!( \"{}\", buffer ); } case [`print_str expr `;] { send Out "print!( \"{}\", [expr( Stmt.expr )] ); } case [`print_token `;] { send Out "let s = match std::str::from_utf8(&data\[ts as usize .. te as usize\]) { " Ok(v) => v, " Err(e) => panic!(\"Invalid UTF-8 sequence: {}\", e), " }; "print!( \"{}\", s ); } } void buf_stmt( BufStmt: indep::buf_stmt ) { switch BufStmt case [`buf_clear `( `) `;] { send Out " buffer = String::new(); } case [`buf_append `( `) `;] { send Out " buffer.push( ( fc ) as char ); } } 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 rust( 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: rust "// @GENERATED: true if ProhibitGenflags { send Output "// @PROHIBIT_GENFLAGS:[ProhibitGenflags] } send Output "// " 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; " "unsafe fn m( s: String ) "{ " let data: &\[u8\] = s.as_bytes(); " let mut p:i32 = 0; " let mut pe:i32 = s.len() as i32; " let mut eof:i32 = s.len() as i32; " let mut cs: i32 = 0; " let mut buffer = String::new(); 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 ) { " println!( \"ACCEPT\" ); " } " else { " println!( \"FAIL\" ); " } "} send Output ~ ~fn main() ~{ for InputString: indep::input_string in RagelTree { send Output " unsafe { m( [^InputString].to_string() ); } } send Output ~} ~ } end