summaryrefslogtreecommitdiff
path: root/test/trans.d/trans-c.lm
diff options
context:
space:
mode:
Diffstat (limited to 'test/trans.d/trans-c.lm')
-rw-r--r--test/trans.d/trans-c.lm346
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]
+}