diff options
Diffstat (limited to 'test/trans.d/trans-c.lm')
-rw-r--r-- | test/trans.d/trans-c.lm | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/test/trans.d/trans-c.lm b/test/trans.d/trans-c.lm new file mode 100644 index 00000000..563e1eec --- /dev/null +++ b/test/trans.d/trans-c.lm @@ -0,0 +1,346 @@ +int rw_c_factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "ts\[0\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [rw_c_expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [rw_c_expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "( [rw_c_type(Factor.type)] ) ( [rw_c_expr(Factor.expr)] ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [rw_c_expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + else + { + send Out [$Factor] + } +} + +void rw_c_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "char" + } + elsif match Type [`ptr] + { + send Out "char *" + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_c_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_c_abs_expr(Expr.E1)] [$Expr.Op] [rw_c_abs_expr( Expr.E2 )]" + } + else { + rw_c_factor( Expr.factor ) + } +} + +void rw_c_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_c_abs_expr( AbsExpr ) +} + +void rw_c_opt_array( OptArr: indep::opt_arr ) +{ + if OptArr.expr { + send Out "\[[rw_c_expr( OptArr.expr )]\]" + } +} + +int rw_c_var_decl( VarDecl: indep::var_decl ) +{ + send Out + "[rw_c_type( VarDecl.type )] [$VarDecl.tk_ident] [rw_c_opt_array(VarDecl.opt_arr)]; +} + +void rw_c_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[rw_c_expr(OptSub.expr)]\]" +} + +int rw_c_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident rw_c_opt_sub(ExprStmt.opt_sub)] = [rw_c_expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_c_expr(ExprStmt.expr)]; + } +} + +int rw_c_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [rw_c_expr( IfStmt.expr )] ) + "{ + " [rw_c_stmt_list( IfStmt._repeat_stmt )] + "} + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else { + " [rw_c_stmt_list( IfStmt.opt_else._repeat_stmt )] + "} + } +} + +int rw_c_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "printf( \"%d\", [rw_c_expr(Stmt.expr)] ); + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "fwrite( [rw_c_expr(E1)], 1, [rw_c_expr(E2)], stdout );" + } + else if match Stmt [`print_str expr `;] + { + send Out + "printf( \"%s\", [rw_c_expr( Stmt.expr )] ); + } + else if match Stmt [`print_token `;] + { + send Out + "fwrite ( ts , 1 , te - ts , stdout );" + } +} + +int rw_c_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +void rw_c_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " blen = 0; + } + case [`buf_append `( `) `;] { + send Out + " buffer\[blen++\] = *p; + " buffer\[blen\] = 0; + } +} + + +int rw_c_stmt( Stmt: indep::stmt ) +{ + switch Stmt + case [var_decl] + rw_c_var_decl( Stmt.var_decl ) + case [expr_stmt] + rw_c_expr_stmt( Stmt.expr_stmt ) + case [if_stmt] + rw_c_if_stmt( Stmt.if_stmt ) + case [print_stmt] + rw_c_print_stmt( Stmt.print_stmt ) + case [buf_stmt] + rw_c_buf_stmt( Stmt.buf_stmt ) + case [ragel_stmt] + rw_c_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_c_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_c_stmt( Stmt ) +} + +out_code::lines rw_c_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser<out_code::lines>() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_c_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_c_expr( ActionBlock.expr )]} + } + send Out [] eos + return Out->tree +} + +void rw_c( Output: stream ) +{ + send Output + "/* + " * @LANG: c + " * @GENERATED: true + + if ProhibitGenflags { + send Output + " * @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + " */ + " + "#include <string.h> + "#include <stdio.h> + " + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser<out_code::lines>() + rw_c_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + 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) + } + + Lines: out_code::lines = + rw_c_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[Lines] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + send Output + " + "[@Section] + " + "%% write data; + "int cs; + "int blen; + "char buffer\[1024\]; + " + "void init() + "{ + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser<out_code::lines>() + rw_c_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + "} + " + "void exec( char *data, int len ) + "{ + " char *p = data; + " char *pe = data + len; + + if NeedsEof { + send Output + " char *eof = pe; + } + + send Output + " %% write exec; + "} + " + "void finish( ) + "{ + " if ( cs >= [$MachineName.word]_first_final ) + " printf( \"ACCEPT\\n\" ); + " else + " printf( \"FAIL\\n\" ); + "} + " + + send Output + "char *inp\[\] = { + + NR: int = 0 + for InputString: indep::input_string in RagelTree { + send Output + [^InputString ",\n"] + NR = NR + 1 + } + + send Output + "}; + " + + send Output + "int inplen = [NR]; + " + + send Output + "int main( ) + "{ + " int i; + " for ( i = 0; i < inplen; i++ ) { + " init(); + " exec( inp\[i\], strlen(inp\[i\]) ); + " finish(); + " } + " return 0; + "} + " + +# send Output +# "##### OUTPUT ##### +# +# for OutputLine: indep::output_line in RagelTree +# send Output [OutputLine] +} |