summaryrefslogtreecommitdiff
path: root/test/trans.d
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2019-09-09 10:19:58 -0600
committerAdrian Thurston <thurston@colm.net>2019-09-09 10:19:58 -0600
commitfff52cd5a567ec541cd487b9fee2d89bf9b6f6eb (patch)
tree046a3f0f457343f7c99bf096863daf023a085051 /test/trans.d
parent2d8e9c3f5c0417d6237c945c50f92bf8d28b32d5 (diff)
downloadcolm-fff52cd5a567ec541cd487b9fee2d89bf9b6f6eb.tar.gz
base (aapl, colm, ragel) test cases building
Diffstat (limited to 'test/trans.d')
-rw-r--r--test/trans.d/.gitignore4
-rw-r--r--test/trans.d/Makefile30
-rw-r--r--test/trans.d/actparams.cc63
-rw-r--r--test/trans.d/case/any1.rl17
-rw-r--r--test/trans.d/case/any1_asm.rl118
-rw-r--r--test/trans.d/case/any1_c.rl62
-rw-r--r--test/trans.d/case/any1_crack.rl47
-rw-r--r--test/trans.d/case/any1_cs.rl67
-rw-r--r--test/trans.d/case/any1_d.rl66
-rw-r--r--test/trans.d/case/any1_go.rl52
-rw-r--r--test/trans.d/case/any1_java.rl63
-rw-r--r--test/trans.d/case/any1_julia.rl37
-rw-r--r--test/trans.d/case/any1_ocaml.rl39
-rw-r--r--test/trans.d/case/any1_ruby.rl45
-rw-r--r--test/trans.d/case/any1_rust.rl44
-rw-r--r--test/trans.d/case/atoi1.rl67
-rw-r--r--test/trans.d/case/atoi1_asm.rl246
-rw-r--r--test/trans.d/case/atoi1_c.rl96
-rw-r--r--test/trans.d/case/atoi1_crack.rl81
-rw-r--r--test/trans.d/case/atoi1_cs.rl99
-rw-r--r--test/trans.d/case/atoi1_d.rl99
-rw-r--r--test/trans.d/case/atoi1_go.rl83
-rw-r--r--test/trans.d/case/atoi1_java.rl97
-rw-r--r--test/trans.d/case/atoi1_julia.rl70
-rw-r--r--test/trans.d/case/atoi1_ocaml.rl74
-rw-r--r--test/trans.d/case/atoi1_ruby.rl78
-rw-r--r--test/trans.d/case/atoi1_rust.rl78
-rw-r--r--test/trans.d/case/atoi2.rl81
-rw-r--r--test/trans.d/case/atoi2_asm.rl261
-rw-r--r--test/trans.d/case/atoi2_c.rl111
-rw-r--r--test/trans.d/case/atoi2_crack.rl96
-rw-r--r--test/trans.d/case/atoi2_cs.rl114
-rw-r--r--test/trans.d/case/atoi2_d.rl114
-rw-r--r--test/trans.d/case/atoi2_go.rl98
-rw-r--r--test/trans.d/case/atoi2_java.rl112
-rw-r--r--test/trans.d/case/atoi2_julia.rl85
-rw-r--r--test/trans.d/case/atoi2_ocaml.rl89
-rw-r--r--test/trans.d/case/atoi2_ruby.rl93
-rw-r--r--test/trans.d/case/atoi2_rust.rl93
-rw-r--r--test/trans.d/case/call4.rl39
-rw-r--r--test/trans.d/case/call4_asm.rl180
-rw-r--r--test/trans.d/case/call4_c.rl76
-rw-r--r--test/trans.d/case/call4_crack.rl61
-rw-r--r--test/trans.d/case/call4_cs.rl79
-rw-r--r--test/trans.d/case/call4_d.rl78
-rw-r--r--test/trans.d/case/call4_go.rl70
-rw-r--r--test/trans.d/case/call4_java.rl77
-rw-r--r--test/trans.d/case/call4_julia.rl51
-rw-r--r--test/trans.d/case/call4_rust.rl58
-rw-r--r--test/trans.d/case/caseindep.rl54
-rw-r--r--test/trans.d/case/caseindep_asm.rl170
-rw-r--r--test/trans.d/case/caseindep_c.rl84
-rw-r--r--test/trans.d/case/caseindep_crack.rl69
-rw-r--r--test/trans.d/case/caseindep_cs.rl89
-rw-r--r--test/trans.d/case/caseindep_d.rl88
-rw-r--r--test/trans.d/case/caseindep_go.rl74
-rw-r--r--test/trans.d/case/caseindep_java.rl85
-rw-r--r--test/trans.d/case/caseindep_julia.rl59
-rw-r--r--test/trans.d/case/caseindep_ocaml.rl61
-rw-r--r--test/trans.d/case/caseindep_ruby.rl67
-rw-r--r--test/trans.d/case/caseindep_rust.rl66
-rw-r--r--test/trans.d/case/clang4.rl187
-rw-r--r--test/trans.d/case/clang4_asm.rl603
-rw-r--r--test/trans.d/case/clang4_c.rl202
-rw-r--r--test/trans.d/case/clang4_crack.rl186
-rw-r--r--test/trans.d/case/clang4_cs.rl169
-rw-r--r--test/trans.d/case/clang4_d.rl176
-rw-r--r--test/trans.d/case/clang4_go.rl151
-rw-r--r--test/trans.d/case/clang4_java.rl203
-rw-r--r--test/trans.d/case/clang4_julia.rl175
-rw-r--r--test/trans.d/case/clang4_ocaml.rl183
-rw-r--r--test/trans.d/case/clang4_ruby.rl184
-rw-r--r--test/trans.d/case/clang4_rust.rl182
-rw-r--r--test/trans.d/case/cond1.rl84
-rw-r--r--test/trans.d/case/cond1_asm.rl319
-rw-r--r--test/trans.d/case/cond1_c.rl121
-rw-r--r--test/trans.d/case/cond1_crack.rl106
-rw-r--r--test/trans.d/case/cond1_cs.rl123
-rw-r--r--test/trans.d/case/cond1_d.rl122
-rw-r--r--test/trans.d/case/cond1_go.rl103
-rw-r--r--test/trans.d/case/cond1_java.rl122
-rw-r--r--test/trans.d/case/cond1_julia.rl90
-rw-r--r--test/trans.d/case/cond1_ocaml.rl104
-rw-r--r--test/trans.d/case/cond1_ruby.rl98
-rw-r--r--test/trans.d/case/cond1_rust.rl103
-rw-r--r--test/trans.d/case/cond7.rl80
-rw-r--r--test/trans.d/case/cond7_asm.rl234
-rw-r--r--test/trans.d/case/cond7_c.rl87
-rw-r--r--test/trans.d/case/cond7_crack.rl72
-rw-r--r--test/trans.d/case/cond7_cs.rl86
-rw-r--r--test/trans.d/case/cond7_d.rl87
-rw-r--r--test/trans.d/case/cond7_go.rl71
-rw-r--r--test/trans.d/case/cond7_java.rl88
-rw-r--r--test/trans.d/case/cond7_julia.rl62
-rw-r--r--test/trans.d/case/cond7_ocaml.rl64
-rw-r--r--test/trans.d/case/cond7_ruby.rl70
-rw-r--r--test/trans.d/case/cond7_rust.rl69
-rw-r--r--test/trans.d/case/cppscan6.rl359
-rw-r--r--test/trans.d/case/cppscan6_asm.rl1908
-rw-r--r--test/trans.d/case/cppscan6_c.rl278
-rw-r--r--test/trans.d/case/cppscan6_crack.rl323
-rw-r--r--test/trans.d/case/cppscan6_cs.rl195
-rw-r--r--test/trans.d/case/cppscan6_d.rl195
-rw-r--r--test/trans.d/case/cppscan6_go.rl152
-rw-r--r--test/trans.d/case/cppscan6_java.rl339
-rw-r--r--test/trans.d/case/cppscan6_julia.rl281
-rw-r--r--test/trans.d/case/cppscan6_ocaml.rl255
-rw-r--r--test/trans.d/case/cppscan6_ruby.rl318
-rw-r--r--test/trans.d/case/cppscan6_rust.rl406
-rw-r--r--test/trans.d/case/curs1.rl34
-rw-r--r--test/trans.d/case/curs1_asm.rl171
-rw-r--r--test/trans.d/case/curs1_c.rl73
-rw-r--r--test/trans.d/case/curs1_crack.rl58
-rw-r--r--test/trans.d/case/curs1_cs.rl76
-rw-r--r--test/trans.d/case/curs1_d.rl75
-rw-r--r--test/trans.d/case/curs1_go.rl67
-rw-r--r--test/trans.d/case/curs1_java.rl74
-rw-r--r--test/trans.d/case/curs1_julia.rl48
-rw-r--r--test/trans.d/case/curs1_ocaml.rl52
-rw-r--r--test/trans.d/case/curs1_ruby.rl56
-rw-r--r--test/trans.d/case/curs1_rust.rl55
-rw-r--r--test/trans.d/case/empty1.rl15
-rw-r--r--test/trans.d/case/empty1_asm.rl115
-rw-r--r--test/trans.d/case/empty1_c.rl61
-rw-r--r--test/trans.d/case/empty1_crack.rl46
-rw-r--r--test/trans.d/case/empty1_cs.rl66
-rw-r--r--test/trans.d/case/empty1_d.rl65
-rw-r--r--test/trans.d/case/empty1_go.rl51
-rw-r--r--test/trans.d/case/empty1_java.rl62
-rw-r--r--test/trans.d/case/empty1_julia.rl36
-rw-r--r--test/trans.d/case/empty1_ocaml.rl38
-rw-r--r--test/trans.d/case/empty1_ruby.rl44
-rw-r--r--test/trans.d/case/empty1_rust.rl43
-rw-r--r--test/trans.d/case/eofact.rl51
-rw-r--r--test/trans.d/case/eofact_asm.rl196
-rw-r--r--test/trans.d/case/eofact_c.rl84
-rw-r--r--test/trans.d/case/eofact_crack.rl69
-rw-r--r--test/trans.d/case/eofact_cs.rl84
-rw-r--r--test/trans.d/case/eofact_d.rl84
-rw-r--r--test/trans.d/case/eofact_go.rl70
-rw-r--r--test/trans.d/case/eofact_java.rl85
-rw-r--r--test/trans.d/case/eofact_julia.rl58
-rw-r--r--test/trans.d/case/eofact_ocaml.rl61
-rw-r--r--test/trans.d/case/eofact_ruby.rl66
-rw-r--r--test/trans.d/case/eofact_rust.rl65
-rw-r--r--test/trans.d/case/erract2.rl90
-rw-r--r--test/trans.d/case/erract2_asm.rl259
-rw-r--r--test/trans.d/case/erract2_c.rl95
-rw-r--r--test/trans.d/case/erract2_crack.rl80
-rw-r--r--test/trans.d/case/erract2_cs.rl91
-rw-r--r--test/trans.d/case/erract2_d.rl91
-rw-r--r--test/trans.d/case/erract2_go.rl77
-rw-r--r--test/trans.d/case/erract2_java.rl96
-rw-r--r--test/trans.d/case/erract2_julia.rl69
-rw-r--r--test/trans.d/case/erract2_ocaml.rl72
-rw-r--r--test/trans.d/case/erract2_ruby.rl77
-rw-r--r--test/trans.d/case/erract2_rust.rl76
-rw-r--r--test/trans.d/case/goto1.rl37
-rw-r--r--test/trans.d/case/goto1_asm.rl187
-rw-r--r--test/trans.d/case/goto1_c.rl75
-rw-r--r--test/trans.d/case/goto1_crack.rl60
-rw-r--r--test/trans.d/case/goto1_cs.rl78
-rw-r--r--test/trans.d/case/goto1_d.rl77
-rw-r--r--test/trans.d/case/goto1_go.rl69
-rw-r--r--test/trans.d/case/goto1_java.rl76
-rw-r--r--test/trans.d/case/goto1_julia.rl50
-rw-r--r--test/trans.d/case/goto1_rust.rl57
-rw-r--r--test/trans.d/case/gotocallret1.rl117
-rw-r--r--test/trans.d/case/gotocallret1_asm.rl280
-rw-r--r--test/trans.d/case/gotocallret1_c.rl122
-rw-r--r--test/trans.d/case/gotocallret1_crack.rl107
-rw-r--r--test/trans.d/case/gotocallret1_cs.rl123
-rw-r--r--test/trans.d/case/gotocallret1_d.rl123
-rw-r--r--test/trans.d/case/gotocallret1_go.rl116
-rw-r--r--test/trans.d/case/gotocallret1_java.rl123
-rw-r--r--test/trans.d/case/gotocallret1_julia.rl94
-rw-r--r--test/trans.d/case/gotocallret1_rust.rl103
-rw-r--r--test/trans.d/case/gotocallret2.rl78
-rw-r--r--test/trans.d/case/gotocallret2_asm.rl484
-rw-r--r--test/trans.d/case/gotocallret2_c.rl135
-rw-r--r--test/trans.d/case/gotocallret2_crack.rl122
-rw-r--r--test/trans.d/case/gotocallret2_cs.rl123
-rw-r--r--test/trans.d/case/gotocallret2_d.rl123
-rw-r--r--test/trans.d/case/gotocallret2_go.rl122
-rw-r--r--test/trans.d/case/gotocallret2_java.rl138
-rw-r--r--test/trans.d/case/gotocallret2_julia.rl106
-rw-r--r--test/trans.d/case/gotocallret2_rust.rl118
-rw-r--r--test/trans.d/case/gotocallret3.rl121
-rw-r--r--test/trans.d/case/gotocallret3_asm.rl292
-rw-r--r--test/trans.d/case/gotocallret3_c.rl123
-rw-r--r--test/trans.d/case/gotocallret3_crack.rl108
-rw-r--r--test/trans.d/case/gotocallret3_cs.rl123
-rw-r--r--test/trans.d/case/gotocallret3_d.rl123
-rw-r--r--test/trans.d/case/gotocallret3_go.rl116
-rw-r--r--test/trans.d/case/gotocallret3_java.rl124
-rw-r--r--test/trans.d/case/gotocallret3_julia.rl95
-rw-r--r--test/trans.d/case/gotocallret3_ocaml.rl104
-rw-r--r--test/trans.d/case/gotocallret3_ruby.rl103
-rw-r--r--test/trans.d/case/gotocallret3_rust.rl104
-rw-r--r--test/trans.d/case/ncall1.rl38
-rw-r--r--test/trans.d/case/ncall1_asm.rl180
-rw-r--r--test/trans.d/case/ncall1_c.rl76
-rw-r--r--test/trans.d/case/ncall1_crack.rl61
-rw-r--r--test/trans.d/case/ncall1_cs.rl79
-rw-r--r--test/trans.d/case/ncall1_d.rl78
-rw-r--r--test/trans.d/case/ncall1_go.rl70
-rw-r--r--test/trans.d/case/ncall1_java.rl77
-rw-r--r--test/trans.d/case/ncall1_julia.rl51
-rw-r--r--test/trans.d/case/ncall1_ocaml.rl57
-rw-r--r--test/trans.d/case/ncall1_ruby.rl59
-rw-r--r--test/trans.d/case/ncall1_rust.rl58
-rw-r--r--test/trans.d/case/next1.rl36
-rw-r--r--test/trans.d/case/next1_asm.rl187
-rw-r--r--test/trans.d/case/next1_c.rl75
-rw-r--r--test/trans.d/case/next1_crack.rl60
-rw-r--r--test/trans.d/case/next1_cs.rl78
-rw-r--r--test/trans.d/case/next1_d.rl77
-rw-r--r--test/trans.d/case/next1_go.rl69
-rw-r--r--test/trans.d/case/next1_java.rl76
-rw-r--r--test/trans.d/case/next1_julia.rl50
-rw-r--r--test/trans.d/case/next1_ocaml.rl56
-rw-r--r--test/trans.d/case/next1_ruby.rl58
-rw-r--r--test/trans.d/case/next1_rust.rl57
-rw-r--r--test/trans.d/case/next2.rl64
-rw-r--r--test/trans.d/case/next2_asm.rl256
-rw-r--r--test/trans.d/case/next2_c.rl94
-rw-r--r--test/trans.d/case/next2_crack.rl79
-rw-r--r--test/trans.d/case/next2_cs.rl96
-rw-r--r--test/trans.d/case/next2_d.rl95
-rw-r--r--test/trans.d/case/next2_go.rl92
-rw-r--r--test/trans.d/case/next2_java.rl95
-rw-r--r--test/trans.d/case/next2_julia.rl68
-rw-r--r--test/trans.d/case/next2_ocaml.rl78
-rw-r--r--test/trans.d/case/next2_ruby.rl76
-rw-r--r--test/trans.d/case/next2_rust.rl76
-rw-r--r--test/trans.d/case/patact.rl99
-rw-r--r--test/trans.d/case/patact_asm.rl426
-rw-r--r--test/trans.d/case/patact_c.rl120
-rw-r--r--test/trans.d/case/patact_crack.rl107
-rw-r--r--test/trans.d/case/patact_cs.rl106
-rw-r--r--test/trans.d/case/patact_d.rl106
-rw-r--r--test/trans.d/case/patact_go.rl104
-rw-r--r--test/trans.d/case/patact_java.rl123
-rw-r--r--test/trans.d/case/patact_julia.rl94
-rw-r--r--test/trans.d/case/patact_ocaml.rl97
-rw-r--r--test/trans.d/case/patact_ruby.rl102
-rw-r--r--test/trans.d/case/patact_rust.rl103
-rw-r--r--test/trans.d/case/rangei.rl28
-rw-r--r--test/trans.d/case/rangei_asm.rl131
-rw-r--r--test/trans.d/case/rangei_c.rl71
-rw-r--r--test/trans.d/case/rangei_crack.rl56
-rw-r--r--test/trans.d/case/rangei_cs.rl76
-rw-r--r--test/trans.d/case/rangei_d.rl75
-rw-r--r--test/trans.d/case/rangei_go.rl61
-rw-r--r--test/trans.d/case/rangei_java.rl72
-rw-r--r--test/trans.d/case/rangei_julia.rl46
-rw-r--r--test/trans.d/case/rangei_ocaml.rl48
-rw-r--r--test/trans.d/case/rangei_ruby.rl54
-rw-r--r--test/trans.d/case/rangei_rust.rl53
-rw-r--r--test/trans.d/case/scan1.rl70
-rw-r--r--test/trans.d/case/scan1_asm.rl394
-rw-r--r--test/trans.d/case/scan1_c.rl114
-rw-r--r--test/trans.d/case/scan1_crack.rl101
-rw-r--r--test/trans.d/case/scan1_cs.rl103
-rw-r--r--test/trans.d/case/scan1_d.rl103
-rw-r--r--test/trans.d/case/scan1_go.rl84
-rw-r--r--test/trans.d/case/scan1_java.rl117
-rw-r--r--test/trans.d/case/scan1_julia.rl83
-rw-r--r--test/trans.d/case/scan1_ocaml.rl96
-rw-r--r--test/trans.d/case/scan1_ruby.rl91
-rw-r--r--test/trans.d/case/scan1_rust.rl97
-rw-r--r--test/trans.d/case/scan2.rl34
-rw-r--r--test/trans.d/case/scan2_asm.rl168
-rw-r--r--test/trans.d/case/scan2_c.rl75
-rw-r--r--test/trans.d/case/scan2_crack.rl62
-rw-r--r--test/trans.d/case/scan2_cs.rl76
-rw-r--r--test/trans.d/case/scan2_d.rl76
-rw-r--r--test/trans.d/case/scan2_go.rl62
-rw-r--r--test/trans.d/case/scan2_java.rl78
-rw-r--r--test/trans.d/case/scan2_julia.rl49
-rw-r--r--test/trans.d/case/scan2_ocaml.rl52
-rw-r--r--test/trans.d/case/scan2_ruby.rl57
-rw-r--r--test/trans.d/case/scan2_rust.rl58
-rw-r--r--test/trans.d/case/scan3.rl33
-rw-r--r--test/trans.d/case/scan3_asm.rl166
-rw-r--r--test/trans.d/case/scan3_c.rl73
-rw-r--r--test/trans.d/case/scan3_crack.rl60
-rw-r--r--test/trans.d/case/scan3_cs.rl74
-rw-r--r--test/trans.d/case/scan3_d.rl74
-rw-r--r--test/trans.d/case/scan3_go.rl60
-rw-r--r--test/trans.d/case/scan3_java.rl76
-rw-r--r--test/trans.d/case/scan3_julia.rl47
-rw-r--r--test/trans.d/case/scan3_ocaml.rl50
-rw-r--r--test/trans.d/case/scan3_ruby.rl55
-rw-r--r--test/trans.d/case/scan3_rust.rl56
-rw-r--r--test/trans.d/case/scan4.rl34
-rw-r--r--test/trans.d/case/scan4_asm.rl156
-rw-r--r--test/trans.d/case/scan4_c.rl74
-rw-r--r--test/trans.d/case/scan4_crack.rl61
-rw-r--r--test/trans.d/case/scan4_cs.rl76
-rw-r--r--test/trans.d/case/scan4_d.rl76
-rw-r--r--test/trans.d/case/scan4_go.rl62
-rw-r--r--test/trans.d/case/scan4_java.rl77
-rw-r--r--test/trans.d/case/scan4_julia.rl48
-rw-r--r--test/trans.d/case/scan4_ocaml.rl51
-rw-r--r--test/trans.d/case/scan4_ruby.rl56
-rw-r--r--test/trans.d/case/scan4_rust.rl57
-rw-r--r--test/trans.d/case/stateact1.rl47
-rw-r--r--test/trans.d/case/stateact1_asm.rl208
-rw-r--r--test/trans.d/case/stateact1_c.rl87
-rw-r--r--test/trans.d/case/stateact1_crack.rl72
-rw-r--r--test/trans.d/case/stateact1_cs.rl86
-rw-r--r--test/trans.d/case/stateact1_d.rl85
-rw-r--r--test/trans.d/case/stateact1_go.rl72
-rw-r--r--test/trans.d/case/stateact1_java.rl88
-rw-r--r--test/trans.d/case/stateact1_julia.rl62
-rw-r--r--test/trans.d/case/stateact1_ocaml.rl64
-rw-r--r--test/trans.d/case/stateact1_ruby.rl70
-rw-r--r--test/trans.d/case/stateact1_rust.rl69
-rw-r--r--test/trans.d/case/targs1.rl35
-rw-r--r--test/trans.d/case/targs1_asm.rl172
-rw-r--r--test/trans.d/case/targs1_c.rl74
-rw-r--r--test/trans.d/case/targs1_crack.rl59
-rw-r--r--test/trans.d/case/targs1_cs.rl77
-rw-r--r--test/trans.d/case/targs1_d.rl76
-rw-r--r--test/trans.d/case/targs1_go.rl68
-rw-r--r--test/trans.d/case/targs1_java.rl75
-rw-r--r--test/trans.d/case/targs1_julia.rl49
-rw-r--r--test/trans.d/case/targs1_ocaml.rl53
-rw-r--r--test/trans.d/case/targs1_ruby.rl57
-rw-r--r--test/trans.d/case/targs1_rust.rl56
-rw-r--r--test/trans.d/case/zlen1.rl15
-rw-r--r--test/trans.d/case/zlen1_asm.rl115
-rw-r--r--test/trans.d/case/zlen1_c.rl61
-rw-r--r--test/trans.d/case/zlen1_crack.rl46
-rw-r--r--test/trans.d/case/zlen1_cs.rl66
-rw-r--r--test/trans.d/case/zlen1_d.rl65
-rw-r--r--test/trans.d/case/zlen1_go.rl51
-rw-r--r--test/trans.d/case/zlen1_java.rl62
-rw-r--r--test/trans.d/case/zlen1_julia.rl36
-rw-r--r--test/trans.d/case/zlen1_ocaml.rl38
-rw-r--r--test/trans.d/case/zlen1_ruby.rl44
-rw-r--r--test/trans.d/case/zlen1_rust.rl43
-rwxr-xr-xtest/trans.d/gentests45
-rw-r--r--test/trans.d/main.c16
-rw-r--r--test/trans.d/ragel-c.lm175
-rw-r--r--test/trans.d/ragel-crack.lm150
-rw-r--r--test/trans.d/ragel-ocaml.lm147
-rw-r--r--test/trans.d/ragel-ruby.lm146
-rw-r--r--test/trans.d/ragel.lm559
-rw-r--r--test/trans.d/trans-asm.lm601
-rw-r--r--test/trans.d/trans-c.lm346
-rw-r--r--test/trans.d/trans-crack.lm346
-rw-r--r--test/trans.d/trans-csharp.lm346
-rw-r--r--test/trans.d/trans-d.lm332
-rw-r--r--test/trans.d/trans-go.lm322
-rw-r--r--test/trans.d/trans-java.lm346
-rw-r--r--test/trans.d/trans-julia.lm332
-rw-r--r--test/trans.d/trans-ocaml.lm362
-rw-r--r--test/trans.d/trans-ruby.lm336
-rw-r--r--test/trans.d/trans-rust.lm344
-rw-r--r--test/trans.d/trans.lm366
362 files changed, 41327 insertions, 0 deletions
diff --git a/test/trans.d/.gitignore b/test/trans.d/.gitignore
new file mode 100644
index 00000000..9dd4d30c
--- /dev/null
+++ b/test/trans.d/.gitignore
@@ -0,0 +1,4 @@
+/trans
+/trans.c
+/*.o
+/working
diff --git a/test/trans.d/Makefile b/test/trans.d/Makefile
new file mode 100644
index 00000000..b831cd2e
--- /dev/null
+++ b/test/trans.d/Makefile
@@ -0,0 +1,30 @@
+
+include ../colm.mk
+
+all: trans
+
+COLM = $(SUBJECT_BIN)
+COLM_INC = $(SUBJECT_CPPFLAGS)
+COLM_LIB = $(SUBJECT_LDFLAGS)
+
+TRANS_DEPS = $(wildcard *-*.lm)
+
+OBJ = actparams.o trans.o main.o
+
+trans: $(OBJ)
+ g++ -o $@ $(OBJ) $(COLM_LIB) -lcolm
+
+actparams.o: actparams.cc
+ g++ -c $(COLM_INC) -o $@ $<
+
+main.o: main.c
+ gcc -c $(COLM_INC) -o $@ $<
+
+trans.o: trans.c
+ gcc -c $(COLM_INC) -o $@ $<
+
+trans.c: trans.lm $(TRANS_DEPS)
+ $(COLM) -b trans_object -c -o $@ $<
+
+clean:
+ rm -f *.o
diff --git a/test/trans.d/actparams.cc b/test/trans.d/actparams.cc
new file mode 100644
index 00000000..d9e9d6ff
--- /dev/null
+++ b/test/trans.d/actparams.cc
@@ -0,0 +1,63 @@
+
+#include <colm/tree.h>
+#include <colm/bytecode.h>
+
+#include <iostream>
+#include <map>
+#include <set>
+
+using std::map;
+using std::set;
+using std::string;
+using std::pair;
+using std::cout;
+using std::endl;
+
+extern "C" {
+ colm_value_t cc_action_params_find( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action );
+ colm_value_t cc_action_params_insert( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action );
+}
+
+typedef set<string> Set;
+typedef map< string, Set > Map;
+static Map machineMap;
+
+value_t cc_action_params_find( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action )
+{
+ string machine( _machine->value->data, _machine->value->length );
+ string action( _action->value->data, _action->value->length );
+
+ // cout << "cc_action_params_find " << machine << " " << action << " ";
+
+ long res = 0;
+ Map::iterator M = machineMap.find( machine );
+ if ( M != machineMap.end() )
+ res = M->second.find( action ) != M->second.end();
+
+ // cout << ( res ? "FOUND" : "NOT FOUND" ) << endl;
+
+ colm_tree_downref( prg, sp, (tree_t*)_machine );
+ colm_tree_downref( prg, sp, (tree_t*)_action );
+
+ return (value_t) res;
+}
+
+value_t cc_action_params_insert( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action )
+{
+ string machine( _machine->value->data, _machine->value->length );
+ string action( _action->value->data, _action->value->length );
+
+ // cout << "cc_action_params_insert " << machine << " " << action << endl;
+
+ Map::iterator M = machineMap.find( machine );
+ if ( M == machineMap.end() )
+ machineMap.insert( pair<string, Set>( machine, Set() ) );
+
+ M = machineMap.find( machine );
+ M->second.insert( action );
+
+ colm_tree_downref( prg, sp, (tree_t*)_machine );
+ colm_tree_downref( prg, sp, (tree_t*)_action );
+
+ return 0;
+}
diff --git a/test/trans.d/case/any1.rl b/test/trans.d/case/any1.rl
new file mode 100644
index 00000000..81ec713c
--- /dev/null
+++ b/test/trans.d/case/any1.rl
@@ -0,0 +1,17 @@
+/*
+ * @LANG: indep
+ */
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+##### INPUT #####
+""
+"x"
+"xx"
+##### OUTPUT #####
+FAIL
+ACCEPT
+FAIL
diff --git a/test/trans.d/case/any1_asm.rl b/test/trans.d/case/any1_asm.rl
new file mode 100644
index 00000000..4a9cc24e
--- /dev/null
+++ b/test/trans.d/case/any1_asm.rl
@@ -0,0 +1,118 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq any1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string ""
+.L_inp_1:
+ .string "x"
+.L_inp_2:
+ .string "xx"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+
+ .align 8
+inplen:
+ .quad 3
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/any1_c.rl b/test/trans.d/case/any1_c.rl
new file mode 100644
index 00000000..6fbbb85c
--- /dev/null
+++ b/test/trans.d/case/any1_c.rl
@@ -0,0 +1,62 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= any1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"",
+"x",
+"xx",
+};
+
+int inplen = 3;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/any1_crack.rl b/test/trans.d/case/any1_crack.rl
new file mode 100644
index 00000000..8458ae75
--- /dev/null
+++ b/test/trans.d/case/any1_crack.rl
@@ -0,0 +1,47 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= any1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "" );
+ m( "x" );
+ m( "xx" );
+}
+
+main();
diff --git a/test/trans.d/case/any1_cs.rl b/test/trans.d/case/any1_cs.rl
new file mode 100644
index 00000000..33700be9
--- /dev/null
+++ b/test/trans.d/case/any1_cs.rl
@@ -0,0 +1,67 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= any1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"",
+"x",
+"xx",
+};
+
+
+static readonly int inplen = 3;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/any1_d.rl b/test/trans.d/case/any1_d.rl
new file mode 100644
index 00000000..b08bb574
--- /dev/null
+++ b/test/trans.d/case/any1_d.rl
@@ -0,0 +1,66 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class any1
+{
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= any1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"",
+"x",
+"xx",
+];
+
+int inplen = 3;
+
+}
+int main()
+{
+ any1 m = new any1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/any1_go.rl b/test/trans.d/case/any1_go.rl
new file mode 100644
index 00000000..71396428
--- /dev/null
+++ b/test/trans.d/case/any1_go.rl
@@ -0,0 +1,52 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= any1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"",
+"x",
+"xx",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/any1_java.rl b/test/trans.d/case/any1_java.rl
new file mode 100644
index 00000000..ba28d77f
--- /dev/null
+++ b/test/trans.d/case/any1_java.rl
@@ -0,0 +1,63 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class any1_java
+{
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= any1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"",
+"x",
+"xx",
+};
+
+static final int inplen = 3;
+
+public static void main (String[] args)
+{
+ any1_java machine = new any1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/any1_julia.rl b/test/trans.d/case/any1_julia.rl
new file mode 100644
index 00000000..40b7387f
--- /dev/null
+++ b/test/trans.d/case/any1_julia.rl
@@ -0,0 +1,37 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= any1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "" );
+ m( "x" );
+ m( "xx" );
diff --git a/test/trans.d/case/any1_ocaml.rl b/test/trans.d/case/any1_ocaml.rl
new file mode 100644
index 00000000..d2bd7731
--- /dev/null
+++ b/test/trans.d/case/any1_ocaml.rl
@@ -0,0 +1,39 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= any1_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "";
+ exec "x";
+ exec "xx";
+ ()
+;;
+
diff --git a/test/trans.d/case/any1_ruby.rl b/test/trans.d/case/any1_ruby.rl
new file mode 100644
index 00000000..b102b035
--- /dev/null
+++ b/test/trans.d/case/any1_ruby.rl
@@ -0,0 +1,45 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= any1_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"",
+"x",
+"xx",
+]
+
+inplen = 3
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/any1_rust.rl b/test/trans.d/case/any1_rust.rl
new file mode 100644
index 00000000..fc7939e2
--- /dev/null
+++ b/test/trans.d/case/any1_rust.rl
@@ -0,0 +1,44 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine any1;
+ main := any;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= any1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "".to_string() ); }
+ unsafe { m( "x".to_string() ); }
+ unsafe { m( "xx".to_string() ); }
+}
+
diff --git a/test/trans.d/case/atoi1.rl b/test/trans.d/case/atoi1.rl
new file mode 100644
index 00000000..b56996e5
--- /dev/null
+++ b/test/trans.d/case/atoi1.rl
@@ -0,0 +1,67 @@
+/*
+ * @LANG: indep
+ */
+bool neg;
+int value;
+
+value = 0;
+neg = false;
+%%{
+ machine atoi;
+
+ action begin {
+ neg = false;
+ value = 0;
+ }
+
+ action see_neg {
+ neg = true;
+ }
+
+ action add_digit {
+ value = value * 10 + <int>(fc - 48);
+ }
+
+ action finish {
+ if ( neg != 0 ) {
+ value = -1 * value;
+ }
+ }
+ action print {
+ print_int value;
+ print_str "\n";
+ }
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+##### INPUT #####
+"1\n"
+"12\n"
+"222222\n"
+"+2123\n"
+"213 3213\n"
+"-12321\n"
+"--123\n"
+"-99\n"
+" -3000\n"
+##### OUTPUT #####
+1
+ACCEPT
+12
+ACCEPT
+222222
+ACCEPT
+2123
+ACCEPT
+FAIL
+-12321
+ACCEPT
+FAIL
+-99
+ACCEPT
+FAIL
diff --git a/test/trans.d/case/atoi1_asm.rl b/test/trans.d/case/atoi1_asm.rl
new file mode 100644
index 00000000..085b5f37
--- /dev/null
+++ b/test/trans.d/case/atoi1_asm.rl
@@ -0,0 +1,246 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm neg,8,8
+ .text
+ .section .data
+ .comm value,8,8
+ .text
+
+%%{
+ machine atoi;
+
+ action begin {
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, neg (%rip)
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+
+}
+
+ action see_neg {
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, neg (%rip)
+
+}
+
+ action add_digit {
+ movq value (%rip), %rax
+ pushq %rax
+ movq $10 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ imul %rcx, %rax
+ pushq %rax
+ movsbq (%r12), %rax
+ pushq %rax
+ movq $48, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ subq %rcx, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+
+}
+
+ action finish {
+ movq neg (%rip), %rax
+ pushq %rax
+ movq $0 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ setne %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 1f
+ movq $-1 , %rax
+ pushq %rax
+ movq value(%rip), %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ imul %rcx, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+1:
+
+}
+ action print {
+ movq value(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+3:
+ .string "\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, neg (%rip)
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq atoi_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1\n"
+.L_inp_1:
+ .string "12\n"
+.L_inp_2:
+ .string "222222\n"
+.L_inp_3:
+ .string "+2123\n"
+.L_inp_4:
+ .string "213 3213\n"
+.L_inp_5:
+ .string "-12321\n"
+.L_inp_6:
+ .string "--123\n"
+.L_inp_7:
+ .string "-99\n"
+.L_inp_8:
+ .string " -3000\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+
+ .align 8
+inplen:
+ .quad 9
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/atoi1_c.rl b/test/trans.d/case/atoi1_c.rl
new file mode 100644
index 00000000..20409ccc
--- /dev/null
+++ b/test/trans.d/case/atoi1_c.rl
@@ -0,0 +1,96 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int neg ;
+int value ;
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+ action print {printf( "%d", value );
+printf( "%s", "\n" );
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= atoi_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+int inplen = 9;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/atoi1_crack.rl b/test/trans.d/case/atoi1_crack.rl
new file mode 100644
index 00000000..8e3adfcc
--- /dev/null
+++ b/test/trans.d/case/atoi1_crack.rl
@@ -0,0 +1,81 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int neg;
+int value;
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ( fc - 48 ) )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+ action print {cout.format( value );
+cout.format( "\n" );
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+value = 0;
+neg = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= atoi_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1\n" );
+ m( "12\n" );
+ m( "222222\n" );
+ m( "+2123\n" );
+ m( "213 3213\n" );
+ m( "-12321\n" );
+ m( "--123\n" );
+ m( "-99\n" );
+ m( " -3000\n" );
+}
+
+main();
diff --git a/test/trans.d/case/atoi1_cs.rl b/test/trans.d/case/atoi1_cs.rl
new file mode 100644
index 00000000..64051f10
--- /dev/null
+++ b/test/trans.d/case/atoi1_cs.rl
@@ -0,0 +1,99 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int neg;
+int value;
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+ action print {Console.Write( value );Console.Write( "\n" );}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= atoi_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+
+static readonly int inplen = 9;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/atoi1_d.rl b/test/trans.d/case/atoi1_d.rl
new file mode 100644
index 00000000..1d9d0ffa
--- /dev/null
+++ b/test/trans.d/case/atoi1_d.rl
@@ -0,0 +1,99 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class atoi
+{
+int neg;
+int value;
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + cast( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+ action print {printf( "%d", value );
+printf( "%.*s", "\n" );}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= atoi_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+];
+
+int inplen = 9;
+
+}
+int main()
+{
+ atoi m = new atoi();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/atoi1_go.rl b/test/trans.d/case/atoi1_go.rl
new file mode 100644
index 00000000..0ffa7a1a
--- /dev/null
+++ b/test/trans.d/case/atoi1_go.rl
@@ -0,0 +1,83 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var neg int ;
+var value int ;
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 ) {
+ value = -1 * value;
+
+}
+}
+ action print {fmt.Print( value );fmt.Print( "\n" );}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= atoi_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/atoi1_java.rl b/test/trans.d/case/atoi1_java.rl
new file mode 100644
index 00000000..033555d1
--- /dev/null
+++ b/test/trans.d/case/atoi1_java.rl
@@ -0,0 +1,97 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class atoi1_java
+{
+int neg ;
+int value ;
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+ action print {System.out.print( value );
+System.out.print( "\n" );
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= atoi_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+static final int inplen = 9;
+
+public static void main (String[] args)
+{
+ atoi1_java machine = new atoi1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/atoi1_julia.rl b/test/trans.d/case/atoi1_julia.rl
new file mode 100644
index 00000000..1576981f
--- /dev/null
+++ b/test/trans.d/case/atoi1_julia.rl
@@ -0,0 +1,70 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + convert( Int, ( fc - 48 ) )
+;
+}
+
+ action finish {if ( neg != 0 )
+ value = -1 * value;
+
+end
+}
+ action print {print( value );
+print( "\n" );
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+neg = 0;
+value = 0;
+value = 0;
+neg = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= atoi_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1\n" );
+ m( "12\n" );
+ m( "222222\n" );
+ m( "+2123\n" );
+ m( "213 3213\n" );
+ m( "-12321\n" );
+ m( "--123\n" );
+ m( "-99\n" );
+ m( " -3000\n" );
diff --git a/test/trans.d/case/atoi1_ocaml.rl b/test/trans.d/case/atoi1_ocaml.rl
new file mode 100644
index 00000000..b0bc8c9f
--- /dev/null
+++ b/test/trans.d/case/atoi1_ocaml.rl
@@ -0,0 +1,74 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let neg = ref 0
+let value = ref 0
+
+%%{
+ machine atoi;
+
+ action begin {neg := 0;
+value := 0;
+}
+
+ action see_neg {neg := 1;
+}
+
+ action add_digit {value := value .contents * 10 + ( fc - 48 )
+;
+}
+
+ action finish {if neg .contents != 0 then
+begin
+ value := -1 * value.contents;
+
+end
+;
+}
+ action print {print_int( value.contents );
+print_string( "\n" );
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+value := 0;
+neg := 0;
+ %% write init;
+ %% write exec;
+ if !cs >= atoi_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1\n";
+ exec "12\n";
+ exec "222222\n";
+ exec "+2123\n";
+ exec "213 3213\n";
+ exec "-12321\n";
+ exec "--123\n";
+ exec "-99\n";
+ exec " -3000\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/atoi1_ruby.rl b/test/trans.d/case/atoi1_ruby.rl
new file mode 100644
index 00000000..c8a67ccc
--- /dev/null
+++ b/test/trans.d/case/atoi1_ruby.rl
@@ -0,0 +1,78 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+ value = -1 * value;
+
+end
+}
+ action print {print( value );
+print( "\n" );
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+neg = 1
+value = 1
+value = 0;
+neg = 0;
+ %% write init;
+ %% write exec;
+ if cs >= atoi_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+]
+
+inplen = 9
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/atoi1_rust.rl b/test/trans.d/case/atoi1_rust.rl
new file mode 100644
index 00000000..3af63b7f
--- /dev/null
+++ b/test/trans.d/case/atoi1_rust.rl
@@ -0,0 +1,78 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut neg : i8 = 0;
+static mut value : i32 = 0;
+
+%%{
+ machine atoi;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( ( fc - 48 ) as i32 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+ action print {print!( "{}", value );
+print!( "{}", "\n" );
+}
+
+ atoi = (
+ ('-'@see_neg | '+')? (digit @add_digit)+
+ ) >begin %finish;
+
+ main := atoi '\n' @print;
+}%%
+
+
+
+%% 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();
+value = 0;
+neg = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= atoi_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1\n".to_string() ); }
+ unsafe { m( "12\n".to_string() ); }
+ unsafe { m( "222222\n".to_string() ); }
+ unsafe { m( "+2123\n".to_string() ); }
+ unsafe { m( "213 3213\n".to_string() ); }
+ unsafe { m( "-12321\n".to_string() ); }
+ unsafe { m( "--123\n".to_string() ); }
+ unsafe { m( "-99\n".to_string() ); }
+ unsafe { m( " -3000\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/atoi2.rl b/test/trans.d/case/atoi2.rl
new file mode 100644
index 00000000..9b8cd13c
--- /dev/null
+++ b/test/trans.d/case/atoi2.rl
@@ -0,0 +1,81 @@
+/*
+ * @LANG: indep
+ * This implementes an atoi machine using the statechart paradigm.
+ */
+bool neg;
+int value;
+
+value = 0;
+neg = false;
+
+%%{
+ machine state_chart;
+
+ action begin {
+ neg = false;
+ value = 0;
+ }
+
+ action see_neg {
+ neg = true;
+ }
+
+ action add_digit {
+ value = value * 10 + <int>(fc - 48);
+ }
+
+ action finish {
+ if ( neg != 0 ) {
+ value = -1 * value;
+ }
+ }
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof { print_int value; print_str "\n"; }
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+##### INPUT #####
+"1\n"
+"12\n"
+"222222\n"
+"+2123\n"
+"213 3213\n"
+"-12321\n"
+"--123\n"
+"-99\n"
+" -3000\n"
+##### OUTPUT #####
+1
+ACCEPT
+12
+ACCEPT
+222222
+ACCEPT
+2123
+ACCEPT
+FAIL
+-12321
+ACCEPT
+FAIL
+-99
+ACCEPT
+FAIL
diff --git a/test/trans.d/case/atoi2_asm.rl b/test/trans.d/case/atoi2_asm.rl
new file mode 100644
index 00000000..51e8eb48
--- /dev/null
+++ b/test/trans.d/case/atoi2_asm.rl
@@ -0,0 +1,261 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm neg,8,8
+ .text
+ .section .data
+ .comm value,8,8
+ .text
+
+%%{
+ machine state_chart;
+
+ action begin {
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, neg (%rip)
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+
+}
+
+ action see_neg {
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, neg (%rip)
+
+}
+
+ action add_digit {
+ movq value (%rip), %rax
+ pushq %rax
+ movq $10 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ imul %rcx, %rax
+ pushq %rax
+ movsbq (%r12), %rax
+ pushq %rax
+ movq $48, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ subq %rcx, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+
+}
+
+ action finish {
+ movq neg (%rip), %rax
+ pushq %rax
+ movq $0 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ setne %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 1f
+ movq $-1 , %rax
+ pushq %rax
+ movq value(%rip), %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ imul %rcx, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+1:
+
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {
+ movq value(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+3:
+ .string "\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, value (%rip)
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, neg (%rip)
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq state_chart_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1\n"
+.L_inp_1:
+ .string "12\n"
+.L_inp_2:
+ .string "222222\n"
+.L_inp_3:
+ .string "+2123\n"
+.L_inp_4:
+ .string "213 3213\n"
+.L_inp_5:
+ .string "-12321\n"
+.L_inp_6:
+ .string "--123\n"
+.L_inp_7:
+ .string "-99\n"
+.L_inp_8:
+ .string " -3000\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+
+ .align 8
+inplen:
+ .quad 9
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/atoi2_c.rl b/test/trans.d/case/atoi2_c.rl
new file mode 100644
index 00000000..0a7431fe
--- /dev/null
+++ b/test/trans.d/case/atoi2_c.rl
@@ -0,0 +1,111 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int neg ;
+int value ;
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {printf( "%d", value );
+printf( "%s", "\n" );
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_chart_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+int inplen = 9;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/atoi2_crack.rl b/test/trans.d/case/atoi2_crack.rl
new file mode 100644
index 00000000..cf7123cf
--- /dev/null
+++ b/test/trans.d/case/atoi2_crack.rl
@@ -0,0 +1,96 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int neg;
+int value;
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ( fc - 48 ) )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {cout.format( value );
+cout.format( "\n" );
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+value = 0;
+neg = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= state_chart_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1\n" );
+ m( "12\n" );
+ m( "222222\n" );
+ m( "+2123\n" );
+ m( "213 3213\n" );
+ m( "-12321\n" );
+ m( "--123\n" );
+ m( "-99\n" );
+ m( " -3000\n" );
+}
+
+main();
diff --git a/test/trans.d/case/atoi2_cs.rl b/test/trans.d/case/atoi2_cs.rl
new file mode 100644
index 00000000..b3a182b8
--- /dev/null
+++ b/test/trans.d/case/atoi2_cs.rl
@@ -0,0 +1,114 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int neg;
+int value;
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {Console.Write( value );Console.Write( "\n" );}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_chart_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+
+static readonly int inplen = 9;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/atoi2_d.rl b/test/trans.d/case/atoi2_d.rl
new file mode 100644
index 00000000..301cf6fa
--- /dev/null
+++ b/test/trans.d/case/atoi2_d.rl
@@ -0,0 +1,114 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class state_chart
+{
+int neg;
+int value;
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + cast( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {printf( "%d", value );
+printf( "%.*s", "\n" );}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_chart_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+];
+
+int inplen = 9;
+
+}
+int main()
+{
+ state_chart m = new state_chart();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/atoi2_go.rl b/test/trans.d/case/atoi2_go.rl
new file mode 100644
index 00000000..4ff0d8d9
--- /dev/null
+++ b/test/trans.d/case/atoi2_go.rl
@@ -0,0 +1,98 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var neg int ;
+var value int ;
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 ) {
+ value = -1 * value;
+
+}
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {fmt.Print( value );fmt.Print( "\n" );}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= state_chart_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/atoi2_java.rl b/test/trans.d/case/atoi2_java.rl
new file mode 100644
index 00000000..e26228e3
--- /dev/null
+++ b/test/trans.d/case/atoi2_java.rl
@@ -0,0 +1,112 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class atoi2_java
+{
+int neg ;
+int value ;
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( int ) ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {System.out.print( value );
+System.out.print( "\n" );
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+value = 0;
+neg = 0;
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_chart_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+};
+
+static final int inplen = 9;
+
+public static void main (String[] args)
+{
+ atoi2_java machine = new atoi2_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/atoi2_julia.rl b/test/trans.d/case/atoi2_julia.rl
new file mode 100644
index 00000000..b43e2593
--- /dev/null
+++ b/test/trans.d/case/atoi2_julia.rl
@@ -0,0 +1,85 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + convert( Int, ( fc - 48 ) )
+;
+}
+
+ action finish {if ( neg != 0 )
+ value = -1 * value;
+
+end
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {print( value );
+print( "\n" );
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+neg = 0;
+value = 0;
+value = 0;
+neg = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= state_chart_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1\n" );
+ m( "12\n" );
+ m( "222222\n" );
+ m( "+2123\n" );
+ m( "213 3213\n" );
+ m( "-12321\n" );
+ m( "--123\n" );
+ m( "-99\n" );
+ m( " -3000\n" );
diff --git a/test/trans.d/case/atoi2_ocaml.rl b/test/trans.d/case/atoi2_ocaml.rl
new file mode 100644
index 00000000..45dc1f6e
--- /dev/null
+++ b/test/trans.d/case/atoi2_ocaml.rl
@@ -0,0 +1,89 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let neg = ref 0
+let value = ref 0
+
+%%{
+ machine state_chart;
+
+ action begin {neg := 0;
+value := 0;
+}
+
+ action see_neg {neg := 1;
+}
+
+ action add_digit {value := value .contents * 10 + ( fc - 48 )
+;
+}
+
+ action finish {if neg .contents != 0 then
+begin
+ value := -1 * value.contents;
+
+end
+;
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {print_int( value.contents );
+print_string( "\n" );
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+value := 0;
+neg := 0;
+ %% write init;
+ %% write exec;
+ if !cs >= state_chart_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1\n";
+ exec "12\n";
+ exec "222222\n";
+ exec "+2123\n";
+ exec "213 3213\n";
+ exec "-12321\n";
+ exec "--123\n";
+ exec "-99\n";
+ exec " -3000\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/atoi2_ruby.rl b/test/trans.d/case/atoi2_ruby.rl
new file mode 100644
index 00000000..0d86d793
--- /dev/null
+++ b/test/trans.d/case/atoi2_ruby.rl
@@ -0,0 +1,93 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( fc - 48 )
+;
+}
+
+ action finish {if ( neg != 0 )
+ value = -1 * value;
+
+end
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {print( value );
+print( "\n" );
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+neg = 1
+value = 1
+value = 0;
+neg = 0;
+ %% write init;
+ %% write exec;
+ if cs >= state_chart_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1\n",
+"12\n",
+"222222\n",
+"+2123\n",
+"213 3213\n",
+"-12321\n",
+"--123\n",
+"-99\n",
+" -3000\n",
+]
+
+inplen = 9
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/atoi2_rust.rl b/test/trans.d/case/atoi2_rust.rl
new file mode 100644
index 00000000..5510068a
--- /dev/null
+++ b/test/trans.d/case/atoi2_rust.rl
@@ -0,0 +1,93 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut neg : i8 = 0;
+static mut value : i32 = 0;
+
+%%{
+ machine state_chart;
+
+ action begin {neg = 0;
+value = 0;
+}
+
+ action see_neg {neg = 1;
+}
+
+ action add_digit {value = value * 10 + ( ( fc - 48 ) as i32 )
+;
+}
+
+ action finish {if ( neg != 0 )
+{
+ value = -1 * value;
+
+}
+}
+
+ atoi = (
+ start: (
+ '-' @see_neg ->om_num |
+ '+' ->om_num |
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # One or more nums.
+ om_num: (
+ [0-9] @add_digit ->more_nums
+ ),
+
+ # Zero ore more nums.
+ more_nums: (
+ [0-9] @add_digit ->more_nums |
+ '' -> final
+ )
+ ) >begin %finish;
+
+ action oneof {print!( "{}", value );
+print!( "{}", "\n" );
+}
+ main := ( atoi '\n' @oneof )*;
+}%%
+
+
+
+%% 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();
+value = 0;
+neg = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= state_chart_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1\n".to_string() ); }
+ unsafe { m( "12\n".to_string() ); }
+ unsafe { m( "222222\n".to_string() ); }
+ unsafe { m( "+2123\n".to_string() ); }
+ unsafe { m( "213 3213\n".to_string() ); }
+ unsafe { m( "-12321\n".to_string() ); }
+ unsafe { m( "--123\n".to_string() ); }
+ unsafe { m( "-99\n".to_string() ); }
+ unsafe { m( " -3000\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/call4.rl b/test/trans.d/case/call4.rl
new file mode 100644
index 00000000..72edf30e
--- /dev/null
+++ b/test/trans.d/case/call4.rl
@@ -0,0 +1,39 @@
+/*
+ * @LANG: indep
+ * @PROHIBIT_LANGUAGES: ruby ocaml
+ * @PROHIBIT_FEATFLAGS: --var-backend
+ */
+
+int target;
+int top;
+int stack[32];
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ print_str "one\n";
+ fret;
+ };
+
+ two := 'two' @{
+ print_str "two\n";
+ fret;
+ };
+
+ main := (
+ '1' @{ target = fentry(one); fcall *target; }
+ | '2' @{ target = fentry(two); fcall *target; }
+ | '\n'
+ )*;
+}%%
+
+##### INPUT #####
+"1one2two1one\n"
+##### OUTPUT #####
+one
+two
+one
+ACCEPT
diff --git a/test/trans.d/case/call4_asm.rl b/test/trans.d/case/call4_asm.rl
new file mode 100644
index 00000000..70e816ed
--- /dev/null
+++ b/test/trans.d/case/call4_asm.rl
@@ -0,0 +1,180 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm target,8,8
+ .text
+ .section .data
+ .comm top,8,8
+ .text
+ .section .data
+ .comm stack,8,8
+ .text
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ .section .rodata
+1:
+ .string "one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fret;
+
+
+};
+
+ two := 'two' @{
+ .section .rodata
+2:
+ .string "two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fret;
+
+
+};
+
+ main := (
+ '1' @{
+ movq $fentry(one), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fcall * %rcx;
+
+}
+ | '2' @{
+ movq $fentry(two), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fcall * %rcx;
+
+}
+ | '\n'
+ )*;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq call4_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1one2two1one\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/call4_c.rl b/test/trans.d/case/call4_c.rl
new file mode 100644
index 00000000..e8002904
--- /dev/null
+++ b/test/trans.d/case/call4_c.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int target ;
+int top ;
+int stack [32];
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%s", "one\n" );
+fret;};
+
+ two := 'two' @{printf( "%s", "two\n" );
+fret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;}
+ | '2' @{target = fentry(two);
+fcall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= call4_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1one2two1one\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/call4_crack.rl b/test/trans.d/case/call4_crack.rl
new file mode 100644
index 00000000..ecac128b
--- /dev/null
+++ b/test/trans.d/case/call4_crack.rl
@@ -0,0 +1,61 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int target;
+int top;
+array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{cout.format( "one\n" );
+fret;};
+
+ two := 'two' @{cout.format( "two\n" );
+fret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;}
+ | '2' @{target = fentry(two);
+fcall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= call4_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1one2two1one\n" );
+}
+
+main();
diff --git a/test/trans.d/case/call4_cs.rl b/test/trans.d/case/call4_cs.rl
new file mode 100644
index 00000000..19f01958
--- /dev/null
+++ b/test/trans.d/case/call4_cs.rl
@@ -0,0 +1,79 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int target;
+int top;
+int [] stack = new int [32];
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{Console.Write( "one\n" );fret;};
+
+ two := 'two' @{Console.Write( "two\n" );fret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;}
+ | '2' @{target = fentry(two);
+fcall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= call4_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1one2two1one\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/call4_d.rl b/test/trans.d/case/call4_d.rl
new file mode 100644
index 00000000..b187ce85
--- /dev/null
+++ b/test/trans.d/case/call4_d.rl
@@ -0,0 +1,78 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class call4
+{
+int target;
+int top;
+int stack[32];
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%.*s", "one\n" );fret;};
+
+ two := 'two' @{printf( "%.*s", "two\n" );fret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;}
+ | '2' @{target = fentry(two);
+fcall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= call4_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1one2two1one\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ call4 m = new call4();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/call4_go.rl b/test/trans.d/case/call4_go.rl
new file mode 100644
index 00000000..886f3031
--- /dev/null
+++ b/test/trans.d/case/call4_go.rl
@@ -0,0 +1,70 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var target int ;
+var top int ;
+var stack [32] int ;
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{fmt.Print( "one\n" );fret;
+
+};
+
+ two := 'two' @{fmt.Print( "two\n" );fret;
+
+};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;
+}
+ | '2' @{target = fentry(two);
+fcall *target;
+}
+ | '\n'
+ )*;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= call4_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1one2two1one\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/call4_java.rl b/test/trans.d/case/call4_java.rl
new file mode 100644
index 00000000..5bdf9a3f
--- /dev/null
+++ b/test/trans.d/case/call4_java.rl
@@ -0,0 +1,77 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class call4_java
+{
+int target ;
+int top ;
+int stack [] = new int[32];
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{System.out.print( "one\n" );
+fret;};
+
+ two := 'two' @{System.out.print( "two\n" );
+fret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;}
+ | '2' @{target = fentry(two);
+fcall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= call4_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1one2two1one\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ call4_java machine = new call4_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/call4_julia.rl b/test/trans.d/case/call4_julia.rl
new file mode 100644
index 00000000..263e65d6
--- /dev/null
+++ b/test/trans.d/case/call4_julia.rl
@@ -0,0 +1,51 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+fret;};
+
+ two := 'two' @{print( "two\n" );
+fret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;}
+ | '2' @{target = fentry(two);
+fcall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+target = 0;
+top = 0;
+stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= call4_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1one2two1one\n" );
diff --git a/test/trans.d/case/call4_rust.rl b/test/trans.d/case/call4_rust.rl
new file mode 100644
index 00000000..f9d24550
--- /dev/null
+++ b/test/trans.d/case/call4_rust.rl
@@ -0,0 +1,58 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut target : i32 = 0;
+static mut top : i32 = 0;
+static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+%%{
+ machine call4;
+
+ unused := 'unused';
+
+ one := 'one' @{print!( "{}", "one\n" );
+fret;};
+
+ two := 'two' @{print!( "{}", "two\n" );
+fret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fcall *target;}
+ | '2' @{target = fentry(two);
+fcall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= call4_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1one2two1one\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/caseindep.rl b/test/trans.d/case/caseindep.rl
new file mode 100644
index 00000000..d3bd188c
--- /dev/null
+++ b/test/trans.d/case/caseindep.rl
@@ -0,0 +1,54 @@
+/*
+ * @LANG: indep
+ */
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+##### INPUT #####
+"1hello\n"
+"1HELLO\n"
+"1HeLLo\n"
+"2hello\n"
+"2HELLO\n"
+"2HeLLo\n"
+"3hello\n"
+"3HELLO\n"
+"3HeLLo\n"
+"4hello\n"
+"4HELLO\n"
+"4HeLLo\n"
+"5hello\n"
+"5HELLO\n"
+"5HeLLo\n"
+"6hello\n"
+"6HELLO\n"
+"6HeLLo\n"
+##### OUTPUT #####
+ACCEPT
+FAIL
+FAIL
+ACCEPT
+FAIL
+FAIL
+ACCEPT
+FAIL
+FAIL
+ACCEPT
+ACCEPT
+ACCEPT
+ACCEPT
+ACCEPT
+ACCEPT
+ACCEPT
+ACCEPT
+ACCEPT
diff --git a/test/trans.d/case/caseindep_asm.rl b/test/trans.d/case/caseindep_asm.rl
new file mode 100644
index 00000000..bc4aca8f
--- /dev/null
+++ b/test/trans.d/case/caseindep_asm.rl
@@ -0,0 +1,170 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq indep_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1hello\n"
+.L_inp_1:
+ .string "1HELLO\n"
+.L_inp_2:
+ .string "1HeLLo\n"
+.L_inp_3:
+ .string "2hello\n"
+.L_inp_4:
+ .string "2HELLO\n"
+.L_inp_5:
+ .string "2HeLLo\n"
+.L_inp_6:
+ .string "3hello\n"
+.L_inp_7:
+ .string "3HELLO\n"
+.L_inp_8:
+ .string "3HeLLo\n"
+.L_inp_9:
+ .string "4hello\n"
+.L_inp_10:
+ .string "4HELLO\n"
+.L_inp_11:
+ .string "4HeLLo\n"
+.L_inp_12:
+ .string "5hello\n"
+.L_inp_13:
+ .string "5HELLO\n"
+.L_inp_14:
+ .string "5HeLLo\n"
+.L_inp_15:
+ .string "6hello\n"
+.L_inp_16:
+ .string "6HELLO\n"
+.L_inp_17:
+ .string "6HeLLo\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+ .quad .L_inp_9
+ .quad .L_inp_10
+ .quad .L_inp_11
+ .quad .L_inp_12
+ .quad .L_inp_13
+ .quad .L_inp_14
+ .quad .L_inp_15
+ .quad .L_inp_16
+ .quad .L_inp_17
+
+ .align 8
+inplen:
+ .quad 18
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/caseindep_c.rl b/test/trans.d/case/caseindep_c.rl
new file mode 100644
index 00000000..a0771ae0
--- /dev/null
+++ b/test/trans.d/case/caseindep_c.rl
@@ -0,0 +1,84 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= indep_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1hello\n",
+"1HELLO\n",
+"1HeLLo\n",
+"2hello\n",
+"2HELLO\n",
+"2HeLLo\n",
+"3hello\n",
+"3HELLO\n",
+"3HeLLo\n",
+"4hello\n",
+"4HELLO\n",
+"4HeLLo\n",
+"5hello\n",
+"5HELLO\n",
+"5HeLLo\n",
+"6hello\n",
+"6HELLO\n",
+"6HeLLo\n",
+};
+
+int inplen = 18;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/caseindep_crack.rl b/test/trans.d/case/caseindep_crack.rl
new file mode 100644
index 00000000..a4c2bf8a
--- /dev/null
+++ b/test/trans.d/case/caseindep_crack.rl
@@ -0,0 +1,69 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= indep_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1hello\n" );
+ m( "1HELLO\n" );
+ m( "1HeLLo\n" );
+ m( "2hello\n" );
+ m( "2HELLO\n" );
+ m( "2HeLLo\n" );
+ m( "3hello\n" );
+ m( "3HELLO\n" );
+ m( "3HeLLo\n" );
+ m( "4hello\n" );
+ m( "4HELLO\n" );
+ m( "4HeLLo\n" );
+ m( "5hello\n" );
+ m( "5HELLO\n" );
+ m( "5HeLLo\n" );
+ m( "6hello\n" );
+ m( "6HELLO\n" );
+ m( "6HeLLo\n" );
+}
+
+main();
diff --git a/test/trans.d/case/caseindep_cs.rl b/test/trans.d/case/caseindep_cs.rl
new file mode 100644
index 00000000..404be8f1
--- /dev/null
+++ b/test/trans.d/case/caseindep_cs.rl
@@ -0,0 +1,89 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= indep_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1hello\n",
+"1HELLO\n",
+"1HeLLo\n",
+"2hello\n",
+"2HELLO\n",
+"2HeLLo\n",
+"3hello\n",
+"3HELLO\n",
+"3HeLLo\n",
+"4hello\n",
+"4HELLO\n",
+"4HeLLo\n",
+"5hello\n",
+"5HELLO\n",
+"5HeLLo\n",
+"6hello\n",
+"6HELLO\n",
+"6HeLLo\n",
+};
+
+
+static readonly int inplen = 18;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/caseindep_d.rl b/test/trans.d/case/caseindep_d.rl
new file mode 100644
index 00000000..dc666dd9
--- /dev/null
+++ b/test/trans.d/case/caseindep_d.rl
@@ -0,0 +1,88 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class indep
+{
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= indep_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1hello\n",
+"1HELLO\n",
+"1HeLLo\n",
+"2hello\n",
+"2HELLO\n",
+"2HeLLo\n",
+"3hello\n",
+"3HELLO\n",
+"3HeLLo\n",
+"4hello\n",
+"4HELLO\n",
+"4HeLLo\n",
+"5hello\n",
+"5HELLO\n",
+"5HeLLo\n",
+"6hello\n",
+"6HELLO\n",
+"6HeLLo\n",
+];
+
+int inplen = 18;
+
+}
+int main()
+{
+ indep m = new indep();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/caseindep_go.rl b/test/trans.d/case/caseindep_go.rl
new file mode 100644
index 00000000..106751a8
--- /dev/null
+++ b/test/trans.d/case/caseindep_go.rl
@@ -0,0 +1,74 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= indep_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1hello\n",
+"1HELLO\n",
+"1HeLLo\n",
+"2hello\n",
+"2HELLO\n",
+"2HeLLo\n",
+"3hello\n",
+"3HELLO\n",
+"3HeLLo\n",
+"4hello\n",
+"4HELLO\n",
+"4HeLLo\n",
+"5hello\n",
+"5HELLO\n",
+"5HeLLo\n",
+"6hello\n",
+"6HELLO\n",
+"6HeLLo\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/caseindep_java.rl b/test/trans.d/case/caseindep_java.rl
new file mode 100644
index 00000000..2156fe34
--- /dev/null
+++ b/test/trans.d/case/caseindep_java.rl
@@ -0,0 +1,85 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class caseindep_java
+{
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= indep_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1hello\n",
+"1HELLO\n",
+"1HeLLo\n",
+"2hello\n",
+"2HELLO\n",
+"2HeLLo\n",
+"3hello\n",
+"3HELLO\n",
+"3HeLLo\n",
+"4hello\n",
+"4HELLO\n",
+"4HeLLo\n",
+"5hello\n",
+"5HELLO\n",
+"5HeLLo\n",
+"6hello\n",
+"6HELLO\n",
+"6HeLLo\n",
+};
+
+static final int inplen = 18;
+
+public static void main (String[] args)
+{
+ caseindep_java machine = new caseindep_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/caseindep_julia.rl b/test/trans.d/case/caseindep_julia.rl
new file mode 100644
index 00000000..9a39658a
--- /dev/null
+++ b/test/trans.d/case/caseindep_julia.rl
@@ -0,0 +1,59 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= indep_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1hello\n" );
+ m( "1HELLO\n" );
+ m( "1HeLLo\n" );
+ m( "2hello\n" );
+ m( "2HELLO\n" );
+ m( "2HeLLo\n" );
+ m( "3hello\n" );
+ m( "3HELLO\n" );
+ m( "3HeLLo\n" );
+ m( "4hello\n" );
+ m( "4HELLO\n" );
+ m( "4HeLLo\n" );
+ m( "5hello\n" );
+ m( "5HELLO\n" );
+ m( "5HeLLo\n" );
+ m( "6hello\n" );
+ m( "6HELLO\n" );
+ m( "6HeLLo\n" );
diff --git a/test/trans.d/case/caseindep_ocaml.rl b/test/trans.d/case/caseindep_ocaml.rl
new file mode 100644
index 00000000..90aedfc4
--- /dev/null
+++ b/test/trans.d/case/caseindep_ocaml.rl
@@ -0,0 +1,61 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= indep_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1hello\n";
+ exec "1HELLO\n";
+ exec "1HeLLo\n";
+ exec "2hello\n";
+ exec "2HELLO\n";
+ exec "2HeLLo\n";
+ exec "3hello\n";
+ exec "3HELLO\n";
+ exec "3HeLLo\n";
+ exec "4hello\n";
+ exec "4HELLO\n";
+ exec "4HeLLo\n";
+ exec "5hello\n";
+ exec "5HELLO\n";
+ exec "5HeLLo\n";
+ exec "6hello\n";
+ exec "6HELLO\n";
+ exec "6HeLLo\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/caseindep_ruby.rl b/test/trans.d/case/caseindep_ruby.rl
new file mode 100644
index 00000000..3d21d0c9
--- /dev/null
+++ b/test/trans.d/case/caseindep_ruby.rl
@@ -0,0 +1,67 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= indep_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1hello\n",
+"1HELLO\n",
+"1HeLLo\n",
+"2hello\n",
+"2HELLO\n",
+"2HeLLo\n",
+"3hello\n",
+"3HELLO\n",
+"3HeLLo\n",
+"4hello\n",
+"4HELLO\n",
+"4HeLLo\n",
+"5hello\n",
+"5HELLO\n",
+"5HeLLo\n",
+"6hello\n",
+"6HELLO\n",
+"6HeLLo\n",
+]
+
+inplen = 18
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/caseindep_rust.rl b/test/trans.d/case/caseindep_rust.rl
new file mode 100644
index 00000000..281a9af5
--- /dev/null
+++ b/test/trans.d/case/caseindep_rust.rl
@@ -0,0 +1,66 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+%%{
+ machine indep;
+
+ main := (
+ ( '1' 'hello' ) |
+ ( '2' "hello" ) |
+ ( '3' /hello/ ) |
+ ( '4' 'hello'i ) |
+ ( '5' "hello"i ) |
+ ( '6' /hello/i )
+ ) '\n';
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= indep_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1hello\n".to_string() ); }
+ unsafe { m( "1HELLO\n".to_string() ); }
+ unsafe { m( "1HeLLo\n".to_string() ); }
+ unsafe { m( "2hello\n".to_string() ); }
+ unsafe { m( "2HELLO\n".to_string() ); }
+ unsafe { m( "2HeLLo\n".to_string() ); }
+ unsafe { m( "3hello\n".to_string() ); }
+ unsafe { m( "3HELLO\n".to_string() ); }
+ unsafe { m( "3HeLLo\n".to_string() ); }
+ unsafe { m( "4hello\n".to_string() ); }
+ unsafe { m( "4HELLO\n".to_string() ); }
+ unsafe { m( "4HeLLo\n".to_string() ); }
+ unsafe { m( "5hello\n".to_string() ); }
+ unsafe { m( "5HELLO\n".to_string() ); }
+ unsafe { m( "5HeLLo\n".to_string() ); }
+ unsafe { m( "6hello\n".to_string() ); }
+ unsafe { m( "6HELLO\n".to_string() ); }
+ unsafe { m( "6HeLLo\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/clang4.rl b/test/trans.d/case/clang4.rl
new file mode 100644
index 00000000..b033a479
--- /dev/null
+++ b/test/trans.d/case/clang4.rl
@@ -0,0 +1,187 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ */
+
+int pos;
+int line;
+
+pos = 0;
+line = 1;
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buf_append(); }
+
+ # Function to clear the buffer.
+ action clearBuf { buf_clear(); }
+
+ action incLine { line = line + 1; }
+
+ # Functions to dump tokens as they are matched.
+ action ident {
+ print_str "ident(";
+ print_int line;
+ print_str ",";
+ print_int blen;
+ print_str "): ";
+ print_str buffer;
+ print_str "\n";
+ }
+ action literal {
+ print_str "literal(";
+ print_int line;
+ print_str ",";
+ print_int blen;
+ print_str "): ";
+ print_str buffer;
+ print_str "\n";
+ }
+ action float {
+ print_str "float(";
+ print_int line;
+ print_str ",";
+ print_int blen;
+ print_str "): ";
+ print_str buffer;
+ print_str "\n";
+ }
+ action integer {
+ print_str "int(";
+ print_int line;
+ print_str ",";
+ print_int blen;
+ print_str "): ";
+ print_str buffer;
+ print_str "\n";
+ }
+ action hex {
+ print_str "hex(";
+ print_int line;
+ print_str ",";
+ print_int blen;
+ print_str "): ";
+ print_str buffer;
+ print_str "\n";
+ }
+ action symbol {
+ print_str "symbol(";
+ print_int line;
+ print_str ",";
+ print_int blen;
+ print_str "): ";
+ print_str buffer;
+ print_str "\n";
+ }
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+##### INPUT #####
+"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n"
+"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n"
+##### OUTPUT #####
+int(1,3): 999
+hex(1,6): aAFF99
+float(1,5): 99.99
+literal(2,5): lksdj
+literal(8,12):
+
+literal
+
+
+
+hex(8,5): 00aba
+ident(8,8): foobardd
+symbol(8,1): .
+ident(8,4): ddsf
+hex(8,1): 0
+symbol(8,1): .
+int(8,1): 9
+ACCEPT
+ident(1,17): wordwithnum00asdf
+int(2,3): 000
+ident(2,14): wordfollowsnum
+symbol(2,1): ,
+ident(2,5): makes
+ident(2,3): new
+ident(2,6): symbol
+ident(4,9): finishing
+ident(4,5): early
+FAIL
diff --git a/test/trans.d/case/clang4_asm.rl b/test/trans.d/case/clang4_asm.rl
new file mode 100644
index 00000000..882cd148
--- /dev/null
+++ b/test/trans.d/case/clang4_asm.rl
@@ -0,0 +1,603 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm pos,8,8
+ .text
+ .section .data
+ .comm line,8,8
+ .text
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar {
+ movq bpos(%rip), %rax
+ movb (%r12), %cl
+ movb %cl, buf(%rax)
+ addq $1, %rax
+ movb $0, buf(%rax)
+ movq %rax, bpos(%rip)
+
+}
+
+ # Function to clear the buffer.
+ action clearBuf {
+ movq $0, bpos(%rip)
+
+}
+
+ action incLine {
+ movq line (%rip), %rax
+ pushq %rax
+ movq $1, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, line (%rip)
+
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {
+ .section .rodata
+1:
+ .string "ident("
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq line(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+2:
+ .string ","
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq bpos(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+3:
+ .string "): "
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $buf, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+4:
+ .string "\n"
+ .text
+ movq $4b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action literal {
+ .section .rodata
+5:
+ .string "literal("
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq line(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+6:
+ .string ","
+ .text
+ movq $6b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq bpos(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+7:
+ .string "): "
+ .text
+ movq $7b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $buf, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+8:
+ .string "\n"
+ .text
+ movq $8b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action float {
+ .section .rodata
+9:
+ .string "float("
+ .text
+ movq $9b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq line(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+10:
+ .string ","
+ .text
+ movq $10b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq bpos(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+11:
+ .string "): "
+ .text
+ movq $11b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $buf, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+12:
+ .string "\n"
+ .text
+ movq $12b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action integer {
+ .section .rodata
+13:
+ .string "int("
+ .text
+ movq $13b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq line(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+14:
+ .string ","
+ .text
+ movq $14b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq bpos(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+15:
+ .string "): "
+ .text
+ movq $15b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $buf, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+16:
+ .string "\n"
+ .text
+ movq $16b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action hex {
+ .section .rodata
+17:
+ .string "hex("
+ .text
+ movq $17b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq line(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+18:
+ .string ","
+ .text
+ movq $18b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq bpos(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+19:
+ .string "): "
+ .text
+ movq $19b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $buf, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+20:
+ .string "\n"
+ .text
+ movq $20b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action symbol {
+ .section .rodata
+21:
+ .string "symbol("
+ .text
+ movq $21b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq line(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+22:
+ .string ","
+ .text
+ movq $22b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq bpos(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+23:
+ .string "): "
+ .text
+ movq $23b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $buf, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+24:
+ .string "\n"
+ .text
+ movq $24b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, pos (%rip)
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, line (%rip)
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq clang_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n"
+.L_inp_1:
+ .string "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+
+ .align 8
+inplen:
+ .quad 2
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/clang4_c.rl b/test/trans.d/case/clang4_c.rl
new file mode 100644
index 00000000..b64d027a
--- /dev/null
+++ b/test/trans.d/case/clang4_c.rl
@@ -0,0 +1,202 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int pos ;
+int line ;
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer[blen++] = *p;
+ buffer[blen] = 0;
+}
+
+ # Function to clear the buffer.
+ action clearBuf { blen = 0;
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {printf( "%s", "ident(" );
+printf( "%d", line );
+printf( "%s", "," );
+printf( "%d", blen );
+printf( "%s", "): " );
+printf( "%s", buffer );
+printf( "%s", "\n" );
+}
+ action literal {printf( "%s", "literal(" );
+printf( "%d", line );
+printf( "%s", "," );
+printf( "%d", blen );
+printf( "%s", "): " );
+printf( "%s", buffer );
+printf( "%s", "\n" );
+}
+ action float {printf( "%s", "float(" );
+printf( "%d", line );
+printf( "%s", "," );
+printf( "%d", blen );
+printf( "%s", "): " );
+printf( "%s", buffer );
+printf( "%s", "\n" );
+}
+ action integer {printf( "%s", "int(" );
+printf( "%d", line );
+printf( "%s", "," );
+printf( "%d", blen );
+printf( "%s", "): " );
+printf( "%s", buffer );
+printf( "%s", "\n" );
+}
+ action hex {printf( "%s", "hex(" );
+printf( "%d", line );
+printf( "%s", "," );
+printf( "%d", blen );
+printf( "%s", "): " );
+printf( "%s", buffer );
+printf( "%s", "\n" );
+}
+ action symbol {printf( "%s", "symbol(" );
+printf( "%d", line );
+printf( "%s", "," );
+printf( "%d", blen );
+printf( "%s", "): " );
+printf( "%s", buffer );
+printf( "%s", "\n" );
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+pos = 0;
+line = 1;
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= clang_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n",
+"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n",
+};
+
+int inplen = 2;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/clang4_crack.rl b/test/trans.d/case/clang4_crack.rl
new file mode 100644
index 00000000..c15c5c60
--- /dev/null
+++ b/test/trans.d/case/clang4_crack.rl
@@ -0,0 +1,186 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int pos;
+int line;
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer = buffer + fc;
+}
+
+ # Function to clear the buffer.
+ action clearBuf { buffer = "";
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {cout.format( "ident(" );
+cout.format( line );
+cout.format( "," );
+cout.format( buffer.size );
+cout.format( "): " );
+cout.format( buffer );
+cout.format( "\n" );
+}
+ action literal {cout.format( "literal(" );
+cout.format( line );
+cout.format( "," );
+cout.format( buffer.size );
+cout.format( "): " );
+cout.format( buffer );
+cout.format( "\n" );
+}
+ action float {cout.format( "float(" );
+cout.format( line );
+cout.format( "," );
+cout.format( buffer.size );
+cout.format( "): " );
+cout.format( buffer );
+cout.format( "\n" );
+}
+ action integer {cout.format( "int(" );
+cout.format( line );
+cout.format( "," );
+cout.format( buffer.size );
+cout.format( "): " );
+cout.format( buffer );
+cout.format( "\n" );
+}
+ action hex {cout.format( "hex(" );
+cout.format( line );
+cout.format( "," );
+cout.format( buffer.size );
+cout.format( "): " );
+cout.format( buffer );
+cout.format( "\n" );
+}
+ action symbol {cout.format( "symbol(" );
+cout.format( line );
+cout.format( "," );
+cout.format( buffer.size );
+cout.format( "): " );
+cout.format( buffer );
+cout.format( "\n" );
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+pos = 0;
+line = 1;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= clang_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n" );
+ m( "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n" );
+}
+
+main();
diff --git a/test/trans.d/case/clang4_cs.rl b/test/trans.d/case/clang4_cs.rl
new file mode 100644
index 00000000..19bcdc9a
--- /dev/null
+++ b/test/trans.d/case/clang4_cs.rl
@@ -0,0 +1,169 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int pos;
+int line;
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer[blen++] = fc;
+}
+
+ # Function to clear the buffer.
+ action clearBuf { blen = 0;
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {Console.Write( "ident(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen )
+ );Console.Write( "\n" );}
+ action literal {Console.Write( "literal(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen )
+ );Console.Write( "\n" );}
+ action float {Console.Write( "float(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen )
+ );Console.Write( "\n" );}
+ action integer {Console.Write( "int(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen )
+ );Console.Write( "\n" );}
+ action hex {Console.Write( "hex(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen )
+ );Console.Write( "\n" );}
+ action symbol {Console.Write( "symbol(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen )
+ );Console.Write( "\n" );}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+pos = 0;
+line = 1;
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= clang_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n",
+"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n",
+};
+
+
+static readonly int inplen = 2;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/clang4_d.rl b/test/trans.d/case/clang4_d.rl
new file mode 100644
index 00000000..3c890ca3
--- /dev/null
+++ b/test/trans.d/case/clang4_d.rl
@@ -0,0 +1,176 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class clang
+{
+int pos;
+int line;
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer[blen++] = *p;
+ buffer[blen] = 0;
+}
+
+ # Function to clear the buffer.
+ action clearBuf { blen = 0;
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {printf( "%.*s", "ident(" );printf( "%d", line );
+printf( "%.*s", "," );printf( "%d", blen );
+printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );}
+ action literal {printf( "%.*s", "literal(" );printf( "%d", line );
+printf( "%.*s", "," );printf( "%d", blen );
+printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );}
+ action float {printf( "%.*s", "float(" );printf( "%d", line );
+printf( "%.*s", "," );printf( "%d", blen );
+printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );}
+ action integer {printf( "%.*s", "int(" );printf( "%d", line );
+printf( "%.*s", "," );printf( "%d", blen );
+printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );}
+ action hex {printf( "%.*s", "hex(" );printf( "%d", line );
+printf( "%.*s", "," );printf( "%d", blen );
+printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );}
+ action symbol {printf( "%.*s", "symbol(" );printf( "%d", line );
+printf( "%.*s", "," );printf( "%d", blen );
+printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+pos = 0;
+line = 1;
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= clang_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n",
+"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n",
+];
+
+int inplen = 2;
+
+}
+int main()
+{
+ clang m = new clang();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/clang4_go.rl b/test/trans.d/case/clang4_go.rl
new file mode 100644
index 00000000..bbdd169e
--- /dev/null
+++ b/test/trans.d/case/clang4_go.rl
@@ -0,0 +1,151 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var pos int ;
+var line int ;
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer[blen] = fc;
+ blen += 1;
+ buffer[blen] = 0;
+}
+
+ # Function to clear the buffer.
+ action clearBuf { blen = 0;
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {fmt.Print( "ident(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );}
+ action literal {fmt.Print( "literal(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );}
+ action float {fmt.Print( "float(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );}
+ action integer {fmt.Print( "int(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );}
+ action hex {fmt.Print( "hex(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );}
+ action symbol {fmt.Print( "symbol(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+pos = 0;
+line = 1;
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= clang_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n",
+"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/clang4_java.rl b/test/trans.d/case/clang4_java.rl
new file mode 100644
index 00000000..cd5e9b93
--- /dev/null
+++ b/test/trans.d/case/clang4_java.rl
@@ -0,0 +1,203 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class clang4_java
+{
+int pos ;
+int line ;
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer[blen] = fc;
+ blen += 1;
+}
+
+ # Function to clear the buffer.
+ action clearBuf { blen = 0;
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {System.out.print( "ident(" );
+System.out.print( line );
+System.out.print( "," );
+System.out.print( blen );
+System.out.print( "): " );
+System.out.print( new String( buffer, 0, blen ) );
+System.out.print( "\n" );
+}
+ action literal {System.out.print( "literal(" );
+System.out.print( line );
+System.out.print( "," );
+System.out.print( blen );
+System.out.print( "): " );
+System.out.print( new String( buffer, 0, blen ) );
+System.out.print( "\n" );
+}
+ action float {System.out.print( "float(" );
+System.out.print( line );
+System.out.print( "," );
+System.out.print( blen );
+System.out.print( "): " );
+System.out.print( new String( buffer, 0, blen ) );
+System.out.print( "\n" );
+}
+ action integer {System.out.print( "int(" );
+System.out.print( line );
+System.out.print( "," );
+System.out.print( blen );
+System.out.print( "): " );
+System.out.print( new String( buffer, 0, blen ) );
+System.out.print( "\n" );
+}
+ action hex {System.out.print( "hex(" );
+System.out.print( line );
+System.out.print( "," );
+System.out.print( blen );
+System.out.print( "): " );
+System.out.print( new String( buffer, 0, blen ) );
+System.out.print( "\n" );
+}
+ action symbol {System.out.print( "symbol(" );
+System.out.print( line );
+System.out.print( "," );
+System.out.print( blen );
+System.out.print( "): " );
+System.out.print( new String( buffer, 0, blen ) );
+System.out.print( "\n" );
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+pos = 0;
+line = 1;
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= clang_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n",
+"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n",
+};
+
+static final int inplen = 2;
+
+public static void main (String[] args)
+{
+ clang4_java machine = new clang4_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/clang4_julia.rl b/test/trans.d/case/clang4_julia.rl
new file mode 100644
index 00000000..86094bbb
--- /dev/null
+++ b/test/trans.d/case/clang4_julia.rl
@@ -0,0 +1,175 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer = buffer * AbstractString(Char[fc]);
+}
+
+ # Function to clear the buffer.
+ action clearBuf { buffer = "";
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {print( "ident(" );
+print( line );
+print( "," );
+print( length(buffer) );
+print( "): " );
+print( buffer );
+print( "\n" );
+}
+ action literal {print( "literal(" );
+print( line );
+print( "," );
+print( length(buffer) );
+print( "): " );
+print( buffer );
+print( "\n" );
+}
+ action float {print( "float(" );
+print( line );
+print( "," );
+print( length(buffer) );
+print( "): " );
+print( buffer );
+print( "\n" );
+}
+ action integer {print( "int(" );
+print( line );
+print( "," );
+print( length(buffer) );
+print( "): " );
+print( buffer );
+print( "\n" );
+}
+ action hex {print( "hex(" );
+print( line );
+print( "," );
+print( length(buffer) );
+print( "): " );
+print( buffer );
+print( "\n" );
+}
+ action symbol {print( "symbol(" );
+print( line );
+print( "," );
+print( length(buffer) );
+print( "): " );
+print( buffer );
+print( "\n" );
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+pos = 0;
+line = 0;
+pos = 0;
+line = 1;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= clang_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n" );
+ m( "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n" );
diff --git a/test/trans.d/case/clang4_ocaml.rl b/test/trans.d/case/clang4_ocaml.rl
new file mode 100644
index 00000000..d9689faf
--- /dev/null
+++ b/test/trans.d/case/clang4_ocaml.rl
@@ -0,0 +1,183 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let pos = ref 0
+let line = ref 0
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { begin
+ String.set buffer blen.contents data.[p.contents];
+ blen := blen.contents + 1;
+ end
+}
+
+ # Function to clear the buffer.
+ action clearBuf {begin
+ blen := 0;
+end
+}
+
+ action incLine {line := line .contents + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {print_string( "ident(" );
+print_int( line.contents );
+print_string( "," );
+print_int( blen.contents );
+print_string( "): " );
+print_string( String.sub buffer 0 blen.contents );
+print_string( "\n" );
+}
+ action literal {print_string( "literal(" );
+print_int( line.contents );
+print_string( "," );
+print_int( blen.contents );
+print_string( "): " );
+print_string( String.sub buffer 0 blen.contents );
+print_string( "\n" );
+}
+ action float {print_string( "float(" );
+print_int( line.contents );
+print_string( "," );
+print_int( blen.contents );
+print_string( "): " );
+print_string( String.sub buffer 0 blen.contents );
+print_string( "\n" );
+}
+ action integer {print_string( "int(" );
+print_int( line.contents );
+print_string( "," );
+print_int( blen.contents );
+print_string( "): " );
+print_string( String.sub buffer 0 blen.contents );
+print_string( "\n" );
+}
+ action hex {print_string( "hex(" );
+print_int( line.contents );
+print_string( "," );
+print_int( blen.contents );
+print_string( "): " );
+print_string( String.sub buffer 0 blen.contents );
+print_string( "\n" );
+}
+ action symbol {print_string( "symbol(" );
+print_int( line.contents );
+print_string( "," );
+print_int( blen.contents );
+print_string( "): " );
+print_string( String.sub buffer 0 blen.contents );
+print_string( "\n" );
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+pos := 0;
+line := 1;
+ %% write init;
+ %% write exec;
+ if !cs >= clang_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n";
+ exec "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/clang4_ruby.rl b/test/trans.d/case/clang4_ruby.rl
new file mode 100644
index 00000000..383d6d34
--- /dev/null
+++ b/test/trans.d/case/clang4_ruby.rl
@@ -0,0 +1,184 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer[blen] = fc;
+ blen += 1;
+}
+
+ # Function to clear the buffer.
+ action clearBuf { blen = 0;
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {print( "ident(" );
+print( line );
+print( "," );
+print( blen );
+print( "): " );
+print( buffer[0..blen-1].pack( "c*" ) );
+print( "\n" );
+}
+ action literal {print( "literal(" );
+print( line );
+print( "," );
+print( blen );
+print( "): " );
+print( buffer[0..blen-1].pack( "c*" ) );
+print( "\n" );
+}
+ action float {print( "float(" );
+print( line );
+print( "," );
+print( blen );
+print( "): " );
+print( buffer[0..blen-1].pack( "c*" ) );
+print( "\n" );
+}
+ action integer {print( "int(" );
+print( line );
+print( "," );
+print( blen );
+print( "): " );
+print( buffer[0..blen-1].pack( "c*" ) );
+print( "\n" );
+}
+ action hex {print( "hex(" );
+print( line );
+print( "," );
+print( blen );
+print( "): " );
+print( buffer[0..blen-1].pack( "c*" ) );
+print( "\n" );
+}
+ action symbol {print( "symbol(" );
+print( line );
+print( "," );
+print( blen );
+print( "): " );
+print( buffer[0..blen-1].pack( "c*" ) );
+print( "\n" );
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+pos = 1
+line = 1
+pos = 0;
+line = 1;
+ %% write init;
+ %% write exec;
+ if cs >= clang_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n",
+"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n",
+]
+
+inplen = 2
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/clang4_rust.rl b/test/trans.d/case/clang4_rust.rl
new file mode 100644
index 00000000..b77a8aec
--- /dev/null
+++ b/test/trans.d/case/clang4_rust.rl
@@ -0,0 +1,182 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut pos : i32 = 0;
+static mut line : i32 = 0;
+
+%%{
+ machine clang;
+
+ # Function to buffer a character.
+ action bufChar { buffer.push( ( fc ) as char );
+}
+
+ # Function to clear the buffer.
+ action clearBuf { buffer = String::new();
+}
+
+ action incLine {line = line + 1;
+}
+
+ # Functions to dump tokens as they are matched.
+ action ident {print!( "{}", "ident(" );
+print!( "{}", line );
+print!( "{}", "," );
+print!( "{}", buffer.len() );
+print!( "{}", "): " );
+print!( "{}", buffer );
+print!( "{}", "\n" );
+}
+ action literal {print!( "{}", "literal(" );
+print!( "{}", line );
+print!( "{}", "," );
+print!( "{}", buffer.len() );
+print!( "{}", "): " );
+print!( "{}", buffer );
+print!( "{}", "\n" );
+}
+ action float {print!( "{}", "float(" );
+print!( "{}", line );
+print!( "{}", "," );
+print!( "{}", buffer.len() );
+print!( "{}", "): " );
+print!( "{}", buffer );
+print!( "{}", "\n" );
+}
+ action integer {print!( "{}", "int(" );
+print!( "{}", line );
+print!( "{}", "," );
+print!( "{}", buffer.len() );
+print!( "{}", "): " );
+print!( "{}", buffer );
+print!( "{}", "\n" );
+}
+ action hex {print!( "{}", "hex(" );
+print!( "{}", line );
+print!( "{}", "," );
+print!( "{}", buffer.len() );
+print!( "{}", "): " );
+print!( "{}", buffer );
+print!( "{}", "\n" );
+}
+ action symbol {print!( "{}", "symbol(" );
+print!( "{}", line );
+print!( "{}", "," );
+print!( "{}", buffer.len() );
+print!( "{}", "): " );
+print!( "{}", buffer );
+print!( "{}", "\n" );
+}
+
+ # Alpha numberic characters or underscore.
+ alnumu = alnum | '_';
+
+ # Alpha charactres or underscore.
+ alphau = alpha | '_';
+
+ # Symbols. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving dump the symbol.
+ symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol;
+
+ # Identifier. Upon entering clear the buffer. On all transitions
+ # buffer a character. Upon leaving, dump the identifier.
+ ident = (alphau . alnumu*) >clearBuf $bufChar %ident;
+
+ # Match single characters inside literal strings. Or match
+ # an escape sequence. Buffers the charater matched.
+ sliteralChar =
+ ( extend - ['\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+ dliteralChar =
+ ( extend - ["\\] ) @bufChar |
+ ( '\\' . extend @bufChar );
+
+ # Single quote and double quota literals. At the start clear
+ # the buffer. Upon leaving dump the literal.
+ sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal;
+ dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal;
+ literal = sliteral | dliteral;
+
+ # Whitespace is standard ws, newlines and control codes.
+ whitespace = any - 33 .. 126;
+
+ # Describe both c style comments and c++ style comments. The
+ # priority bump on tne terminator of the comments brings us
+ # out of the extend* which matches everything.
+ ccComment = '//' . extend* $0 . '\n' @1;
+ cComment = '/!' . extend* $0 . '!/' @1;
+
+ # Match an integer. We don't bother clearing the buf or filling it.
+ # The float machine overlaps with int and it will do it.
+ integer = digit+ %integer;
+
+ # Match a float. Upon entering the machine clear the buf, buffer
+ # characters on every trans and dump the float upon leaving.
+ float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float;
+
+ # Match a hex. Upon entering the hex part, clear the buf, buffer characters
+ # on every trans and dump the hex on leaving transitions.
+ hex = '0x' . xdigit+ >clearBuf $bufChar %hex;
+
+ # Or together all the lanuage elements.
+ fin = ( ccComment |
+ cComment |
+ symbol |
+ ident |
+ literal |
+ whitespace |
+ integer |
+ float |
+ hex );
+
+ # Star the language elements. It is critical in this type of application
+ # that we decrease the priority of out transitions before doing so. This
+ # is so that when we see 'aa' we stay in the fin machine to match an ident
+ # of length two and not wrap around to the front to match two idents of
+ # length one.
+ clang_main = ( fin $1 %0 )*;
+
+ # This machine matches everything, taking note of newlines.
+ newline = ( any | '\n' @incLine )*;
+
+ # The final fsm is the lexer intersected with the newline machine which
+ # will count lines for us. Since the newline machine accepts everything,
+ # the strings accepted is goverened by the clang_main machine, onto which
+ # the newline machine overlays line counting.
+ main := clang_main & newline;
+}%%
+
+
+
+%% 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();
+pos = 0;
+line = 1;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= clang_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n".to_string() ); }
+ unsafe { m( "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/cond1.rl b/test/trans.d/case/cond1.rl
new file mode 100644
index 00000000..cd96c0ec
--- /dev/null
+++ b/test/trans.d/case/cond1.rl
@@ -0,0 +1,84 @@
+/*
+ * @LANG: indep
+ */
+
+bool i;
+bool j;
+bool k;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one { print_str " one\n";}
+ action two { print_str " two\n";}
+ action three { print_str " three\n";}
+
+ action seti {
+ if ( fc == 48 ) {
+ i = false;
+ } else {
+ i = true;
+ }
+ }
+ action setj {
+ if ( fc == 48 ) {
+ j = false;
+ } else {
+ j = true;
+ }
+ }
+ action setk {
+ if ( fc == 48 ) {
+ k = false;
+ } else {
+ k = true;
+ }
+ }
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+##### INPUT #####
+"000abc\n"
+"100abc\n"
+"010abc\n"
+"110abc\n"
+"001abc\n"
+"101abc\n"
+"011abc\n"
+"111abc\n"
+##### OUTPUT #####
+FAIL
+ one
+ACCEPT
+ two
+ACCEPT
+ one
+ two
+ACCEPT
+ three
+ACCEPT
+ one
+ three
+ACCEPT
+ two
+ three
+ACCEPT
+ one
+ two
+ three
+ACCEPT
diff --git a/test/trans.d/case/cond1_asm.rl b/test/trans.d/case/cond1_asm.rl
new file mode 100644
index 00000000..82904376
--- /dev/null
+++ b/test/trans.d/case/cond1_asm.rl
@@ -0,0 +1,319 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm i,8,8
+ .text
+ .section .data
+ .comm j,8,8
+ .text
+ .section .data
+ .comm k,8,8
+ .text
+
+%%{
+ machine foo;
+
+ action c1 {
+ movq i (%rip), %rax
+ pushq %rax
+ movq $0, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ setne %al
+ movsbq %al, %rax
+ pushq %rax
+
+ popq %rax
+}
+ action c2 {
+ movq j (%rip), %rax
+ pushq %rax
+ movq $0, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ setne %al
+ movsbq %al, %rax
+ pushq %rax
+
+ popq %rax
+}
+ action c3 {
+ movq k (%rip), %rax
+ pushq %rax
+ movq $0, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ setne %al
+ movsbq %al, %rax
+ pushq %rax
+
+ popq %rax
+}
+ action one {
+ .section .rodata
+1:
+ .string " one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action two {
+ .section .rodata
+2:
+ .string " two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action three {
+ .section .rodata
+3:
+ .string " three\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ action seti {
+ movsbq (%r12), %rax
+ pushq %rax
+ movq $48 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 4f
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, i (%rip)
+ jmp 5f
+4:
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, i (%rip)
+5:
+
+}
+ action setj {
+ movsbq (%r12), %rax
+ pushq %rax
+ movq $48 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 6f
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, j (%rip)
+ jmp 7f
+6:
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, j (%rip)
+7:
+
+}
+ action setk {
+ movsbq (%r12), %rax
+ pushq %rax
+ movq $48 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 8f
+ movq $0, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, k (%rip)
+ jmp 9f
+8:
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, k (%rip)
+9:
+
+}
+
+ action break {
+ fnbreak;
+
+}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq foo_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "000abc\n"
+.L_inp_1:
+ .string "100abc\n"
+.L_inp_2:
+ .string "010abc\n"
+.L_inp_3:
+ .string "110abc\n"
+.L_inp_4:
+ .string "001abc\n"
+.L_inp_5:
+ .string "101abc\n"
+.L_inp_6:
+ .string "011abc\n"
+.L_inp_7:
+ .string "111abc\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+
+ .align 8
+inplen:
+ .quad 8
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/cond1_c.rl b/test/trans.d/case/cond1_c.rl
new file mode 100644
index 00000000..4ec07430
--- /dev/null
+++ b/test/trans.d/case/cond1_c.rl
@@ -0,0 +1,121 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int i ;
+int j ;
+int k ;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {printf( "%s", " one\n" );
+}
+ action two {printf( "%s", " two\n" );
+}
+ action three {printf( "%s", " three\n" );
+}
+
+ action seti {if ( fc == 48 )
+{
+ i = 0;
+
+}
+else {
+ i = 1;
+
+}
+}
+ action setj {if ( fc == 48 )
+{
+ j = 0;
+
+}
+else {
+ j = 1;
+
+}
+}
+ action setk {if ( fc == 48 )
+{
+ k = 0;
+
+}
+else {
+ k = 1;
+
+}
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"000abc\n",
+"100abc\n",
+"010abc\n",
+"110abc\n",
+"001abc\n",
+"101abc\n",
+"011abc\n",
+"111abc\n",
+};
+
+int inplen = 8;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/cond1_crack.rl b/test/trans.d/case/cond1_crack.rl
new file mode 100644
index 00000000..cfab3d11
--- /dev/null
+++ b/test/trans.d/case/cond1_crack.rl
@@ -0,0 +1,106 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int i;
+int j;
+int k;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {cout.format( " one\n" );
+}
+ action two {cout.format( " two\n" );
+}
+ action three {cout.format( " three\n" );
+}
+
+ action seti {if ( fc == 48 )
+{
+ i = 0;
+
+}
+else {
+ i = 1;
+
+}
+}
+ action setj {if ( fc == 48 )
+{
+ j = 0;
+
+}
+else {
+ j = 1;
+
+}
+}
+ action setk {if ( fc == 48 )
+{
+ k = 0;
+
+}
+else {
+ k = 1;
+
+}
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= foo_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "000abc\n" );
+ m( "100abc\n" );
+ m( "010abc\n" );
+ m( "110abc\n" );
+ m( "001abc\n" );
+ m( "101abc\n" );
+ m( "011abc\n" );
+ m( "111abc\n" );
+}
+
+main();
diff --git a/test/trans.d/case/cond1_cs.rl b/test/trans.d/case/cond1_cs.rl
new file mode 100644
index 00000000..5b1c2b42
--- /dev/null
+++ b/test/trans.d/case/cond1_cs.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int i;
+int j;
+int k;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {Console.Write( " one\n" );}
+ action two {Console.Write( " two\n" );}
+ action three {Console.Write( " three\n" );}
+
+ action seti {if ( fc == 48 )
+{
+ i = 0;
+
+}
+else {
+ i = 1;
+
+}
+}
+ action setj {if ( fc == 48 )
+{
+ j = 0;
+
+}
+else {
+ j = 1;
+
+}
+}
+ action setk {if ( fc == 48 )
+{
+ k = 0;
+
+}
+else {
+ k = 1;
+
+}
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"000abc\n",
+"100abc\n",
+"010abc\n",
+"110abc\n",
+"001abc\n",
+"101abc\n",
+"011abc\n",
+"111abc\n",
+};
+
+
+static readonly int inplen = 8;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/cond1_d.rl b/test/trans.d/case/cond1_d.rl
new file mode 100644
index 00000000..113bdc36
--- /dev/null
+++ b/test/trans.d/case/cond1_d.rl
@@ -0,0 +1,122 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class foo
+{
+int i;
+int j;
+int k;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {printf( "%.*s", " one\n" );}
+ action two {printf( "%.*s", " two\n" );}
+ action three {printf( "%.*s", " three\n" );}
+
+ action seti {if ( fc == 48 )
+{
+ i = 0;
+
+}
+else {
+ i = 1;
+
+}
+}
+ action setj {if ( fc == 48 )
+{
+ j = 0;
+
+}
+else {
+ j = 1;
+
+}
+}
+ action setk {if ( fc == 48 )
+{
+ k = 0;
+
+}
+else {
+ k = 1;
+
+}
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"000abc\n",
+"100abc\n",
+"010abc\n",
+"110abc\n",
+"001abc\n",
+"101abc\n",
+"011abc\n",
+"111abc\n",
+];
+
+int inplen = 8;
+
+}
+int main()
+{
+ foo m = new foo();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/cond1_go.rl b/test/trans.d/case/cond1_go.rl
new file mode 100644
index 00000000..20904188
--- /dev/null
+++ b/test/trans.d/case/cond1_go.rl
@@ -0,0 +1,103 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var i int ;
+var j int ;
+var k int ;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {fmt.Print( " one\n" );}
+ action two {fmt.Print( " two\n" );}
+ action three {fmt.Print( " three\n" );}
+
+ action seti {if ( fc == 48 ) {
+ i = 0;
+
+} else {
+ i = 1;
+
+}
+}
+ action setj {if ( fc == 48 ) {
+ j = 0;
+
+} else {
+ j = 1;
+
+}
+}
+ action setk {if ( fc == 48 ) {
+ k = 0;
+
+} else {
+ k = 1;
+
+}
+}
+
+ action break {fnbreak;
+}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= foo_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"000abc\n",
+"100abc\n",
+"010abc\n",
+"110abc\n",
+"001abc\n",
+"101abc\n",
+"011abc\n",
+"111abc\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/cond1_java.rl b/test/trans.d/case/cond1_java.rl
new file mode 100644
index 00000000..a49f1844
--- /dev/null
+++ b/test/trans.d/case/cond1_java.rl
@@ -0,0 +1,122 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class cond1_java
+{
+int i ;
+int j ;
+int k ;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {System.out.print( " one\n" );
+}
+ action two {System.out.print( " two\n" );
+}
+ action three {System.out.print( " three\n" );
+}
+
+ action seti {if ( fc == 48 )
+{
+ i = 0;
+
+}
+else {
+ i = 1;
+
+}
+}
+ action setj {if ( fc == 48 )
+{
+ j = 0;
+
+}
+else {
+ j = 1;
+
+}
+}
+ action setk {if ( fc == 48 )
+{
+ k = 0;
+
+}
+else {
+ k = 1;
+
+}
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"000abc\n",
+"100abc\n",
+"010abc\n",
+"110abc\n",
+"001abc\n",
+"101abc\n",
+"011abc\n",
+"111abc\n",
+};
+
+static final int inplen = 8;
+
+public static void main (String[] args)
+{
+ cond1_java machine = new cond1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/cond1_julia.rl b/test/trans.d/case/cond1_julia.rl
new file mode 100644
index 00000000..ca40d50c
--- /dev/null
+++ b/test/trans.d/case/cond1_julia.rl
@@ -0,0 +1,90 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {print( " one\n" );
+}
+ action two {print( " two\n" );
+}
+ action three {print( " three\n" );
+}
+
+ action seti {if ( fc == 48 )
+ i = 0;
+
+else
+ i = 1;
+
+end
+}
+ action setj {if ( fc == 48 )
+ j = 0;
+
+else
+ j = 1;
+
+end
+}
+ action setk {if ( fc == 48 )
+ k = 0;
+
+else
+ k = 1;
+
+end
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+i = 0;
+j = 0;
+k = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= foo_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "000abc\n" );
+ m( "100abc\n" );
+ m( "010abc\n" );
+ m( "110abc\n" );
+ m( "001abc\n" );
+ m( "101abc\n" );
+ m( "011abc\n" );
+ m( "111abc\n" );
diff --git a/test/trans.d/case/cond1_ocaml.rl b/test/trans.d/case/cond1_ocaml.rl
new file mode 100644
index 00000000..4c01cd53
--- /dev/null
+++ b/test/trans.d/case/cond1_ocaml.rl
@@ -0,0 +1,104 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let i = ref 0
+let j = ref 0
+let k = ref 0
+
+%%{
+ machine foo;
+
+ action c1 {i .contents != 0}
+ action c2 {j .contents != 0}
+ action c3 {k .contents != 0}
+ action one {print_string( " one\n" );
+}
+ action two {print_string( " two\n" );
+}
+ action three {print_string( " three\n" );
+}
+
+ action seti {if fc == 48 then
+begin
+ i := 0;
+
+end
+else
+begin
+ i := 1;
+
+end
+;
+}
+ action setj {if fc == 48 then
+begin
+ j := 0;
+
+end
+else
+begin
+ j := 1;
+
+end
+;
+}
+ action setk {if fc == 48 then
+begin
+ k := 0;
+
+end
+else
+begin
+ k := 1;
+
+end
+;
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= foo_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "000abc\n";
+ exec "100abc\n";
+ exec "010abc\n";
+ exec "110abc\n";
+ exec "001abc\n";
+ exec "101abc\n";
+ exec "011abc\n";
+ exec "111abc\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/cond1_ruby.rl b/test/trans.d/case/cond1_ruby.rl
new file mode 100644
index 00000000..cfbfbcb0
--- /dev/null
+++ b/test/trans.d/case/cond1_ruby.rl
@@ -0,0 +1,98 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {print( " one\n" );
+}
+ action two {print( " two\n" );
+}
+ action three {print( " three\n" );
+}
+
+ action seti {if ( fc == 48 )
+ i = 0;
+
+else
+ i = 1;
+
+end
+}
+ action setj {if ( fc == 48 )
+ j = 0;
+
+else
+ j = 1;
+
+end
+}
+ action setk {if ( fc == 48 )
+ k = 0;
+
+else
+ k = 1;
+
+end
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+i = 1
+j = 1
+k = 1
+ %% write init;
+ %% write exec;
+ if cs >= foo_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"000abc\n",
+"100abc\n",
+"010abc\n",
+"110abc\n",
+"001abc\n",
+"101abc\n",
+"011abc\n",
+"111abc\n",
+]
+
+inplen = 8
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/cond1_rust.rl b/test/trans.d/case/cond1_rust.rl
new file mode 100644
index 00000000..829da378
--- /dev/null
+++ b/test/trans.d/case/cond1_rust.rl
@@ -0,0 +1,103 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut i : i8 = 0;
+static mut j : i8 = 0;
+static mut k : i8 = 0;
+
+%%{
+ machine foo;
+
+ action c1 {i != 0}
+ action c2 {j != 0}
+ action c3 {k != 0}
+ action one {print!( "{}", " one\n" );
+}
+ action two {print!( "{}", " two\n" );
+}
+ action three {print!( "{}", " three\n" );
+}
+
+ action seti {if ( fc == 48 )
+{
+ i = 0;
+
+}
+else {
+ i = 1;
+
+}
+}
+ action setj {if ( fc == 48 )
+{
+ j = 0;
+
+}
+else {
+ j = 1;
+
+}
+}
+ action setk {if ( fc == 48 )
+{
+ k = 0;
+
+}
+else {
+ k = 1;
+
+}
+}
+
+ action break {fnbreak;}
+
+ one = 'a' 'b' when c1 'c' @one;
+ two = 'a'* 'b' when c2 'c' @two;
+ three = 'a'+ 'b' when c3 'c' @three;
+
+ main :=
+ [01] @seti
+ [01] @setj
+ [01] @setk
+ ( one | two | three ) '\n' @break;
+
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= foo_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "000abc\n".to_string() ); }
+ unsafe { m( "100abc\n".to_string() ); }
+ unsafe { m( "010abc\n".to_string() ); }
+ unsafe { m( "110abc\n".to_string() ); }
+ unsafe { m( "001abc\n".to_string() ); }
+ unsafe { m( "101abc\n".to_string() ); }
+ unsafe { m( "011abc\n".to_string() ); }
+ unsafe { m( "111abc\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/cond7.rl b/test/trans.d/case/cond7.rl
new file mode 100644
index 00000000..2fb66b4b
--- /dev/null
+++ b/test/trans.d/case/cond7.rl
@@ -0,0 +1,80 @@
+/*
+ * @LANG: indep
+ */
+
+int i;
+int c;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {
+ i = i - 1;
+ c = <int>(fc);
+ print_str "item: ";
+ print_int c;
+ print_str "\n";
+ }
+
+ count = [0-9] @{
+ i = <int>(fc - 48);
+ print_str "count: ";
+ print_int i;
+ print_str "\n";
+ };
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+##### INPUT #####
+"00\n"
+"019\n"
+"190\n"
+"1719\n"
+"1040000\n"
+"104000a\n"
+"104000\n"
+##### OUTPUT #####
+count: 0
+count: 0
+ACCEPT
+count: 0
+count: 1
+item: 57
+ACCEPT
+count: 1
+item: 57
+count: 0
+ACCEPT
+count: 1
+item: 55
+count: 1
+item: 57
+ACCEPT
+count: 1
+item: 48
+count: 4
+item: 48
+item: 48
+item: 48
+item: 48
+ACCEPT
+count: 1
+item: 48
+count: 4
+item: 48
+item: 48
+item: 48
+FAIL
+count: 1
+item: 48
+count: 4
+item: 48
+item: 48
+item: 48
+FAIL
diff --git a/test/trans.d/case/cond7_asm.rl b/test/trans.d/case/cond7_asm.rl
new file mode 100644
index 00000000..f3d4de57
--- /dev/null
+++ b/test/trans.d/case/cond7_asm.rl
@@ -0,0 +1,234 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm i,8,8
+ .text
+ .section .data
+ .comm c,8,8
+ .text
+
+%%{
+ machine foo;
+
+ action testi {
+ movq i (%rip), %rax
+ pushq %rax
+ movq $0, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ pushq %rax
+
+ popq %rax
+}
+ action inc {
+ movq i (%rip), %rax
+ pushq %rax
+ movq $1, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ subq %rcx, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, i (%rip)
+ movsbq (%r12), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, c (%rip)
+ .section .rodata
+1:
+ .string "item: "
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq c(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+2:
+ .string "\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ count = [0-9] @{
+ movsbq (%r12), %rax
+ pushq %rax
+ movq $48, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ subq %rcx, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, i (%rip)
+ .section .rodata
+3:
+ .string "count: "
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq i(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+4:
+ .string "\n"
+ .text
+ movq $4b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq foo_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "00\n"
+.L_inp_1:
+ .string "019\n"
+.L_inp_2:
+ .string "190\n"
+.L_inp_3:
+ .string "1719\n"
+.L_inp_4:
+ .string "1040000\n"
+.L_inp_5:
+ .string "104000a\n"
+.L_inp_6:
+ .string "104000\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+
+ .align 8
+inplen:
+ .quad 7
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/cond7_c.rl b/test/trans.d/case/cond7_c.rl
new file mode 100644
index 00000000..506b2207
--- /dev/null
+++ b/test/trans.d/case/cond7_c.rl
@@ -0,0 +1,87 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int i ;
+int c ;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = ( int ) ( fc )
+;
+printf( "%s", "item: " );
+printf( "%d", c );
+printf( "%s", "\n" );
+}
+
+ count = [0-9] @{i = ( int ) ( fc - 48 )
+;
+printf( "%s", "count: " );
+printf( "%d", i );
+printf( "%s", "\n" );
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"00\n",
+"019\n",
+"190\n",
+"1719\n",
+"1040000\n",
+"104000a\n",
+"104000\n",
+};
+
+int inplen = 7;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/cond7_crack.rl b/test/trans.d/case/cond7_crack.rl
new file mode 100644
index 00000000..e2beed73
--- /dev/null
+++ b/test/trans.d/case/cond7_crack.rl
@@ -0,0 +1,72 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int i;
+int c;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = ( int ( fc ) )
+;
+cout.format( "item: " );
+cout.format( c );
+cout.format( "\n" );
+}
+
+ count = [0-9] @{i = ( int ( fc - 48 ) )
+;
+cout.format( "count: " );
+cout.format( i );
+cout.format( "\n" );
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= foo_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "00\n" );
+ m( "019\n" );
+ m( "190\n" );
+ m( "1719\n" );
+ m( "1040000\n" );
+ m( "104000a\n" );
+ m( "104000\n" );
+}
+
+main();
diff --git a/test/trans.d/case/cond7_cs.rl b/test/trans.d/case/cond7_cs.rl
new file mode 100644
index 00000000..006397fe
--- /dev/null
+++ b/test/trans.d/case/cond7_cs.rl
@@ -0,0 +1,86 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int i;
+int c;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = ( int ) ( fc )
+;
+Console.Write( "item: " );Console.Write( c );Console.Write( "\n" );}
+
+ count = [0-9] @{i = ( int ) ( fc - 48 )
+;
+Console.Write( "count: " );Console.Write( i );Console.Write( "\n" );};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"00\n",
+"019\n",
+"190\n",
+"1719\n",
+"1040000\n",
+"104000a\n",
+"104000\n",
+};
+
+
+static readonly int inplen = 7;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/cond7_d.rl b/test/trans.d/case/cond7_d.rl
new file mode 100644
index 00000000..90cc2a8c
--- /dev/null
+++ b/test/trans.d/case/cond7_d.rl
@@ -0,0 +1,87 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class foo
+{
+int i;
+int c;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = cast( int ) ( fc )
+;
+printf( "%.*s", "item: " );printf( "%d", c );
+printf( "%.*s", "\n" );}
+
+ count = [0-9] @{i = cast( int ) ( fc - 48 )
+;
+printf( "%.*s", "count: " );printf( "%d", i );
+printf( "%.*s", "\n" );};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"00\n",
+"019\n",
+"190\n",
+"1719\n",
+"1040000\n",
+"104000a\n",
+"104000\n",
+];
+
+int inplen = 7;
+
+}
+int main()
+{
+ foo m = new foo();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/cond7_go.rl b/test/trans.d/case/cond7_go.rl
new file mode 100644
index 00000000..a3e700bc
--- /dev/null
+++ b/test/trans.d/case/cond7_go.rl
@@ -0,0 +1,71 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var i int ;
+var c int ;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = ( int ) ( fc )
+;
+fmt.Print( "item: " );fmt.Print( c );fmt.Print( "\n" );}
+
+ count = [0-9] @{i = ( int ) ( fc - 48 )
+;
+fmt.Print( "count: " );fmt.Print( i );fmt.Print( "\n" );};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= foo_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"00\n",
+"019\n",
+"190\n",
+"1719\n",
+"1040000\n",
+"104000a\n",
+"104000\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/cond7_java.rl b/test/trans.d/case/cond7_java.rl
new file mode 100644
index 00000000..156a77d7
--- /dev/null
+++ b/test/trans.d/case/cond7_java.rl
@@ -0,0 +1,88 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class cond7_java
+{
+int i ;
+int c ;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = ( int ) ( fc )
+;
+System.out.print( "item: " );
+System.out.print( c );
+System.out.print( "\n" );
+}
+
+ count = [0-9] @{i = ( int ) ( fc - 48 )
+;
+System.out.print( "count: " );
+System.out.print( i );
+System.out.print( "\n" );
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= foo_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"00\n",
+"019\n",
+"190\n",
+"1719\n",
+"1040000\n",
+"104000a\n",
+"104000\n",
+};
+
+static final int inplen = 7;
+
+public static void main (String[] args)
+{
+ cond7_java machine = new cond7_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/cond7_julia.rl b/test/trans.d/case/cond7_julia.rl
new file mode 100644
index 00000000..924c3b25
--- /dev/null
+++ b/test/trans.d/case/cond7_julia.rl
@@ -0,0 +1,62 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = convert( Int, ( fc ) )
+;
+print( "item: " );
+print( c );
+print( "\n" );
+}
+
+ count = [0-9] @{i = convert( Int, ( fc - 48 ) )
+;
+print( "count: " );
+print( i );
+print( "\n" );
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+i = 0;
+c = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= foo_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "00\n" );
+ m( "019\n" );
+ m( "190\n" );
+ m( "1719\n" );
+ m( "1040000\n" );
+ m( "104000a\n" );
+ m( "104000\n" );
diff --git a/test/trans.d/case/cond7_ocaml.rl b/test/trans.d/case/cond7_ocaml.rl
new file mode 100644
index 00000000..e559fdec
--- /dev/null
+++ b/test/trans.d/case/cond7_ocaml.rl
@@ -0,0 +1,64 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let i = ref 0
+let c = ref 0
+
+%%{
+ machine foo;
+
+ action testi {i .contents > 0}
+ action inc {i := i .contents - 1;
+c := ( fc )
+;
+print_string( "item: " );
+print_int( c.contents );
+print_string( "\n" );
+}
+
+ count = [0-9] @{i := ( fc - 48 )
+;
+print_string( "count: " );
+print_int( i.contents );
+print_string( "\n" );
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= foo_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "00\n";
+ exec "019\n";
+ exec "190\n";
+ exec "1719\n";
+ exec "1040000\n";
+ exec "104000a\n";
+ exec "104000\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/cond7_ruby.rl b/test/trans.d/case/cond7_ruby.rl
new file mode 100644
index 00000000..a2970258
--- /dev/null
+++ b/test/trans.d/case/cond7_ruby.rl
@@ -0,0 +1,70 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = ( fc )
+;
+print( "item: " );
+print( c );
+print( "\n" );
+}
+
+ count = [0-9] @{i = ( fc - 48 )
+;
+print( "count: " );
+print( i );
+print( "\n" );
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+i = 1
+c = 1
+ %% write init;
+ %% write exec;
+ if cs >= foo_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"00\n",
+"019\n",
+"190\n",
+"1719\n",
+"1040000\n",
+"104000a\n",
+"104000\n",
+]
+
+inplen = 7
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/cond7_rust.rl b/test/trans.d/case/cond7_rust.rl
new file mode 100644
index 00000000..97e86165
--- /dev/null
+++ b/test/trans.d/case/cond7_rust.rl
@@ -0,0 +1,69 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut i : i32 = 0;
+static mut c : i32 = 0;
+
+%%{
+ machine foo;
+
+ action testi {i > 0}
+ action inc {i = i - 1;
+c = ( ( fc ) as i32 )
+;
+print!( "{}", "item: " );
+print!( "{}", c );
+print!( "{}", "\n" );
+}
+
+ count = [0-9] @{i = ( ( fc - 48 ) as i32 )
+;
+print!( "{}", "count: " );
+print!( "{}", i );
+print!( "{}", "\n" );
+};
+
+ sub =
+ count # record the number of digits
+ ( digit when testi @inc )* outwhen !testi;
+
+ main := sub sub '\n';
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= foo_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "00\n".to_string() ); }
+ unsafe { m( "019\n".to_string() ); }
+ unsafe { m( "190\n".to_string() ); }
+ unsafe { m( "1719\n".to_string() ); }
+ unsafe { m( "1040000\n".to_string() ); }
+ unsafe { m( "104000a\n".to_string() ); }
+ unsafe { m( "104000\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/cppscan6.rl b/test/trans.d/case/cppscan6.rl
new file mode 100644
index 00000000..05824150
--- /dev/null
+++ b/test/trans.d/case/cppscan6.rl
@@ -0,0 +1,359 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ *
+ * const char *data = ts;
+ * int len = te - ts;
+ * cout << "<" << tok << "> ";
+ * for ( int i = 0; i < len; i++ )
+ * cout << data[i];
+ * cout << '\n';
+ */
+
+ptr ts;
+ptr te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ action comment {
+ token = 242;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ }
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {
+ token = 193;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {
+ token = 192;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{
+ token = 195;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {
+ token = 194;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {
+ token = 218;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {
+ token = 219;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {
+ token = 220;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {
+ token = 197;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '==' => {
+ token = 223;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '!=' => {
+ token = 224;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '&&' => {
+ token = 225;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '||' => {
+ token = 226;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '*=' => {
+ token = 227;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '/=' => {
+ token = 228;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '%=' => {
+ token = 229;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '+=' => {
+ token = 230;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '-=' => {
+ token = 231;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '&=' => {
+ token = 232;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '^=' => {
+ token = 233;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '|=' => {
+ token = 234;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '++' => {
+ token = 212;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '--' => {
+ token = 213;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '->' => {
+ token = 211;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '->*' => {
+ token = 214;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ '.*' => {
+ token = 215;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Three char compounds, first item already buffered.
+ '...' => {
+ token = 240;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {
+ token = <int>(first_token_char);
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {
+ token = 241;
+ print_str "<";
+ print_int token;
+ print_str "> ";
+ print_token;
+ print_str "\n";
+ };
+ *|;
+}%%
+
+##### INPUT #####
+"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22"
+"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/"
+"'\n'\n"
+##### OUTPUT #####
+<192> "\"hi"
+<241>
+<242> /!
+!/
+<241>
+
+<218> 44
+<241>
+<194> .44
+<241>
+
+<194> 44.
+<241>
+<218> 44
+<241>
+
+<218> 44
+<241>
+<46> .
+<241>
+<218> 44
+<241>
+
+<194> 44.44
+<241>
+
+<195> _hithere22
+ACCEPT
+<193> '\''
+<192> "\n\d'\""
+<241>
+
+<195> hi
+<241>
+
+<218> 99
+<241>
+
+<194> .99
+<241>
+
+<194> 99e-4
+<241>
+
+<214> ->*
+<241>
+
+<226> ||
+<241>
+
+<220> 0x98
+<241>
+
+<218> 0
+<195> x
+<241>
+
+<242> //
+
+<242> /! * !/
+ACCEPT
+FAIL
diff --git a/test/trans.d/case/cppscan6_asm.rl b/test/trans.d/case/cppscan6_asm.rl
new file mode 100644
index 00000000..8e9a211a
--- /dev/null
+++ b/test/trans.d/case/cppscan6_asm.rl
@@ -0,0 +1,1908 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm ts,8,8
+ .text
+ .section .data
+ .comm te,8,8
+ .text
+ .section .data
+ .comm act,8,8
+ .text
+ .section .data
+ .comm token,8,8
+ .text
+
+%%{
+ machine scanner;
+
+ action comment {
+ movq $242, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+1:
+ .string "<"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+2:
+ .string "> "
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+3:
+ cmp $0, %rcx
+ je 4f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 3b
+4:
+
+ .section .rodata
+5:
+ .string "\n"
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {
+ movq $193, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+6:
+ .string "<"
+ .text
+ movq $6b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+7:
+ .string "> "
+ .text
+ movq $7b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+8:
+ cmp $0, %rcx
+ je 9f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 8b
+9:
+
+ .section .rodata
+10:
+ .string "\n"
+ .text
+ movq $10b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {
+ movq $192, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+11:
+ .string "<"
+ .text
+ movq $11b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+12:
+ .string "> "
+ .text
+ movq $12b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+13:
+ cmp $0, %rcx
+ je 14f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 13b
+14:
+
+ .section .rodata
+15:
+ .string "\n"
+ .text
+ movq $15b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{
+ movq $195, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+16:
+ .string "<"
+ .text
+ movq $16b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+17:
+ .string "> "
+ .text
+ movq $17b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+18:
+ cmp $0, %rcx
+ je 19f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 18b
+19:
+
+ .section .rodata
+20:
+ .string "\n"
+ .text
+ movq $20b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {
+ movq $194, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+21:
+ .string "<"
+ .text
+ movq $21b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+22:
+ .string "> "
+ .text
+ movq $22b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+23:
+ cmp $0, %rcx
+ je 24f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 23b
+24:
+
+ .section .rodata
+25:
+ .string "\n"
+ .text
+ movq $25b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {
+ movq $218, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+26:
+ .string "<"
+ .text
+ movq $26b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+27:
+ .string "> "
+ .text
+ movq $27b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+28:
+ cmp $0, %rcx
+ je 29f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 28b
+29:
+
+ .section .rodata
+30:
+ .string "\n"
+ .text
+ movq $30b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {
+ movq $219, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+31:
+ .string "<"
+ .text
+ movq $31b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+32:
+ .string "> "
+ .text
+ movq $32b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+33:
+ cmp $0, %rcx
+ je 34f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 33b
+34:
+
+ .section .rodata
+35:
+ .string "\n"
+ .text
+ movq $35b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {
+ movq $220, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+36:
+ .string "<"
+ .text
+ movq $36b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+37:
+ .string "> "
+ .text
+ movq $37b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+38:
+ cmp $0, %rcx
+ je 39f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 38b
+39:
+
+ .section .rodata
+40:
+ .string "\n"
+ .text
+ movq $40b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {
+ movq $197, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+41:
+ .string "<"
+ .text
+ movq $41b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+42:
+ .string "> "
+ .text
+ movq $42b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+43:
+ cmp $0, %rcx
+ je 44f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 43b
+44:
+
+ .section .rodata
+45:
+ .string "\n"
+ .text
+ movq $45b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '==' => {
+ movq $223, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+46:
+ .string "<"
+ .text
+ movq $46b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+47:
+ .string "> "
+ .text
+ movq $47b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+48:
+ cmp $0, %rcx
+ je 49f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 48b
+49:
+
+ .section .rodata
+50:
+ .string "\n"
+ .text
+ movq $50b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '!=' => {
+ movq $224, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+51:
+ .string "<"
+ .text
+ movq $51b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+52:
+ .string "> "
+ .text
+ movq $52b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+53:
+ cmp $0, %rcx
+ je 54f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 53b
+54:
+
+ .section .rodata
+55:
+ .string "\n"
+ .text
+ movq $55b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '&&' => {
+ movq $225, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+56:
+ .string "<"
+ .text
+ movq $56b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+57:
+ .string "> "
+ .text
+ movq $57b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+58:
+ cmp $0, %rcx
+ je 59f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 58b
+59:
+
+ .section .rodata
+60:
+ .string "\n"
+ .text
+ movq $60b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '||' => {
+ movq $226, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+61:
+ .string "<"
+ .text
+ movq $61b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+62:
+ .string "> "
+ .text
+ movq $62b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+63:
+ cmp $0, %rcx
+ je 64f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 63b
+64:
+
+ .section .rodata
+65:
+ .string "\n"
+ .text
+ movq $65b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '*=' => {
+ movq $227, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+66:
+ .string "<"
+ .text
+ movq $66b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+67:
+ .string "> "
+ .text
+ movq $67b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+68:
+ cmp $0, %rcx
+ je 69f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 68b
+69:
+
+ .section .rodata
+70:
+ .string "\n"
+ .text
+ movq $70b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '/=' => {
+ movq $228, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+71:
+ .string "<"
+ .text
+ movq $71b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+72:
+ .string "> "
+ .text
+ movq $72b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+73:
+ cmp $0, %rcx
+ je 74f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 73b
+74:
+
+ .section .rodata
+75:
+ .string "\n"
+ .text
+ movq $75b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '%=' => {
+ movq $229, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+76:
+ .string "<"
+ .text
+ movq $76b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+77:
+ .string "> "
+ .text
+ movq $77b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+78:
+ cmp $0, %rcx
+ je 79f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 78b
+79:
+
+ .section .rodata
+80:
+ .string "\n"
+ .text
+ movq $80b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '+=' => {
+ movq $230, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+81:
+ .string "<"
+ .text
+ movq $81b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+82:
+ .string "> "
+ .text
+ movq $82b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+83:
+ cmp $0, %rcx
+ je 84f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 83b
+84:
+
+ .section .rodata
+85:
+ .string "\n"
+ .text
+ movq $85b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '-=' => {
+ movq $231, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+86:
+ .string "<"
+ .text
+ movq $86b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+87:
+ .string "> "
+ .text
+ movq $87b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+88:
+ cmp $0, %rcx
+ je 89f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 88b
+89:
+
+ .section .rodata
+90:
+ .string "\n"
+ .text
+ movq $90b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '&=' => {
+ movq $232, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+91:
+ .string "<"
+ .text
+ movq $91b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+92:
+ .string "> "
+ .text
+ movq $92b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+93:
+ cmp $0, %rcx
+ je 94f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 93b
+94:
+
+ .section .rodata
+95:
+ .string "\n"
+ .text
+ movq $95b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '^=' => {
+ movq $233, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+96:
+ .string "<"
+ .text
+ movq $96b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+97:
+ .string "> "
+ .text
+ movq $97b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+98:
+ cmp $0, %rcx
+ je 99f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 98b
+99:
+
+ .section .rodata
+100:
+ .string "\n"
+ .text
+ movq $100b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '|=' => {
+ movq $234, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+101:
+ .string "<"
+ .text
+ movq $101b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+102:
+ .string "> "
+ .text
+ movq $102b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+103:
+ cmp $0, %rcx
+ je 104f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 103b
+104:
+
+ .section .rodata
+105:
+ .string "\n"
+ .text
+ movq $105b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '++' => {
+ movq $212, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+106:
+ .string "<"
+ .text
+ movq $106b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+107:
+ .string "> "
+ .text
+ movq $107b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+108:
+ cmp $0, %rcx
+ je 109f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 108b
+109:
+
+ .section .rodata
+110:
+ .string "\n"
+ .text
+ movq $110b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '--' => {
+ movq $213, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+111:
+ .string "<"
+ .text
+ movq $111b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+112:
+ .string "> "
+ .text
+ movq $112b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+113:
+ cmp $0, %rcx
+ je 114f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 113b
+114:
+
+ .section .rodata
+115:
+ .string "\n"
+ .text
+ movq $115b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '->' => {
+ movq $211, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+116:
+ .string "<"
+ .text
+ movq $116b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+117:
+ .string "> "
+ .text
+ movq $117b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+118:
+ cmp $0, %rcx
+ je 119f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 118b
+119:
+
+ .section .rodata
+120:
+ .string "\n"
+ .text
+ movq $120b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '->*' => {
+ movq $214, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+121:
+ .string "<"
+ .text
+ movq $121b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+122:
+ .string "> "
+ .text
+ movq $122b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+123:
+ cmp $0, %rcx
+ je 124f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 123b
+124:
+
+ .section .rodata
+125:
+ .string "\n"
+ .text
+ movq $125b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '.*' => {
+ movq $215, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+126:
+ .string "<"
+ .text
+ movq $126b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+127:
+ .string "> "
+ .text
+ movq $127b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+128:
+ cmp $0, %rcx
+ je 129f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 128b
+129:
+
+ .section .rodata
+130:
+ .string "\n"
+ .text
+ movq $130b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {
+ movq $240, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+131:
+ .string "<"
+ .text
+ movq $131b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+132:
+ .string "> "
+ .text
+ movq $132b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+133:
+ cmp $0, %rcx
+ je 134f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 133b
+134:
+
+ .section .rodata
+135:
+ .string "\n"
+ .text
+ movq $135b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {
+ movq -16(%rbp), %rax
+ movsbq (%rax), %rcx
+ pushq %rcx
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+136:
+ .string "<"
+ .text
+ movq $136b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+137:
+ .string "> "
+ .text
+ movq $137b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+138:
+ cmp $0, %rcx
+ je 139f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 138b
+139:
+
+ .section .rodata
+140:
+ .string "\n"
+ .text
+ movq $140b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {
+ movq $241, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, token (%rip)
+ .section .rodata
+141:
+ .string "<"
+ .text
+ movq $141b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq token(%rip), %rax
+ pushq %rax
+ movq $.L_fmt_int, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ .section .rodata
+142:
+ .string "> "
+ .text
+ movq $142b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -16(%rbp), %rax # ts
+ movq -24(%rbp), %rcx # te
+ subq %rax, %rcx # length
+143:
+ cmp $0, %rcx
+ je 144f
+ movsbl (%rax), %edi
+ push %rax
+ push %rcx
+ call putchar
+ pop %rcx
+ pop %rax
+ addq $1, %rax
+ subq $1, %rcx
+ jmp 143b
+144:
+
+ .section .rodata
+145:
+ .string "\n"
+ .text
+ movq $145b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ *|;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq scanner_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22"
+.L_inp_1:
+ .string "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/"
+.L_inp_2:
+ .string "'\n'\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+
+ .align 8
+inplen:
+ .quad 3
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/cppscan6_c.rl b/test/trans.d/case/cppscan6_c.rl
new file mode 100644
index 00000000..bc774d92
--- /dev/null
+++ b/test/trans.d/case/cppscan6_c.rl
@@ -0,0 +1,278 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char * ts ;
+char * te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '==' => {token = 223;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '!=' => {token = 224;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '&&' => {token = 225;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '||' => {token = 226;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '*=' => {token = 227;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '/=' => {token = 228;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '%=' => {token = 229;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '+=' => {token = 230;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '-=' => {token = 231;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '&=' => {token = 232;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '^=' => {token = 233;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '|=' => {token = 234;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '++' => {token = 212;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '--' => {token = 213;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '->' => {token = 211;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '->*' => {token = 214;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ '.*' => {token = 215;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = ( int ) ( ts[0] )
+;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+printf( "%s", "<" );
+printf( "%d", token );
+printf( "%s", "> " );
+fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22",
+"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/",
+"'\n'\n",
+};
+
+int inplen = 3;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/cppscan6_crack.rl b/test/trans.d/case/cppscan6_crack.rl
new file mode 100644
index 00000000..5cf24759
--- /dev/null
+++ b/test/trans.d/case/cppscan6_crack.rl
@@ -0,0 +1,323 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int
+ ts;
+int
+ te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '==' => {token = 223;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '!=' => {token = 224;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '&&' => {token = 225;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '||' => {token = 226;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '*=' => {token = 227;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '/=' => {token = 228;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '%=' => {token = 229;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '+=' => {token = 230;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '-=' => {token = 231;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '&=' => {token = 232;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '^=' => {token = 233;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '|=' => {token = 234;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '++' => {token = 212;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '--' => {token = 213;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '->' => {token = 211;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '->*' => {token = 214;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ '.*' => {token = 215;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = ( int ( data[ts] ) )
+;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+cout.format( "<" );
+cout.format( token );
+cout.format( "> " );
+int len = uintz(te) - uintz(ts);
+cout.write( Buffer(data + uintz(ts), len) );
+cout.format( "\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22" );
+ m( "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/" );
+ m( "'\n'\n" );
+}
+
+main();
diff --git a/test/trans.d/case/cppscan6_cs.rl b/test/trans.d/case/cppscan6_cs.rl
new file mode 100644
index 00000000..11116bba
--- /dev/null
+++ b/test/trans.d/case/cppscan6_cs.rl
@@ -0,0 +1,195 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int ts;
+int te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '==' => {token = 223;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '!=' => {token = 224;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '&&' => {token = 225;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '||' => {token = 226;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '*=' => {token = 227;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '/=' => {token = 228;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '%=' => {token = 229;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '+=' => {token = 230;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '-=' => {token = 231;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '&=' => {token = 232;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '^=' => {token = 233;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '|=' => {token = 234;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '++' => {token = 212;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '--' => {token = 213;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '->' => {token = 211;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '->*' => {token = 214;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ '.*' => {token = 215;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = ( int ) ( data[ts] )
+;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) );
+Console.Write( "\n" );};
+ *|;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22",
+"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/",
+"'\n'\n",
+};
+
+
+static readonly int inplen = 3;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/cppscan6_d.rl b/test/trans.d/case/cppscan6_d.rl
new file mode 100644
index 00000000..f0deb0d7
--- /dev/null
+++ b/test/trans.d/case/cppscan6_d.rl
@@ -0,0 +1,195 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class scanner
+{
+const(char) * ts;
+const(char) * te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '==' => {token = 223;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '!=' => {token = 224;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '&&' => {token = 225;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '||' => {token = 226;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '*=' => {token = 227;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '/=' => {token = 228;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '%=' => {token = 229;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '+=' => {token = 230;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '-=' => {token = 231;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '&=' => {token = 232;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '^=' => {token = 233;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '|=' => {token = 234;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '++' => {token = 212;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '--' => {token = 213;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '->' => {token = 211;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '->*' => {token = 214;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ '.*' => {token = 215;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = cast( int ) ( ts[0] )
+;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+printf( "%.*s", "<" );printf( "%d", token );
+printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22",
+"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/",
+"'\n'\n",
+];
+
+int inplen = 3;
+
+}
+int main()
+{
+ scanner m = new scanner();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/cppscan6_go.rl b/test/trans.d/case/cppscan6_go.rl
new file mode 100644
index 00000000..1616a67f
--- /dev/null
+++ b/test/trans.d/case/cppscan6_go.rl
@@ -0,0 +1,152 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var ts int ;
+var te int ;
+var act int ;
+var token int ;
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '==' => {token = 223;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '!=' => {token = 224;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '&&' => {token = 225;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '||' => {token = 226;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '*=' => {token = 227;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '/=' => {token = 228;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '%=' => {token = 229;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '+=' => {token = 230;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '-=' => {token = 231;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '&=' => {token = 232;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '^=' => {token = 233;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '|=' => {token = 234;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '++' => {token = 212;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '--' => {token = 213;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '->' => {token = 211;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '->*' => {token = 214;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ '.*' => {token = 215;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = ( int ) ( data[ts] )
+;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );};
+ *|;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= scanner_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22",
+"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/",
+"'\n'\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/cppscan6_java.rl b/test/trans.d/case/cppscan6_java.rl
new file mode 100644
index 00000000..fbad9117
--- /dev/null
+++ b/test/trans.d/case/cppscan6_java.rl
@@ -0,0 +1,339 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class cppscan6_java
+{
+int
+ ts ;
+int
+ te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '==' => {token = 223;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '!=' => {token = 224;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '&&' => {token = 225;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '||' => {token = 226;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '*=' => {token = 227;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '/=' => {token = 228;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '%=' => {token = 229;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '+=' => {token = 230;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '-=' => {token = 231;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '&=' => {token = 232;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '^=' => {token = 233;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '|=' => {token = 234;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '++' => {token = 212;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '--' => {token = 213;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '->' => {token = 211;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '->*' => {token = 214;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ '.*' => {token = 215;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = ( int ) ( data[ts] )
+;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+System.out.print( "<" );
+System.out.print( token );
+System.out.print( "> " );
+_s = new String( data, ts, te - ts );
+System.out.print( _s );
+System.out.print( "\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22",
+"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/",
+"'\n'\n",
+};
+
+static final int inplen = 3;
+
+public static void main (String[] args)
+{
+ cppscan6_java machine = new cppscan6_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/cppscan6_julia.rl b/test/trans.d/case/cppscan6_julia.rl
new file mode 100644
index 00000000..ff1dcac4
--- /dev/null
+++ b/test/trans.d/case/cppscan6_julia.rl
@@ -0,0 +1,281 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '==' => {token = 223;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '!=' => {token = 224;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '&&' => {token = 225;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '||' => {token = 226;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '*=' => {token = 227;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '/=' => {token = 228;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '%=' => {token = 229;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '+=' => {token = 230;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '-=' => {token = 231;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '&=' => {token = 232;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '^=' => {token = 233;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '|=' => {token = 234;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '++' => {token = 212;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '--' => {token = 213;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '->' => {token = 211;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '->*' => {token = 214;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ '.*' => {token = 215;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = convert( Int, ( data[ts+1] ) )
+;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+print( "<" );
+print( token );
+print( "> " );
+print( data[(ts+1) : (te)] )
+print( "\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+ts = 0;
+te = 0;
+act = 0;
+token = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22" );
+ m( "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/" );
+ m( "'\n'\n" );
diff --git a/test/trans.d/case/cppscan6_ocaml.rl b/test/trans.d/case/cppscan6_ocaml.rl
new file mode 100644
index 00000000..c6af74dc
--- /dev/null
+++ b/test/trans.d/case/cppscan6_ocaml.rl
@@ -0,0 +1,255 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let ts = ref 0
+let te = ref 0
+let act = ref 0
+let token = ref 0
+
+%%{
+ machine scanner;
+
+ action comment {token := 242;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token := 193;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token := 192;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token := 195;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token := 194;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token := 218;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token := 219;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token := 220;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token := 197;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '==' => {token := 223;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '!=' => {token := 224;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '&&' => {token := 225;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '||' => {token := 226;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '*=' => {token := 227;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '/=' => {token := 228;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '%=' => {token := 229;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '+=' => {token := 230;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '-=' => {token := 231;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '&=' => {token := 232;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '^=' => {token := 233;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '|=' => {token := 234;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '++' => {token := 212;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '--' => {token := 213;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '->' => {token := 211;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '->*' => {token := 214;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ '.*' => {token := 215;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token := 240;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token := ( ( Char.code data.[ts.contents] ) )
+;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token := 241;
+print_string( "<" );
+print_int( token.contents );
+print_string( "> " );
+for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" );
+};
+ *|;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= scanner_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22";
+ exec "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/";
+ exec "'\n'\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/cppscan6_ruby.rl b/test/trans.d/case/cppscan6_ruby.rl
new file mode 100644
index 00000000..58079620
--- /dev/null
+++ b/test/trans.d/case/cppscan6_ruby.rl
@@ -0,0 +1,318 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '==' => {token = 223;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '!=' => {token = 224;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '&&' => {token = 225;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '||' => {token = 226;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '*=' => {token = 227;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '/=' => {token = 228;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '%=' => {token = 229;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '+=' => {token = 230;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '-=' => {token = 231;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '&=' => {token = 232;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '^=' => {token = 233;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '|=' => {token = 234;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '++' => {token = 212;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '--' => {token = 213;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '->' => {token = 211;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '->*' => {token = 214;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ '.*' => {token = 215;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = ( data[ts].ord )
+;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+print( "<" );
+print( token );
+print( "> " );
+_m = data[ts..te-1];
+print( _m );
+print( "\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ts = 1
+te = 1
+act = 1
+token = 1
+ %% write init;
+ %% write exec;
+ if cs >= scanner_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22",
+"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/",
+"'\n'\n",
+]
+
+inplen = 3
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/cppscan6_rust.rl b/test/trans.d/case/cppscan6_rust.rl
new file mode 100644
index 00000000..edd821c6
--- /dev/null
+++ b/test/trans.d/case/cppscan6_rust.rl
@@ -0,0 +1,406 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut ts : i32
+ = 0;
+static mut te : i32
+ = 0;
+static mut act : i32 = 0;
+static mut token : i32 = 0;
+
+%%{
+ machine scanner;
+
+ action comment {token = 242;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+}
+
+
+ main := |*
+
+ # Single and double literals.
+ ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" )
+ => {token = 193;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' )
+ => {token = 192;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Identifiers
+ ( [a-zA-Z_] [a-zA-Z0-9_]* )
+ =>{token = 195;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Floating literals.
+ fract_const = digit* '.' digit+ | digit+ '.';
+ exponent = [eE] [+\-]? digit+;
+ float_suffix = [flFL];
+
+ ( fract_const exponent? float_suffix? |
+ digit+ exponent float_suffix? )
+ => {token = 194;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Integer decimal. Leading part buffered by float.
+ ( ( '0' | [1-9] [0-9]* ) [ulUL]? )
+ => {token = 218;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Integer octal. Leading part buffered by float.
+ ( '0' [0-9]+ [ulUL]? )
+ => {token = 219;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Integer hex. Leading 0 buffered by float.
+ ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) )
+ => {token = 220;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Only buffer the second item, first buffered by symbol.
+ '::' => {token = 197;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '==' => {token = 223;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '!=' => {token = 224;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '&&' => {token = 225;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '||' => {token = 226;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '*=' => {token = 227;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '/=' => {token = 228;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '%=' => {token = 229;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '+=' => {token = 230;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '-=' => {token = 231;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '&=' => {token = 232;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '^=' => {token = 233;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '|=' => {token = 234;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '++' => {token = 212;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '--' => {token = 213;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '->' => {token = 211;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '->*' => {token = 214;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ '.*' => {token = 215;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Three char compounds, first item already buffered.
+ '...' => {token = 240;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Single char symbols.
+ ( punct - [_"'] ) => {token = ( ( data[ts as usize] ) as i32 )
+;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+
+ # Comments and whitespace.
+ '/!' ( any* $0 '!/' @1 ) => comment;
+ '//' ( any* $0 '\n' @1 ) => comment;
+ ( any - 33..126 )+ => {token = 241;
+print!( "{}", "<" );
+print!( "{}", token );
+print!( "{}", "> " );
+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 );
+print!( "{}", "\n" );
+};
+ *|;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22".to_string() ); }
+ unsafe { m( "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/".to_string() ); }
+ unsafe { m( "'\n'\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/curs1.rl b/test/trans.d/case/curs1.rl
new file mode 100644
index 00000000..71c5c43c
--- /dev/null
+++ b/test/trans.d/case/curs1.rl
@@ -0,0 +1,34 @@
+/*
+ * @LANG: indep
+ */
+
+int return_to;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ print_str "one\n";
+ fnext *return_to;
+ };
+
+ two := 'two' @{
+ print_str "two\n";
+ fnext *return_to;
+ };
+
+ main :=
+ '1' @{ return_to = fcurs; fnext one; }
+ | '2' @{ return_to = fcurs; fnext two; }
+ | '\n';
+}%%
+
+##### INPUT #####
+"1one2two1one\n"
+##### OUTPUT #####
+one
+two
+one
+ACCEPT
diff --git a/test/trans.d/case/curs1_asm.rl b/test/trans.d/case/curs1_asm.rl
new file mode 100644
index 00000000..8b71c052
--- /dev/null
+++ b/test/trans.d/case/curs1_asm.rl
@@ -0,0 +1,171 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm return_to,8,8
+ .text
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ .section .rodata
+1:
+ .string "one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq return_to(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ two := 'two' @{
+ .section .rodata
+2:
+ .string "two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq return_to(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ main :=
+ '1' @{
+ fcurs;
+ pushq %rax
+ popq %rax
+ movq %rax, return_to (%rip)
+fnext one;
+
+}
+ | '2' @{
+ fcurs;
+ pushq %rax
+ popq %rax
+ movq %rax, return_to (%rip)
+fnext two;
+
+}
+ | '\n';
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq curs1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1one2two1one\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/curs1_c.rl b/test/trans.d/case/curs1_c.rl
new file mode 100644
index 00000000..781aa33e
--- /dev/null
+++ b/test/trans.d/case/curs1_c.rl
@@ -0,0 +1,73 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int return_to ;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%s", "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{printf( "%s", "two\n" );
+fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= curs1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1one2two1one\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/curs1_crack.rl b/test/trans.d/case/curs1_crack.rl
new file mode 100644
index 00000000..f1b1126d
--- /dev/null
+++ b/test/trans.d/case/curs1_crack.rl
@@ -0,0 +1,58 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int return_to;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{cout.format( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{cout.format( "two\n" );
+fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= curs1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1one2two1one\n" );
+}
+
+main();
diff --git a/test/trans.d/case/curs1_cs.rl b/test/trans.d/case/curs1_cs.rl
new file mode 100644
index 00000000..fe525f85
--- /dev/null
+++ b/test/trans.d/case/curs1_cs.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int return_to;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{Console.Write( "one\n" );fnext *return_to;};
+
+ two := 'two' @{Console.Write( "two\n" );fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= curs1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1one2two1one\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/curs1_d.rl b/test/trans.d/case/curs1_d.rl
new file mode 100644
index 00000000..3bce97a4
--- /dev/null
+++ b/test/trans.d/case/curs1_d.rl
@@ -0,0 +1,75 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class curs1
+{
+int return_to;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%.*s", "one\n" );fnext *return_to;};
+
+ two := 'two' @{printf( "%.*s", "two\n" );fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= curs1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1one2two1one\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ curs1 m = new curs1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/curs1_go.rl b/test/trans.d/case/curs1_go.rl
new file mode 100644
index 00000000..1c9058a2
--- /dev/null
+++ b/test/trans.d/case/curs1_go.rl
@@ -0,0 +1,67 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var return_to int ;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{fmt.Print( "one\n" );fnext *return_to;
+
+};
+
+ two := 'two' @{fmt.Print( "two\n" );fnext *return_to;
+
+};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;
+}
+ | '2' @{return_to = fcurs;
+fnext two;
+}
+ | '\n';
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= curs1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1one2two1one\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/curs1_java.rl b/test/trans.d/case/curs1_java.rl
new file mode 100644
index 00000000..c44dd6c1
--- /dev/null
+++ b/test/trans.d/case/curs1_java.rl
@@ -0,0 +1,74 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class curs1_java
+{
+int return_to ;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{System.out.print( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{System.out.print( "two\n" );
+fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= curs1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1one2two1one\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ curs1_java machine = new curs1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/curs1_julia.rl b/test/trans.d/case/curs1_julia.rl
new file mode 100644
index 00000000..10972c82
--- /dev/null
+++ b/test/trans.d/case/curs1_julia.rl
@@ -0,0 +1,48 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{print( "two\n" );
+fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+return_to = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= curs1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1one2two1one\n" );
diff --git a/test/trans.d/case/curs1_ocaml.rl b/test/trans.d/case/curs1_ocaml.rl
new file mode 100644
index 00000000..b79dc73e
--- /dev/null
+++ b/test/trans.d/case/curs1_ocaml.rl
@@ -0,0 +1,52 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let return_to = ref 0
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print_string( "one\n" );
+fnext *return_to.contents;
+};
+
+ two := 'two' @{print_string( "two\n" );
+fnext *return_to.contents;
+};
+
+ main :=
+ '1' @{return_to := fcurs;
+fnext one; }
+ | '2' @{return_to := fcurs;
+fnext two; }
+ | '\n';
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= curs1_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1one2two1one\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/curs1_ruby.rl b/test/trans.d/case/curs1_ruby.rl
new file mode 100644
index 00000000..dfa48b2f
--- /dev/null
+++ b/test/trans.d/case/curs1_ruby.rl
@@ -0,0 +1,56 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{print( "two\n" );
+fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+return_to = 1
+ %% write init;
+ %% write exec;
+ if cs >= curs1_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1one2two1one\n",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/curs1_rust.rl b/test/trans.d/case/curs1_rust.rl
new file mode 100644
index 00000000..3c666c45
--- /dev/null
+++ b/test/trans.d/case/curs1_rust.rl
@@ -0,0 +1,55 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut return_to : i32 = 0;
+
+%%{
+ machine curs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print!( "{}", "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{print!( "{}", "two\n" );
+fnext *return_to;};
+
+ main :=
+ '1' @{return_to = fcurs;
+fnext one;}
+ | '2' @{return_to = fcurs;
+fnext two;}
+ | '\n';
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= curs1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1one2two1one\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/empty1.rl b/test/trans.d/case/empty1.rl
new file mode 100644
index 00000000..39078902
--- /dev/null
+++ b/test/trans.d/case/empty1.rl
@@ -0,0 +1,15 @@
+/*
+ * @LANG: indep
+ */
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+##### INPUT #####
+""
+"x"
+##### OUTPUT #####
+FAIL
+FAIL
diff --git a/test/trans.d/case/empty1_asm.rl b/test/trans.d/case/empty1_asm.rl
new file mode 100644
index 00000000..5f283c9c
--- /dev/null
+++ b/test/trans.d/case/empty1_asm.rl
@@ -0,0 +1,115 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq empty1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string ""
+.L_inp_1:
+ .string "x"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+
+ .align 8
+inplen:
+ .quad 2
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/empty1_c.rl b/test/trans.d/case/empty1_c.rl
new file mode 100644
index 00000000..be0b4917
--- /dev/null
+++ b/test/trans.d/case/empty1_c.rl
@@ -0,0 +1,61 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= empty1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"",
+"x",
+};
+
+int inplen = 2;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/empty1_crack.rl b/test/trans.d/case/empty1_crack.rl
new file mode 100644
index 00000000..f9ef6600
--- /dev/null
+++ b/test/trans.d/case/empty1_crack.rl
@@ -0,0 +1,46 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= empty1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "" );
+ m( "x" );
+}
+
+main();
diff --git a/test/trans.d/case/empty1_cs.rl b/test/trans.d/case/empty1_cs.rl
new file mode 100644
index 00000000..b1c493aa
--- /dev/null
+++ b/test/trans.d/case/empty1_cs.rl
@@ -0,0 +1,66 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= empty1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"",
+"x",
+};
+
+
+static readonly int inplen = 2;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/empty1_d.rl b/test/trans.d/case/empty1_d.rl
new file mode 100644
index 00000000..3593f520
--- /dev/null
+++ b/test/trans.d/case/empty1_d.rl
@@ -0,0 +1,65 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class empty1
+{
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= empty1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"",
+"x",
+];
+
+int inplen = 2;
+
+}
+int main()
+{
+ empty1 m = new empty1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/empty1_go.rl b/test/trans.d/case/empty1_go.rl
new file mode 100644
index 00000000..b3d535c1
--- /dev/null
+++ b/test/trans.d/case/empty1_go.rl
@@ -0,0 +1,51 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= empty1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"",
+"x",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/empty1_java.rl b/test/trans.d/case/empty1_java.rl
new file mode 100644
index 00000000..54f354c3
--- /dev/null
+++ b/test/trans.d/case/empty1_java.rl
@@ -0,0 +1,62 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class empty1_java
+{
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= empty1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"",
+"x",
+};
+
+static final int inplen = 2;
+
+public static void main (String[] args)
+{
+ empty1_java machine = new empty1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/empty1_julia.rl b/test/trans.d/case/empty1_julia.rl
new file mode 100644
index 00000000..7935b34d
--- /dev/null
+++ b/test/trans.d/case/empty1_julia.rl
@@ -0,0 +1,36 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= empty1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "" );
+ m( "x" );
diff --git a/test/trans.d/case/empty1_ocaml.rl b/test/trans.d/case/empty1_ocaml.rl
new file mode 100644
index 00000000..f9e0249d
--- /dev/null
+++ b/test/trans.d/case/empty1_ocaml.rl
@@ -0,0 +1,38 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= empty1_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "";
+ exec "x";
+ ()
+;;
+
diff --git a/test/trans.d/case/empty1_ruby.rl b/test/trans.d/case/empty1_ruby.rl
new file mode 100644
index 00000000..340af2bc
--- /dev/null
+++ b/test/trans.d/case/empty1_ruby.rl
@@ -0,0 +1,44 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= empty1_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"",
+"x",
+]
+
+inplen = 2
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/empty1_rust.rl b/test/trans.d/case/empty1_rust.rl
new file mode 100644
index 00000000..af89c9a7
--- /dev/null
+++ b/test/trans.d/case/empty1_rust.rl
@@ -0,0 +1,43 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine empty1;
+ main := empty;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= empty1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "".to_string() ); }
+ unsafe { m( "x".to_string() ); }
+}
+
diff --git a/test/trans.d/case/eofact.rl b/test/trans.d/case/eofact.rl
new file mode 100644
index 00000000..83ad2a7e
--- /dev/null
+++ b/test/trans.d/case/eofact.rl
@@ -0,0 +1,51 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ *
+ * Test works with split code gen.
+ */
+
+%%{
+ machine eofact;
+
+ action a1 { print_str "a1\n"; }
+ action a2 { print_str "a2\n"; }
+ action a3 { print_str "a3\n"; }
+ action a4 { print_str "a4\n"; }
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+##### INPUT #####
+""
+"h"
+"hell"
+"hello"
+"hello\n"
+"t"
+"ther"
+"there"
+"friend"
+##### OUTPUT #####
+a1
+a3
+FAIL
+a1
+FAIL
+a1
+FAIL
+a2
+ACCEPT
+ACCEPT
+a3
+FAIL
+a3
+FAIL
+a4
+ACCEPT
+FAIL
diff --git a/test/trans.d/case/eofact_asm.rl b/test/trans.d/case/eofact_asm.rl
new file mode 100644
index 00000000..22937aed
--- /dev/null
+++ b/test/trans.d/case/eofact_asm.rl
@@ -0,0 +1,196 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {
+ .section .rodata
+1:
+ .string "a1\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action a2 {
+ .section .rodata
+2:
+ .string "a2\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action a3 {
+ .section .rodata
+3:
+ .string "a3\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action a4 {
+ .section .rodata
+4:
+ .string "a4\n"
+ .text
+ movq $4b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq eofact_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string ""
+.L_inp_1:
+ .string "h"
+.L_inp_2:
+ .string "hell"
+.L_inp_3:
+ .string "hello"
+.L_inp_4:
+ .string "hello\n"
+.L_inp_5:
+ .string "t"
+.L_inp_6:
+ .string "ther"
+.L_inp_7:
+ .string "there"
+.L_inp_8:
+ .string "friend"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+
+ .align 8
+inplen:
+ .quad 9
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/eofact_c.rl b/test/trans.d/case/eofact_c.rl
new file mode 100644
index 00000000..65bd9b9d
--- /dev/null
+++ b/test/trans.d/case/eofact_c.rl
@@ -0,0 +1,84 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {printf( "%s", "a1\n" );
+}
+ action a2 {printf( "%s", "a2\n" );
+}
+ action a3 {printf( "%s", "a3\n" );
+}
+ action a4 {printf( "%s", "a4\n" );
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= eofact_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"",
+"h",
+"hell",
+"hello",
+"hello\n",
+"t",
+"ther",
+"there",
+"friend",
+};
+
+int inplen = 9;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/eofact_crack.rl b/test/trans.d/case/eofact_crack.rl
new file mode 100644
index 00000000..eb2e924a
--- /dev/null
+++ b/test/trans.d/case/eofact_crack.rl
@@ -0,0 +1,69 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {cout.format( "a1\n" );
+}
+ action a2 {cout.format( "a2\n" );
+}
+ action a3 {cout.format( "a3\n" );
+}
+ action a4 {cout.format( "a4\n" );
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= eofact_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "" );
+ m( "h" );
+ m( "hell" );
+ m( "hello" );
+ m( "hello\n" );
+ m( "t" );
+ m( "ther" );
+ m( "there" );
+ m( "friend" );
+}
+
+main();
diff --git a/test/trans.d/case/eofact_cs.rl b/test/trans.d/case/eofact_cs.rl
new file mode 100644
index 00000000..a1918623
--- /dev/null
+++ b/test/trans.d/case/eofact_cs.rl
@@ -0,0 +1,84 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {Console.Write( "a1\n" );}
+ action a2 {Console.Write( "a2\n" );}
+ action a3 {Console.Write( "a3\n" );}
+ action a4 {Console.Write( "a4\n" );}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= eofact_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"",
+"h",
+"hell",
+"hello",
+"hello\n",
+"t",
+"ther",
+"there",
+"friend",
+};
+
+
+static readonly int inplen = 9;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/eofact_d.rl b/test/trans.d/case/eofact_d.rl
new file mode 100644
index 00000000..5c975f0f
--- /dev/null
+++ b/test/trans.d/case/eofact_d.rl
@@ -0,0 +1,84 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class eofact
+{
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {printf( "%.*s", "a1\n" );}
+ action a2 {printf( "%.*s", "a2\n" );}
+ action a3 {printf( "%.*s", "a3\n" );}
+ action a4 {printf( "%.*s", "a4\n" );}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= eofact_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"",
+"h",
+"hell",
+"hello",
+"hello\n",
+"t",
+"ther",
+"there",
+"friend",
+];
+
+int inplen = 9;
+
+}
+int main()
+{
+ eofact m = new eofact();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/eofact_go.rl b/test/trans.d/case/eofact_go.rl
new file mode 100644
index 00000000..caa7d707
--- /dev/null
+++ b/test/trans.d/case/eofact_go.rl
@@ -0,0 +1,70 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {fmt.Print( "a1\n" );}
+ action a2 {fmt.Print( "a2\n" );}
+ action a3 {fmt.Print( "a3\n" );}
+ action a4 {fmt.Print( "a4\n" );}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= eofact_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"",
+"h",
+"hell",
+"hello",
+"hello\n",
+"t",
+"ther",
+"there",
+"friend",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/eofact_java.rl b/test/trans.d/case/eofact_java.rl
new file mode 100644
index 00000000..9496714c
--- /dev/null
+++ b/test/trans.d/case/eofact_java.rl
@@ -0,0 +1,85 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class eofact_java
+{
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {System.out.print( "a1\n" );
+}
+ action a2 {System.out.print( "a2\n" );
+}
+ action a3 {System.out.print( "a3\n" );
+}
+ action a4 {System.out.print( "a4\n" );
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= eofact_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"",
+"h",
+"hell",
+"hello",
+"hello\n",
+"t",
+"ther",
+"there",
+"friend",
+};
+
+static final int inplen = 9;
+
+public static void main (String[] args)
+{
+ eofact_java machine = new eofact_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/eofact_julia.rl b/test/trans.d/case/eofact_julia.rl
new file mode 100644
index 00000000..4b3eecd7
--- /dev/null
+++ b/test/trans.d/case/eofact_julia.rl
@@ -0,0 +1,58 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {print( "a1\n" );
+}
+ action a2 {print( "a2\n" );
+}
+ action a3 {print( "a3\n" );
+}
+ action a4 {print( "a4\n" );
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= eofact_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "" );
+ m( "h" );
+ m( "hell" );
+ m( "hello" );
+ m( "hello\n" );
+ m( "t" );
+ m( "ther" );
+ m( "there" );
+ m( "friend" );
diff --git a/test/trans.d/case/eofact_ocaml.rl b/test/trans.d/case/eofact_ocaml.rl
new file mode 100644
index 00000000..e8579c32
--- /dev/null
+++ b/test/trans.d/case/eofact_ocaml.rl
@@ -0,0 +1,61 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {print_string( "a1\n" );
+}
+ action a2 {print_string( "a2\n" );
+}
+ action a3 {print_string( "a3\n" );
+}
+ action a4 {print_string( "a4\n" );
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= eofact_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "";
+ exec "h";
+ exec "hell";
+ exec "hello";
+ exec "hello\n";
+ exec "t";
+ exec "ther";
+ exec "there";
+ exec "friend";
+ ()
+;;
+
diff --git a/test/trans.d/case/eofact_ruby.rl b/test/trans.d/case/eofact_ruby.rl
new file mode 100644
index 00000000..6cd5f4e5
--- /dev/null
+++ b/test/trans.d/case/eofact_ruby.rl
@@ -0,0 +1,66 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {print( "a1\n" );
+}
+ action a2 {print( "a2\n" );
+}
+ action a3 {print( "a3\n" );
+}
+ action a4 {print( "a4\n" );
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= eofact_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"",
+"h",
+"hell",
+"hello",
+"hello\n",
+"t",
+"ther",
+"there",
+"friend",
+]
+
+inplen = 9
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/eofact_rust.rl b/test/trans.d/case/eofact_rust.rl
new file mode 100644
index 00000000..5c8492dd
--- /dev/null
+++ b/test/trans.d/case/eofact_rust.rl
@@ -0,0 +1,65 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine eofact;
+
+ action a1 {print!( "{}", "a1\n" );
+}
+ action a2 {print!( "{}", "a2\n" );
+}
+ action a3 {print!( "{}", "a3\n" );
+}
+ action a4 {print!( "{}", "a4\n" );
+}
+
+
+ main := (
+ 'hello' @eof a1 %eof a2 '\n'? |
+ 'there' @eof a3 %eof a4
+ );
+
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= eofact_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "".to_string() ); }
+ unsafe { m( "h".to_string() ); }
+ unsafe { m( "hell".to_string() ); }
+ unsafe { m( "hello".to_string() ); }
+ unsafe { m( "hello\n".to_string() ); }
+ unsafe { m( "t".to_string() ); }
+ unsafe { m( "ther".to_string() ); }
+ unsafe { m( "there".to_string() ); }
+ unsafe { m( "friend".to_string() ); }
+}
+
diff --git a/test/trans.d/case/erract2.rl b/test/trans.d/case/erract2.rl
new file mode 100644
index 00000000..f6007151
--- /dev/null
+++ b/test/trans.d/case/erract2.rl
@@ -0,0 +1,90 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ *
+ * Test error actions.
+ */
+
+%%{
+ machine erract;
+
+ action err_start { print_str "err_start\n"; }
+ action err_all { print_str "err_all\n"; }
+ action err_middle { print_str "err_middle\n"; }
+ action err_out { print_str "err_out\n"; }
+
+ action eof_start { print_str "eof_start\n"; }
+ action eof_all { print_str "eof_all\n"; }
+ action eof_middle { print_str "eof_middle\n"; }
+ action eof_out { print_str "eof_out\n"; }
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+##### INPUT #####
+""
+"h"
+"x"
+"he"
+"hx"
+"hel"
+"hex"
+"hell"
+"helx"
+"hello"
+"hellx"
+"hello\n"
+"hellox"
+##### OUTPUT #####
+err_start
+eof_start
+err_all
+eof_all
+FAIL
+err_all
+err_middle
+eof_all
+eof_middle
+FAIL
+err_start
+err_all
+FAIL
+err_all
+err_middle
+eof_all
+eof_middle
+FAIL
+err_all
+err_middle
+FAIL
+err_all
+err_middle
+eof_all
+eof_middle
+FAIL
+err_all
+err_middle
+FAIL
+err_all
+err_middle
+eof_all
+eof_middle
+FAIL
+err_all
+err_middle
+FAIL
+err_all
+err_out
+eof_all
+eof_out
+FAIL
+err_all
+err_middle
+FAIL
+ACCEPT
+err_all
+err_out
+FAIL
diff --git a/test/trans.d/case/erract2_asm.rl b/test/trans.d/case/erract2_asm.rl
new file mode 100644
index 00000000..11e74664
--- /dev/null
+++ b/test/trans.d/case/erract2_asm.rl
@@ -0,0 +1,259 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {
+ .section .rodata
+1:
+ .string "err_start\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action err_all {
+ .section .rodata
+2:
+ .string "err_all\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action err_middle {
+ .section .rodata
+3:
+ .string "err_middle\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action err_out {
+ .section .rodata
+4:
+ .string "err_out\n"
+ .text
+ movq $4b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ action eof_start {
+ .section .rodata
+5:
+ .string "eof_start\n"
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action eof_all {
+ .section .rodata
+6:
+ .string "eof_all\n"
+ .text
+ movq $6b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action eof_middle {
+ .section .rodata
+7:
+ .string "eof_middle\n"
+ .text
+ movq $7b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action eof_out {
+ .section .rodata
+8:
+ .string "eof_out\n"
+ .text
+ movq $8b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq erract_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string ""
+.L_inp_1:
+ .string "h"
+.L_inp_2:
+ .string "x"
+.L_inp_3:
+ .string "he"
+.L_inp_4:
+ .string "hx"
+.L_inp_5:
+ .string "hel"
+.L_inp_6:
+ .string "hex"
+.L_inp_7:
+ .string "hell"
+.L_inp_8:
+ .string "helx"
+.L_inp_9:
+ .string "hello"
+.L_inp_10:
+ .string "hellx"
+.L_inp_11:
+ .string "hello\n"
+.L_inp_12:
+ .string "hellox"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+ .quad .L_inp_9
+ .quad .L_inp_10
+ .quad .L_inp_11
+ .quad .L_inp_12
+
+ .align 8
+inplen:
+ .quad 13
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/erract2_c.rl b/test/trans.d/case/erract2_c.rl
new file mode 100644
index 00000000..be05030f
--- /dev/null
+++ b/test/trans.d/case/erract2_c.rl
@@ -0,0 +1,95 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {printf( "%s", "err_start\n" );
+}
+ action err_all {printf( "%s", "err_all\n" );
+}
+ action err_middle {printf( "%s", "err_middle\n" );
+}
+ action err_out {printf( "%s", "err_out\n" );
+}
+
+ action eof_start {printf( "%s", "eof_start\n" );
+}
+ action eof_all {printf( "%s", "eof_all\n" );
+}
+ action eof_middle {printf( "%s", "eof_middle\n" );
+}
+ action eof_out {printf( "%s", "eof_out\n" );
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= erract_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"",
+"h",
+"x",
+"he",
+"hx",
+"hel",
+"hex",
+"hell",
+"helx",
+"hello",
+"hellx",
+"hello\n",
+"hellox",
+};
+
+int inplen = 13;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/erract2_crack.rl b/test/trans.d/case/erract2_crack.rl
new file mode 100644
index 00000000..0d419cad
--- /dev/null
+++ b/test/trans.d/case/erract2_crack.rl
@@ -0,0 +1,80 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {cout.format( "err_start\n" );
+}
+ action err_all {cout.format( "err_all\n" );
+}
+ action err_middle {cout.format( "err_middle\n" );
+}
+ action err_out {cout.format( "err_out\n" );
+}
+
+ action eof_start {cout.format( "eof_start\n" );
+}
+ action eof_all {cout.format( "eof_all\n" );
+}
+ action eof_middle {cout.format( "eof_middle\n" );
+}
+ action eof_out {cout.format( "eof_out\n" );
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= erract_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "" );
+ m( "h" );
+ m( "x" );
+ m( "he" );
+ m( "hx" );
+ m( "hel" );
+ m( "hex" );
+ m( "hell" );
+ m( "helx" );
+ m( "hello" );
+ m( "hellx" );
+ m( "hello\n" );
+ m( "hellox" );
+}
+
+main();
diff --git a/test/trans.d/case/erract2_cs.rl b/test/trans.d/case/erract2_cs.rl
new file mode 100644
index 00000000..3a264143
--- /dev/null
+++ b/test/trans.d/case/erract2_cs.rl
@@ -0,0 +1,91 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+
+%%{
+ machine erract;
+
+ action err_start {Console.Write( "err_start\n" );}
+ action err_all {Console.Write( "err_all\n" );}
+ action err_middle {Console.Write( "err_middle\n" );}
+ action err_out {Console.Write( "err_out\n" );}
+
+ action eof_start {Console.Write( "eof_start\n" );}
+ action eof_all {Console.Write( "eof_all\n" );}
+ action eof_middle {Console.Write( "eof_middle\n" );}
+ action eof_out {Console.Write( "eof_out\n" );}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= erract_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"",
+"h",
+"x",
+"he",
+"hx",
+"hel",
+"hex",
+"hell",
+"helx",
+"hello",
+"hellx",
+"hello\n",
+"hellox",
+};
+
+
+static readonly int inplen = 13;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/erract2_d.rl b/test/trans.d/case/erract2_d.rl
new file mode 100644
index 00000000..a6ca6d77
--- /dev/null
+++ b/test/trans.d/case/erract2_d.rl
@@ -0,0 +1,91 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class erract
+{
+
+
+
+%%{
+ machine erract;
+
+ action err_start {printf( "%.*s", "err_start\n" );}
+ action err_all {printf( "%.*s", "err_all\n" );}
+ action err_middle {printf( "%.*s", "err_middle\n" );}
+ action err_out {printf( "%.*s", "err_out\n" );}
+
+ action eof_start {printf( "%.*s", "eof_start\n" );}
+ action eof_all {printf( "%.*s", "eof_all\n" );}
+ action eof_middle {printf( "%.*s", "eof_middle\n" );}
+ action eof_out {printf( "%.*s", "eof_out\n" );}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= erract_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"",
+"h",
+"x",
+"he",
+"hx",
+"hel",
+"hex",
+"hell",
+"helx",
+"hello",
+"hellx",
+"hello\n",
+"hellox",
+];
+
+int inplen = 13;
+
+}
+int main()
+{
+ erract m = new erract();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/erract2_go.rl b/test/trans.d/case/erract2_go.rl
new file mode 100644
index 00000000..c7ba0989
--- /dev/null
+++ b/test/trans.d/case/erract2_go.rl
@@ -0,0 +1,77 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {fmt.Print( "err_start\n" );}
+ action err_all {fmt.Print( "err_all\n" );}
+ action err_middle {fmt.Print( "err_middle\n" );}
+ action err_out {fmt.Print( "err_out\n" );}
+
+ action eof_start {fmt.Print( "eof_start\n" );}
+ action eof_all {fmt.Print( "eof_all\n" );}
+ action eof_middle {fmt.Print( "eof_middle\n" );}
+ action eof_out {fmt.Print( "eof_out\n" );}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= erract_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"",
+"h",
+"x",
+"he",
+"hx",
+"hel",
+"hex",
+"hell",
+"helx",
+"hello",
+"hellx",
+"hello\n",
+"hellox",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/erract2_java.rl b/test/trans.d/case/erract2_java.rl
new file mode 100644
index 00000000..edda48fa
--- /dev/null
+++ b/test/trans.d/case/erract2_java.rl
@@ -0,0 +1,96 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class erract2_java
+{
+
+
+
+%%{
+ machine erract;
+
+ action err_start {System.out.print( "err_start\n" );
+}
+ action err_all {System.out.print( "err_all\n" );
+}
+ action err_middle {System.out.print( "err_middle\n" );
+}
+ action err_out {System.out.print( "err_out\n" );
+}
+
+ action eof_start {System.out.print( "eof_start\n" );
+}
+ action eof_all {System.out.print( "eof_all\n" );
+}
+ action eof_middle {System.out.print( "eof_middle\n" );
+}
+ action eof_out {System.out.print( "eof_out\n" );
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= erract_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"",
+"h",
+"x",
+"he",
+"hx",
+"hel",
+"hex",
+"hell",
+"helx",
+"hello",
+"hellx",
+"hello\n",
+"hellox",
+};
+
+static final int inplen = 13;
+
+public static void main (String[] args)
+{
+ erract2_java machine = new erract2_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/erract2_julia.rl b/test/trans.d/case/erract2_julia.rl
new file mode 100644
index 00000000..c8312cba
--- /dev/null
+++ b/test/trans.d/case/erract2_julia.rl
@@ -0,0 +1,69 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {print( "err_start\n" );
+}
+ action err_all {print( "err_all\n" );
+}
+ action err_middle {print( "err_middle\n" );
+}
+ action err_out {print( "err_out\n" );
+}
+
+ action eof_start {print( "eof_start\n" );
+}
+ action eof_all {print( "eof_all\n" );
+}
+ action eof_middle {print( "eof_middle\n" );
+}
+ action eof_out {print( "eof_out\n" );
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= erract_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "" );
+ m( "h" );
+ m( "x" );
+ m( "he" );
+ m( "hx" );
+ m( "hel" );
+ m( "hex" );
+ m( "hell" );
+ m( "helx" );
+ m( "hello" );
+ m( "hellx" );
+ m( "hello\n" );
+ m( "hellox" );
diff --git a/test/trans.d/case/erract2_ocaml.rl b/test/trans.d/case/erract2_ocaml.rl
new file mode 100644
index 00000000..dfeeaf5e
--- /dev/null
+++ b/test/trans.d/case/erract2_ocaml.rl
@@ -0,0 +1,72 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {print_string( "err_start\n" );
+}
+ action err_all {print_string( "err_all\n" );
+}
+ action err_middle {print_string( "err_middle\n" );
+}
+ action err_out {print_string( "err_out\n" );
+}
+
+ action eof_start {print_string( "eof_start\n" );
+}
+ action eof_all {print_string( "eof_all\n" );
+}
+ action eof_middle {print_string( "eof_middle\n" );
+}
+ action eof_out {print_string( "eof_out\n" );
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= erract_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "";
+ exec "h";
+ exec "x";
+ exec "he";
+ exec "hx";
+ exec "hel";
+ exec "hex";
+ exec "hell";
+ exec "helx";
+ exec "hello";
+ exec "hellx";
+ exec "hello\n";
+ exec "hellox";
+ ()
+;;
+
diff --git a/test/trans.d/case/erract2_ruby.rl b/test/trans.d/case/erract2_ruby.rl
new file mode 100644
index 00000000..0e65e2c0
--- /dev/null
+++ b/test/trans.d/case/erract2_ruby.rl
@@ -0,0 +1,77 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {print( "err_start\n" );
+}
+ action err_all {print( "err_all\n" );
+}
+ action err_middle {print( "err_middle\n" );
+}
+ action err_out {print( "err_out\n" );
+}
+
+ action eof_start {print( "eof_start\n" );
+}
+ action eof_all {print( "eof_all\n" );
+}
+ action eof_middle {print( "eof_middle\n" );
+}
+ action eof_out {print( "eof_out\n" );
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= erract_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"",
+"h",
+"x",
+"he",
+"hx",
+"hel",
+"hex",
+"hell",
+"helx",
+"hello",
+"hellx",
+"hello\n",
+"hellox",
+]
+
+inplen = 13
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/erract2_rust.rl b/test/trans.d/case/erract2_rust.rl
new file mode 100644
index 00000000..e541df3c
--- /dev/null
+++ b/test/trans.d/case/erract2_rust.rl
@@ -0,0 +1,76 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine erract;
+
+ action err_start {print!( "{}", "err_start\n" );
+}
+ action err_all {print!( "{}", "err_all\n" );
+}
+ action err_middle {print!( "{}", "err_middle\n" );
+}
+ action err_out {print!( "{}", "err_out\n" );
+}
+
+ action eof_start {print!( "{}", "eof_start\n" );
+}
+ action eof_all {print!( "{}", "eof_all\n" );
+}
+ action eof_middle {print!( "{}", "eof_middle\n" );
+}
+ action eof_out {print!( "{}", "eof_out\n" );
+}
+
+ main := ( 'hello'
+ >err err_start $err err_all <>err err_middle %err err_out
+ >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out
+ ) '\n';
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= erract_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "".to_string() ); }
+ unsafe { m( "h".to_string() ); }
+ unsafe { m( "x".to_string() ); }
+ unsafe { m( "he".to_string() ); }
+ unsafe { m( "hx".to_string() ); }
+ unsafe { m( "hel".to_string() ); }
+ unsafe { m( "hex".to_string() ); }
+ unsafe { m( "hell".to_string() ); }
+ unsafe { m( "helx".to_string() ); }
+ unsafe { m( "hello".to_string() ); }
+ unsafe { m( "hellx".to_string() ); }
+ unsafe { m( "hello\n".to_string() ); }
+ unsafe { m( "hellox".to_string() ); }
+}
+
diff --git a/test/trans.d/case/goto1.rl b/test/trans.d/case/goto1.rl
new file mode 100644
index 00000000..4b9385bd
--- /dev/null
+++ b/test/trans.d/case/goto1.rl
@@ -0,0 +1,37 @@
+/*
+ * @LANG: indep
+ * @PROHIBIT_LANGUAGES: ruby ocaml
+ */
+
+int target;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ print_str "one\n";
+ target = fentry(main);
+ fgoto *target;
+ };
+
+ two := 'two' @{
+ print_str "two\n";
+ target = fentry(main);
+ fgoto *target;
+ };
+
+ main :=
+ '1' @{ target = fentry(one); fgoto *target; }
+ | '2' @{ target = fentry(two); fgoto *target; }
+ | '\n';
+}%%
+
+##### INPUT #####
+"1one2two1one\n"
+##### OUTPUT #####
+one
+two
+one
+ACCEPT
diff --git a/test/trans.d/case/goto1_asm.rl b/test/trans.d/case/goto1_asm.rl
new file mode 100644
index 00000000..f92f45a6
--- /dev/null
+++ b/test/trans.d/case/goto1_asm.rl
@@ -0,0 +1,187 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm target,8,8
+ .text
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ .section .rodata
+1:
+ .string "one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(main), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fgoto * %rcx;
+
+};
+
+ two := 'two' @{
+ .section .rodata
+2:
+ .string "two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(main), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fgoto * %rcx;
+
+};
+
+ main :=
+ '1' @{
+ movq $fentry(one), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fgoto * %rcx;
+
+}
+ | '2' @{
+ movq $fentry(two), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fgoto * %rcx;
+
+}
+ | '\n';
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq goto1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1one2two1one\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/goto1_c.rl b/test/trans.d/case/goto1_c.rl
new file mode 100644
index 00000000..729c5c5a
--- /dev/null
+++ b/test/trans.d/case/goto1_c.rl
@@ -0,0 +1,75 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int target ;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%s", "one\n" );
+target = fentry(main);
+fgoto *target;};
+
+ two := 'two' @{printf( "%s", "two\n" );
+target = fentry(main);
+fgoto *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;}
+ | '2' @{target = fentry(two);
+fgoto *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= goto1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1one2two1one\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/goto1_crack.rl b/test/trans.d/case/goto1_crack.rl
new file mode 100644
index 00000000..6a124918
--- /dev/null
+++ b/test/trans.d/case/goto1_crack.rl
@@ -0,0 +1,60 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int target;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{cout.format( "one\n" );
+target = fentry(main);
+fgoto *target;};
+
+ two := 'two' @{cout.format( "two\n" );
+target = fentry(main);
+fgoto *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;}
+ | '2' @{target = fentry(two);
+fgoto *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= goto1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1one2two1one\n" );
+}
+
+main();
diff --git a/test/trans.d/case/goto1_cs.rl b/test/trans.d/case/goto1_cs.rl
new file mode 100644
index 00000000..bf95503a
--- /dev/null
+++ b/test/trans.d/case/goto1_cs.rl
@@ -0,0 +1,78 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int target;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{Console.Write( "one\n" );target = fentry(main);
+fgoto *target;};
+
+ two := 'two' @{Console.Write( "two\n" );target = fentry(main);
+fgoto *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;}
+ | '2' @{target = fentry(two);
+fgoto *target;}
+ | '\n';
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= goto1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1one2two1one\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/goto1_d.rl b/test/trans.d/case/goto1_d.rl
new file mode 100644
index 00000000..dc7979cd
--- /dev/null
+++ b/test/trans.d/case/goto1_d.rl
@@ -0,0 +1,77 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class goto1
+{
+int target;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%.*s", "one\n" );target = fentry(main);
+fgoto *target;};
+
+ two := 'two' @{printf( "%.*s", "two\n" );target = fentry(main);
+fgoto *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;}
+ | '2' @{target = fentry(two);
+fgoto *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= goto1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1one2two1one\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ goto1 m = new goto1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/goto1_go.rl b/test/trans.d/case/goto1_go.rl
new file mode 100644
index 00000000..ba6df377
--- /dev/null
+++ b/test/trans.d/case/goto1_go.rl
@@ -0,0 +1,69 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var target int ;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{fmt.Print( "one\n" );target = fentry(main);
+fgoto *target;
+
+};
+
+ two := 'two' @{fmt.Print( "two\n" );target = fentry(main);
+fgoto *target;
+
+};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;
+}
+ | '2' @{target = fentry(two);
+fgoto *target;
+}
+ | '\n';
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= goto1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1one2two1one\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/goto1_java.rl b/test/trans.d/case/goto1_java.rl
new file mode 100644
index 00000000..668faaf7
--- /dev/null
+++ b/test/trans.d/case/goto1_java.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class goto1_java
+{
+int target ;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{System.out.print( "one\n" );
+target = fentry(main);
+fgoto *target;};
+
+ two := 'two' @{System.out.print( "two\n" );
+target = fentry(main);
+fgoto *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;}
+ | '2' @{target = fentry(two);
+fgoto *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= goto1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1one2two1one\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ goto1_java machine = new goto1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/goto1_julia.rl b/test/trans.d/case/goto1_julia.rl
new file mode 100644
index 00000000..33bc2a6d
--- /dev/null
+++ b/test/trans.d/case/goto1_julia.rl
@@ -0,0 +1,50 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+target = fentry(main);
+fgoto *target;};
+
+ two := 'two' @{print( "two\n" );
+target = fentry(main);
+fgoto *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;}
+ | '2' @{target = fentry(two);
+fgoto *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+target = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= goto1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1one2two1one\n" );
diff --git a/test/trans.d/case/goto1_rust.rl b/test/trans.d/case/goto1_rust.rl
new file mode 100644
index 00000000..ac7e4ee8
--- /dev/null
+++ b/test/trans.d/case/goto1_rust.rl
@@ -0,0 +1,57 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut target : i32 = 0;
+
+%%{
+ machine goto1;
+
+ unused := 'unused';
+
+ one := 'one' @{print!( "{}", "one\n" );
+target = fentry(main);
+fgoto *target;};
+
+ two := 'two' @{print!( "{}", "two\n" );
+target = fentry(main);
+fgoto *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fgoto *target;}
+ | '2' @{target = fentry(two);
+fgoto *target;}
+ | '\n';
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= goto1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1one2two1one\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/gotocallret1.rl b/test/trans.d/case/gotocallret1.rl
new file mode 100644
index 00000000..91804725
--- /dev/null
+++ b/test/trans.d/case/gotocallret1.rl
@@ -0,0 +1,117 @@
+/*
+ * @LANG: indep
+ * @PROHIBIT_LANGUAGES: ruby ocaml
+ * @PROHIBIT_FEATFLAGS: --var-backend
+ * @NEEDS_EOF: yes
+ */
+
+/*
+ * Demonstrate the use of goto, call and return. This machine expects either a
+ * lower case char or a digit as a command then a space followed by the command
+ * arg. If the command is a char, then the arg must be an a string of chars.
+ * If the command is a digit, then the arg must be a string of digits. This
+ * choice is determined by action code, rather than though transition
+ * desitinations.
+ */
+
+char comm;
+int top;
+int stack[32];
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction { fentry(garble_line); }
+
+ action err_garbling_line { print_str "error: garbling line\n"; }
+ action goto_main { fgoto main; }
+ action recovery_failed { print_str "error: failed to recover\n"; }
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold; fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {
+ if ( comm >= 'a' ) {
+ fcall alp_comm;
+ } else {
+ fcall dig_comm;
+ }
+ }
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n'
+ ) @{print_str "correct command\n";};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+##### INPUT #####
+"lkajsdf\n"
+"2134\n"
+"(\n"
+"\n"
+"*234234()0909 092 -234aslkf09`1 11\n"
+"1\n"
+"909\n"
+"1 a\n"
+"11 1\n"
+"a 1\n"
+"aa a\n"
+"1 1\n"
+"1 123456\n"
+"a a\n"
+"a abcdef\n"
+"h"
+"a aa1"
+##### OUTPUT #####
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+correct command
+ACCEPT
+correct command
+ACCEPT
+correct command
+ACCEPT
+correct command
+ACCEPT
+error: failed to recover
+FAIL
+error: garbling line
+error: failed to recover
+FAIL
diff --git a/test/trans.d/case/gotocallret1_asm.rl b/test/trans.d/case/gotocallret1_asm.rl
new file mode 100644
index 00000000..f43b3760
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_asm.rl
@@ -0,0 +1,280 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm comm,8,8
+ .text
+ .section .data
+ .comm top,8,8
+ .text
+ .section .data
+ .comm stack,8,8
+ .text
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {
+ movq $fentry(garble_line), %rax
+ pushq %rax
+ popq %rax
+
+}
+
+ action err_garbling_line {
+ .section .rodata
+1:
+ .string "error: garbling line\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action goto_main {
+ fgoto main;
+
+}
+ action recovery_failed {
+ .section .rodata
+2:
+ .string "error: failed to recover\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {
+ fhold;
+fret;
+
+}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {
+ movq comm (%rip), %rax
+ pushq %rax
+ movq $97, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ setge %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 3f
+fcall alp_comm;
+
+ jmp 4f
+3:
+fcall dig_comm;
+
+4:
+
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{
+ movsbq (%r12), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, comm (%rip)
+
+} ' ' @comm_arg '\n'
+ ) @{
+ .section .rodata
+5:
+ .string "correct command\n"
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{
+ fhold;
+fgoto garble_line;
+
+};
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq GotoCallRet_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "lkajsdf\n"
+.L_inp_1:
+ .string "2134\n"
+.L_inp_2:
+ .string "(\n"
+.L_inp_3:
+ .string "\n"
+.L_inp_4:
+ .string "*234234()0909 092 -234aslkf09`1 11\n"
+.L_inp_5:
+ .string "1\n"
+.L_inp_6:
+ .string "909\n"
+.L_inp_7:
+ .string "1 a\n"
+.L_inp_8:
+ .string "11 1\n"
+.L_inp_9:
+ .string "a 1\n"
+.L_inp_10:
+ .string "aa a\n"
+.L_inp_11:
+ .string "1 1\n"
+.L_inp_12:
+ .string "1 123456\n"
+.L_inp_13:
+ .string "a a\n"
+.L_inp_14:
+ .string "a abcdef\n"
+.L_inp_15:
+ .string "h"
+.L_inp_16:
+ .string "a aa1"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+ .quad .L_inp_9
+ .quad .L_inp_10
+ .quad .L_inp_11
+ .quad .L_inp_12
+ .quad .L_inp_13
+ .quad .L_inp_14
+ .quad .L_inp_15
+ .quad .L_inp_16
+
+ .align 8
+inplen:
+ .quad 17
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/gotocallret1_c.rl b/test/trans.d/case/gotocallret1_c.rl
new file mode 100644
index 00000000..6759cc15
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_c.rl
@@ -0,0 +1,122 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char comm ;
+int top ;
+int stack [32];
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {printf( "%s", "error: garbling line\n" );
+}
+ action goto_main {fgoto main;}
+ action recovery_failed {printf( "%s", "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' )
+{
+ fcall alp_comm;
+}
+else {
+ fcall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{printf( "%s", "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+int inplen = 17;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/gotocallret1_crack.rl b/test/trans.d/case/gotocallret1_crack.rl
new file mode 100644
index 00000000..1f1f1aa2
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_crack.rl
@@ -0,0 +1,107 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+byte comm;
+int top;
+array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {cout.format( "error: garbling line\n" );
+}
+ action goto_main {fgoto main;}
+ action recovery_failed {cout.format( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' )
+{
+ fcall alp_comm;
+}
+else {
+ fcall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{cout.format( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= GotoCallRet_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "lkajsdf\n" );
+ m( "2134\n" );
+ m( "(\n" );
+ m( "\n" );
+ m( "*234234()0909 092 -234aslkf09`1 11\n" );
+ m( "1\n" );
+ m( "909\n" );
+ m( "1 a\n" );
+ m( "11 1\n" );
+ m( "a 1\n" );
+ m( "aa a\n" );
+ m( "1 1\n" );
+ m( "1 123456\n" );
+ m( "a a\n" );
+ m( "a abcdef\n" );
+ m( "h" );
+ m( "a aa1" );
+}
+
+main();
diff --git a/test/trans.d/case/gotocallret1_cs.rl b/test/trans.d/case/gotocallret1_cs.rl
new file mode 100644
index 00000000..37a005e8
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_cs.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+char comm;
+int top;
+int [] stack = new int [32];
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {Console.Write( "error: garbling line\n" );}
+ action goto_main {fgoto main;}
+ action recovery_failed {Console.Write( "error: failed to recover\n" );}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' )
+{
+ fcall alp_comm;
+}
+else {
+ fcall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{Console.Write( "correct command\n" );};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+
+static readonly int inplen = 17;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/gotocallret1_d.rl b/test/trans.d/case/gotocallret1_d.rl
new file mode 100644
index 00000000..ba4f57e2
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_d.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class GotoCallRet
+{
+char comm;
+int top;
+int stack[32];
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {printf( "%.*s", "error: garbling line\n" );}
+ action goto_main {fgoto main;}
+ action recovery_failed {printf( "%.*s", "error: failed to recover\n" );}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' )
+{
+ fcall alp_comm;
+}
+else {
+ fcall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{printf( "%.*s", "correct command\n" );};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+];
+
+int inplen = 17;
+
+}
+int main()
+{
+ GotoCallRet m = new GotoCallRet();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/gotocallret1_go.rl b/test/trans.d/case/gotocallret1_go.rl
new file mode 100644
index 00000000..5806cd76
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_go.rl
@@ -0,0 +1,116 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var comm byte ;
+var top int ;
+var stack [32] int ;
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {fmt.Print( "error: garbling line\n" );}
+ action goto_main {fgoto main;
+}
+ action recovery_failed {fmt.Print( "error: failed to recover\n" );}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;
+fret;
+}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' ) {
+ fcall alp_comm;
+
+
+} else {
+ fcall dig_comm;
+
+
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{fmt.Print( "correct command\n" );};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;
+fgoto garble_line;
+};
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= GotoCallRet_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/gotocallret1_java.rl b/test/trans.d/case/gotocallret1_java.rl
new file mode 100644
index 00000000..343ade95
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_java.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class gotocallret1_java
+{
+char comm ;
+int top ;
+int stack [] = new int[32];
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {System.out.print( "error: garbling line\n" );
+}
+ action goto_main {fgoto main;}
+ action recovery_failed {System.out.print( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' )
+{
+ fcall alp_comm;
+}
+else {
+ fcall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{System.out.print( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+static final int inplen = 17;
+
+public static void main (String[] args)
+{
+ gotocallret1_java machine = new gotocallret1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/gotocallret1_julia.rl b/test/trans.d/case/gotocallret1_julia.rl
new file mode 100644
index 00000000..3b7c980a
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_julia.rl
@@ -0,0 +1,94 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {print( "error: garbling line\n" );
+}
+ action goto_main {fgoto main;}
+ action recovery_failed {print( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' )
+ fcall alp_comm;
+else
+ fcall dig_comm;
+end
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{print( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+comm = 0;
+top = 0;
+stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= GotoCallRet_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "lkajsdf\n" );
+ m( "2134\n" );
+ m( "(\n" );
+ m( "\n" );
+ m( "*234234()0909 092 -234aslkf09`1 11\n" );
+ m( "1\n" );
+ m( "909\n" );
+ m( "1 a\n" );
+ m( "11 1\n" );
+ m( "a 1\n" );
+ m( "aa a\n" );
+ m( "1 1\n" );
+ m( "1 123456\n" );
+ m( "a a\n" );
+ m( "a abcdef\n" );
+ m( "h" );
+ m( "a aa1" );
diff --git a/test/trans.d/case/gotocallret1_rust.rl b/test/trans.d/case/gotocallret1_rust.rl
new file mode 100644
index 00000000..308d9eae
--- /dev/null
+++ b/test/trans.d/case/gotocallret1_rust.rl
@@ -0,0 +1,103 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut comm : u8 = 0;
+static mut top : i32 = 0;
+static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+%%{
+ machine GotoCallRet;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {print!( "{}", "error: garbling line\n" );
+}
+ action goto_main {fgoto main;}
+ action recovery_failed {print!( "{}", "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 'a' )
+{
+ fcall alp_comm;
+}
+else {
+ fcall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg '\n'
+ ) @{print!( "{}", "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fgoto garble_line;};
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= GotoCallRet_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "lkajsdf\n".to_string() ); }
+ unsafe { m( "2134\n".to_string() ); }
+ unsafe { m( "(\n".to_string() ); }
+ unsafe { m( "\n".to_string() ); }
+ unsafe { m( "*234234()0909 092 -234aslkf09`1 11\n".to_string() ); }
+ unsafe { m( "1\n".to_string() ); }
+ unsafe { m( "909\n".to_string() ); }
+ unsafe { m( "1 a\n".to_string() ); }
+ unsafe { m( "11 1\n".to_string() ); }
+ unsafe { m( "a 1\n".to_string() ); }
+ unsafe { m( "aa a\n".to_string() ); }
+ unsafe { m( "1 1\n".to_string() ); }
+ unsafe { m( "1 123456\n".to_string() ); }
+ unsafe { m( "a a\n".to_string() ); }
+ unsafe { m( "a abcdef\n".to_string() ); }
+ unsafe { m( "h".to_string() ); }
+ unsafe { m( "a aa1".to_string() ); }
+}
+
diff --git a/test/trans.d/case/gotocallret2.rl b/test/trans.d/case/gotocallret2.rl
new file mode 100644
index 00000000..31dd13d7
--- /dev/null
+++ b/test/trans.d/case/gotocallret2.rl
@@ -0,0 +1,78 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ * @PROHIBIT_LANGUAGES: ruby ocaml
+ * @PROHIBIT_FEATFLAGS: --var-backend
+ */
+
+char comm;
+int top;
+int stack[32];
+ptr ts;
+ptr te;
+int act;
+int val;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{
+ print_str "handle ";
+ fhold;
+ if ( val == 1 ) { fnext *fentry(one); }
+ if ( val == 2 ) { fnext *fentry(two); }
+ if ( val == 3 ) { fnext main; }
+ };
+
+ one := |*
+ '{' => { print_str "{ "; fcall *fentry(one); };
+ "[" => { print_str "[ "; fcall *fentry(two); };
+ "}" sp* => { print_str "} "; fret; };
+ [a-z]+ => { print_str "word "; val = 1; fgoto *fentry(handle); };
+ ' ' => { print_str "space "; };
+ *|;
+
+ two := |*
+ '{' => { print_str "{ "; fcall *fentry(one); };
+ "[" => { print_str "[ "; fcall *fentry(two); };
+ ']' sp* => { print_str "] "; fret; };
+ [a-z]+ => { print_str "word "; val = 2; fgoto *fentry(handle); };
+ ' ' => { print_str "space "; };
+ *|;
+
+ main := |*
+ '{' => { print_str "{ "; fcall one; };
+ "[" => { print_str "[ "; fcall two; };
+ [a-z]+ => { print_str "word "; val = 3; fgoto handle; };
+ [a-z] ' foil' => { print_str "this is the foil";};
+ ' ' => { print_str "space "; };
+ '\n';
+ *|;
+}%%
+
+##### INPUT #####
+"{a{b[c d]d}c}\n"
+"[a{b[c d]d}c}\n"
+"[a[b]c]d{ef{g{h}i}j}l\n"
+"{{[]}}\n"
+"a b c\n"
+"{a b c}\n"
+"[a b c]\n"
+"{]\n"
+"{{}\n"
+"[[[[[[]]]]]]\n"
+"[[[[[[]]}]]]\n"
+##### OUTPUT #####
+{ word handle { word handle [ word handle space word handle ] word handle } word handle } ACCEPT
+[ word handle { word handle [ word handle space word handle ] word handle } word handle FAIL
+[ word handle [ word handle ] word handle ] word handle { word handle { word handle { word handle } word handle } word handle } word handle ACCEPT
+{ { [ ] } } ACCEPT
+word handle space word handle space word handle ACCEPT
+{ word handle space word handle space word handle } ACCEPT
+[ word handle space word handle space word handle ] ACCEPT
+{ FAIL
+{ { } FAIL
+[ [ [ [ [ [ ] ] ] ] ] ] ACCEPT
+[ [ [ [ [ [ ] ] FAIL
diff --git a/test/trans.d/case/gotocallret2_asm.rl b/test/trans.d/case/gotocallret2_asm.rl
new file mode 100644
index 00000000..47253b18
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_asm.rl
@@ -0,0 +1,484 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm comm,8,8
+ .text
+ .section .data
+ .comm top,8,8
+ .text
+ .section .data
+ .comm stack,8,8
+ .text
+ .section .data
+ .comm ts,8,8
+ .text
+ .section .data
+ .comm te,8,8
+ .text
+ .section .data
+ .comm act,8,8
+ .text
+ .section .data
+ .comm val,8,8
+ .text
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{
+ .section .rodata
+1:
+ .string "handle "
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fhold;
+
+ movq val (%rip), %rax
+ pushq %rax
+ movq $1 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 2f
+ movq $fentry(one), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+2:
+ movq val (%rip), %rax
+ pushq %rax
+ movq $2 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 4f
+ movq $fentry(two), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+4:
+ movq val (%rip), %rax
+ pushq %rax
+ movq $3 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 6f
+fnext main;
+6:
+
+};
+
+ one := |*
+ '{' => {
+ .section .rodata
+8:
+ .string "{ "
+ .text
+ movq $8b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(one), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fcall * %rcx;
+
+};
+ "[" => {
+ .section .rodata
+9:
+ .string "[ "
+ .text
+ movq $9b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(two), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fcall * %rcx;
+
+};
+ "}" sp* => {
+ .section .rodata
+10:
+ .string "} "
+ .text
+ movq $10b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fret;
+
+};
+ [a-z]+ => {
+ .section .rodata
+11:
+ .string "word "
+ .text
+ movq $11b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, val (%rip)
+ movq $fentry(handle), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fgoto * %rcx;
+
+};
+ ' ' => {
+ .section .rodata
+12:
+ .string "space "
+ .text
+ movq $12b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ *|;
+
+ two := |*
+ '{' => {
+ .section .rodata
+13:
+ .string "{ "
+ .text
+ movq $13b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(one), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fcall * %rcx;
+
+};
+ "[" => {
+ .section .rodata
+14:
+ .string "[ "
+ .text
+ movq $14b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(two), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fcall * %rcx;
+
+};
+ ']' sp* => {
+ .section .rodata
+15:
+ .string "] "
+ .text
+ movq $15b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fret;
+
+};
+ [a-z]+ => {
+ .section .rodata
+16:
+ .string "word "
+ .text
+ movq $16b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $2, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, val (%rip)
+ movq $fentry(handle), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fgoto * %rcx;
+
+};
+ ' ' => {
+ .section .rodata
+17:
+ .string "space "
+ .text
+ movq $17b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ *|;
+
+ main := |*
+ '{' => {
+ .section .rodata
+18:
+ .string "{ "
+ .text
+ movq $18b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fcall one;
+
+};
+ "[" => {
+ .section .rodata
+19:
+ .string "[ "
+ .text
+ movq $19b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fcall two;
+
+};
+ [a-z]+ => {
+ .section .rodata
+20:
+ .string "word "
+ .text
+ movq $20b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $3, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, val (%rip)
+fgoto handle;
+
+};
+ [a-z] ' foil' => {
+ .section .rodata
+21:
+ .string "this is the foil"
+ .text
+ movq $21b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ ' ' => {
+ .section .rodata
+22:
+ .string "space "
+ .text
+ movq $22b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '\n';
+ *|;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq GotoCallRet_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "{a{b[c d]d}c}\n"
+.L_inp_1:
+ .string "[a{b[c d]d}c}\n"
+.L_inp_2:
+ .string "[a[b]c]d{ef{g{h}i}j}l\n"
+.L_inp_3:
+ .string "{{[]}}\n"
+.L_inp_4:
+ .string "a b c\n"
+.L_inp_5:
+ .string "{a b c}\n"
+.L_inp_6:
+ .string "[a b c]\n"
+.L_inp_7:
+ .string "{]\n"
+.L_inp_8:
+ .string "{{}\n"
+.L_inp_9:
+ .string "[[[[[[]]]]]]\n"
+.L_inp_10:
+ .string "[[[[[[]]}]]]\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+ .quad .L_inp_9
+ .quad .L_inp_10
+
+ .align 8
+inplen:
+ .quad 11
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/gotocallret2_c.rl b/test/trans.d/case/gotocallret2_c.rl
new file mode 100644
index 00000000..26a54187
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_c.rl
@@ -0,0 +1,135 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char comm ;
+int top ;
+int stack [32];
+char * ts ;
+char * te ;
+int act ;
+int val ;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{printf( "%s", "handle " );
+fhold;if ( val == 1 )
+{
+ fnext *fentry(one);
+}
+if ( val == 2 )
+{
+ fnext *fentry(two);
+}
+if ( val == 3 )
+{
+ fnext main;
+}
+};
+
+ one := |*
+ '{' => {printf( "%s", "{ " );
+fcall *fentry(one);};
+ "[" => {printf( "%s", "[ " );
+fcall *fentry(two);};
+ "}" sp* => {printf( "%s", "} " );
+fret;};
+ [a-z]+ => {printf( "%s", "word " );
+val = 1;
+fgoto *fentry(handle);};
+ ' ' => {printf( "%s", "space " );
+};
+ *|;
+
+ two := |*
+ '{' => {printf( "%s", "{ " );
+fcall *fentry(one);};
+ "[" => {printf( "%s", "[ " );
+fcall *fentry(two);};
+ ']' sp* => {printf( "%s", "] " );
+fret;};
+ [a-z]+ => {printf( "%s", "word " );
+val = 2;
+fgoto *fentry(handle);};
+ ' ' => {printf( "%s", "space " );
+};
+ *|;
+
+ main := |*
+ '{' => {printf( "%s", "{ " );
+fcall one;};
+ "[" => {printf( "%s", "[ " );
+fcall two;};
+ [a-z]+ => {printf( "%s", "word " );
+val = 3;
+fgoto handle;};
+ [a-z] ' foil' => {printf( "%s", "this is the foil" );
+};
+ ' ' => {printf( "%s", "space " );
+};
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"{a{b[c d]d}c}\n",
+"[a{b[c d]d}c}\n",
+"[a[b]c]d{ef{g{h}i}j}l\n",
+"{{[]}}\n",
+"a b c\n",
+"{a b c}\n",
+"[a b c]\n",
+"{]\n",
+"{{}\n",
+"[[[[[[]]]]]]\n",
+"[[[[[[]]}]]]\n",
+};
+
+int inplen = 11;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/gotocallret2_crack.rl b/test/trans.d/case/gotocallret2_crack.rl
new file mode 100644
index 00000000..23e22f48
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_crack.rl
@@ -0,0 +1,122 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+byte comm;
+int top;
+array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+int
+ ts;
+int
+ te;
+int act;
+int val;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{cout.format( "handle " );
+fhold;if ( val == 1 )
+{
+ fnext *fentry(one);
+}
+if ( val == 2 )
+{
+ fnext *fentry(two);
+}
+if ( val == 3 )
+{
+ fnext main;
+}
+};
+
+ one := |*
+ '{' => {cout.format( "{ " );
+fcall *fentry(one);};
+ "[" => {cout.format( "[ " );
+fcall *fentry(two);};
+ "}" sp* => {cout.format( "} " );
+fret;};
+ [a-z]+ => {cout.format( "word " );
+val = 1;
+fgoto *fentry(handle);};
+ ' ' => {cout.format( "space " );
+};
+ *|;
+
+ two := |*
+ '{' => {cout.format( "{ " );
+fcall *fentry(one);};
+ "[" => {cout.format( "[ " );
+fcall *fentry(two);};
+ ']' sp* => {cout.format( "] " );
+fret;};
+ [a-z]+ => {cout.format( "word " );
+val = 2;
+fgoto *fentry(handle);};
+ ' ' => {cout.format( "space " );
+};
+ *|;
+
+ main := |*
+ '{' => {cout.format( "{ " );
+fcall one;};
+ "[" => {cout.format( "[ " );
+fcall two;};
+ [a-z]+ => {cout.format( "word " );
+val = 3;
+fgoto handle;};
+ [a-z] ' foil' => {cout.format( "this is the foil" );
+};
+ ' ' => {cout.format( "space " );
+};
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= GotoCallRet_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "{a{b[c d]d}c}\n" );
+ m( "[a{b[c d]d}c}\n" );
+ m( "[a[b]c]d{ef{g{h}i}j}l\n" );
+ m( "{{[]}}\n" );
+ m( "a b c\n" );
+ m( "{a b c}\n" );
+ m( "[a b c]\n" );
+ m( "{]\n" );
+ m( "{{}\n" );
+ m( "[[[[[[]]]]]]\n" );
+ m( "[[[[[[]]}]]]\n" );
+}
+
+main();
diff --git a/test/trans.d/case/gotocallret2_cs.rl b/test/trans.d/case/gotocallret2_cs.rl
new file mode 100644
index 00000000..dc806d0a
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_cs.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+char comm;
+int top;
+int [] stack = new int [32];
+int ts;
+int te;
+int act;
+int val;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{Console.Write( "handle " );fhold;if ( val == 1 )
+{
+ fnext *fentry(one);
+}
+if ( val == 2 )
+{
+ fnext *fentry(two);
+}
+if ( val == 3 )
+{
+ fnext main;
+}
+};
+
+ one := |*
+ '{' => {Console.Write( "{ " );fcall *fentry(one);};
+ "[" => {Console.Write( "[ " );fcall *fentry(two);};
+ "}" sp* => {Console.Write( "} " );fret;};
+ [a-z]+ => {Console.Write( "word " );val = 1;
+fgoto *fentry(handle);};
+ ' ' => {Console.Write( "space " );};
+ *|;
+
+ two := |*
+ '{' => {Console.Write( "{ " );fcall *fentry(one);};
+ "[" => {Console.Write( "[ " );fcall *fentry(two);};
+ ']' sp* => {Console.Write( "] " );fret;};
+ [a-z]+ => {Console.Write( "word " );val = 2;
+fgoto *fentry(handle);};
+ ' ' => {Console.Write( "space " );};
+ *|;
+
+ main := |*
+ '{' => {Console.Write( "{ " );fcall one;};
+ "[" => {Console.Write( "[ " );fcall two;};
+ [a-z]+ => {Console.Write( "word " );val = 3;
+fgoto handle;};
+ [a-z] ' foil' => {Console.Write( "this is the foil" );};
+ ' ' => {Console.Write( "space " );};
+ '\n';
+ *|;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"{a{b[c d]d}c}\n",
+"[a{b[c d]d}c}\n",
+"[a[b]c]d{ef{g{h}i}j}l\n",
+"{{[]}}\n",
+"a b c\n",
+"{a b c}\n",
+"[a b c]\n",
+"{]\n",
+"{{}\n",
+"[[[[[[]]]]]]\n",
+"[[[[[[]]}]]]\n",
+};
+
+
+static readonly int inplen = 11;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/gotocallret2_d.rl b/test/trans.d/case/gotocallret2_d.rl
new file mode 100644
index 00000000..1aa67996
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_d.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class GotoCallRet
+{
+char comm;
+int top;
+int stack[32];
+const(char) * ts;
+const(char) * te;
+int act;
+int val;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{printf( "%.*s", "handle " );fhold;if ( val == 1 )
+{
+ fnext *fentry(one);
+}
+if ( val == 2 )
+{
+ fnext *fentry(two);
+}
+if ( val == 3 )
+{
+ fnext main;
+}
+};
+
+ one := |*
+ '{' => {printf( "%.*s", "{ " );fcall *fentry(one);};
+ "[" => {printf( "%.*s", "[ " );fcall *fentry(two);};
+ "}" sp* => {printf( "%.*s", "} " );fret;};
+ [a-z]+ => {printf( "%.*s", "word " );val = 1;
+fgoto *fentry(handle);};
+ ' ' => {printf( "%.*s", "space " );};
+ *|;
+
+ two := |*
+ '{' => {printf( "%.*s", "{ " );fcall *fentry(one);};
+ "[" => {printf( "%.*s", "[ " );fcall *fentry(two);};
+ ']' sp* => {printf( "%.*s", "] " );fret;};
+ [a-z]+ => {printf( "%.*s", "word " );val = 2;
+fgoto *fentry(handle);};
+ ' ' => {printf( "%.*s", "space " );};
+ *|;
+
+ main := |*
+ '{' => {printf( "%.*s", "{ " );fcall one;};
+ "[" => {printf( "%.*s", "[ " );fcall two;};
+ [a-z]+ => {printf( "%.*s", "word " );val = 3;
+fgoto handle;};
+ [a-z] ' foil' => {printf( "%.*s", "this is the foil" );};
+ ' ' => {printf( "%.*s", "space " );};
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"{a{b[c d]d}c}\n",
+"[a{b[c d]d}c}\n",
+"[a[b]c]d{ef{g{h}i}j}l\n",
+"{{[]}}\n",
+"a b c\n",
+"{a b c}\n",
+"[a b c]\n",
+"{]\n",
+"{{}\n",
+"[[[[[[]]]]]]\n",
+"[[[[[[]]}]]]\n",
+];
+
+int inplen = 11;
+
+}
+int main()
+{
+ GotoCallRet m = new GotoCallRet();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/gotocallret2_go.rl b/test/trans.d/case/gotocallret2_go.rl
new file mode 100644
index 00000000..0a13ab3f
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_go.rl
@@ -0,0 +1,122 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var comm byte ;
+var top int ;
+var stack [32] int ;
+var ts int ;
+var te int ;
+var act int ;
+var val int ;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{fmt.Print( "handle " );fhold;
+
+if ( val == 1 ) {
+ fnext *fentry(one);
+
+}
+if ( val == 2 ) {
+ fnext *fentry(two);
+
+}
+if ( val == 3 ) {
+ fnext main;
+
+}
+};
+
+ one := |*
+ '{' => {fmt.Print( "{ " );fcall *fentry(one);
+};
+ "[" => {fmt.Print( "[ " );fcall *fentry(two);
+};
+ "}" sp* => {fmt.Print( "} " );fret;
+};
+ [a-z]+ => {fmt.Print( "word " );val = 1;
+fgoto *fentry(handle);
+};
+ ' ' => {fmt.Print( "space " );};
+ *|;
+
+ two := |*
+ '{' => {fmt.Print( "{ " );fcall *fentry(one);
+};
+ "[" => {fmt.Print( "[ " );fcall *fentry(two);
+};
+ ']' sp* => {fmt.Print( "] " );fret;
+};
+ [a-z]+ => {fmt.Print( "word " );val = 2;
+fgoto *fentry(handle);
+};
+ ' ' => {fmt.Print( "space " );};
+ *|;
+
+ main := |*
+ '{' => {fmt.Print( "{ " );fcall one;
+};
+ "[" => {fmt.Print( "[ " );fcall two;
+};
+ [a-z]+ => {fmt.Print( "word " );val = 3;
+fgoto handle;
+};
+ [a-z] ' foil' => {fmt.Print( "this is the foil" );};
+ ' ' => {fmt.Print( "space " );};
+ '\n';
+ *|;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= GotoCallRet_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"{a{b[c d]d}c}\n",
+"[a{b[c d]d}c}\n",
+"[a[b]c]d{ef{g{h}i}j}l\n",
+"{{[]}}\n",
+"a b c\n",
+"{a b c}\n",
+"[a b c]\n",
+"{]\n",
+"{{}\n",
+"[[[[[[]]]]]]\n",
+"[[[[[[]]}]]]\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/gotocallret2_java.rl b/test/trans.d/case/gotocallret2_java.rl
new file mode 100644
index 00000000..3022924e
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_java.rl
@@ -0,0 +1,138 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class gotocallret2_java
+{
+char comm ;
+int top ;
+int stack [] = new int[32];
+int
+ ts ;
+int
+ te ;
+int act ;
+int val ;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{System.out.print( "handle " );
+fhold;if ( val == 1 )
+{
+ fnext *fentry(one);
+}
+if ( val == 2 )
+{
+ fnext *fentry(two);
+}
+if ( val == 3 )
+{
+ fnext main;
+}
+};
+
+ one := |*
+ '{' => {System.out.print( "{ " );
+fcall *fentry(one);};
+ "[" => {System.out.print( "[ " );
+fcall *fentry(two);};
+ "}" sp* => {System.out.print( "} " );
+fret;};
+ [a-z]+ => {System.out.print( "word " );
+val = 1;
+fgoto *fentry(handle);};
+ ' ' => {System.out.print( "space " );
+};
+ *|;
+
+ two := |*
+ '{' => {System.out.print( "{ " );
+fcall *fentry(one);};
+ "[" => {System.out.print( "[ " );
+fcall *fentry(two);};
+ ']' sp* => {System.out.print( "] " );
+fret;};
+ [a-z]+ => {System.out.print( "word " );
+val = 2;
+fgoto *fentry(handle);};
+ ' ' => {System.out.print( "space " );
+};
+ *|;
+
+ main := |*
+ '{' => {System.out.print( "{ " );
+fcall one;};
+ "[" => {System.out.print( "[ " );
+fcall two;};
+ [a-z]+ => {System.out.print( "word " );
+val = 3;
+fgoto handle;};
+ [a-z] ' foil' => {System.out.print( "this is the foil" );
+};
+ ' ' => {System.out.print( "space " );
+};
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= GotoCallRet_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"{a{b[c d]d}c}\n",
+"[a{b[c d]d}c}\n",
+"[a[b]c]d{ef{g{h}i}j}l\n",
+"{{[]}}\n",
+"a b c\n",
+"{a b c}\n",
+"[a b c]\n",
+"{]\n",
+"{{}\n",
+"[[[[[[]]]]]]\n",
+"[[[[[[]]}]]]\n",
+};
+
+static final int inplen = 11;
+
+public static void main (String[] args)
+{
+ gotocallret2_java machine = new gotocallret2_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/gotocallret2_julia.rl b/test/trans.d/case/gotocallret2_julia.rl
new file mode 100644
index 00000000..24907e11
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_julia.rl
@@ -0,0 +1,106 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{print( "handle " );
+fhold;if ( val == 1 )
+ fnext *fentry(one);
+end
+if ( val == 2 )
+ fnext *fentry(two);
+end
+if ( val == 3 )
+ fnext main;
+end
+};
+
+ one := |*
+ '{' => {print( "{ " );
+fcall *fentry(one);};
+ "[" => {print( "[ " );
+fcall *fentry(two);};
+ "}" sp* => {print( "} " );
+fret;};
+ [a-z]+ => {print( "word " );
+val = 1;
+fgoto *fentry(handle);};
+ ' ' => {print( "space " );
+};
+ *|;
+
+ two := |*
+ '{' => {print( "{ " );
+fcall *fentry(one);};
+ "[" => {print( "[ " );
+fcall *fentry(two);};
+ ']' sp* => {print( "] " );
+fret;};
+ [a-z]+ => {print( "word " );
+val = 2;
+fgoto *fentry(handle);};
+ ' ' => {print( "space " );
+};
+ *|;
+
+ main := |*
+ '{' => {print( "{ " );
+fcall one;};
+ "[" => {print( "[ " );
+fcall two;};
+ [a-z]+ => {print( "word " );
+val = 3;
+fgoto handle;};
+ [a-z] ' foil' => {print( "this is the foil" );
+};
+ ' ' => {print( "space " );
+};
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+comm = 0;
+top = 0;
+stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+ts = 0;
+te = 0;
+act = 0;
+val = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= GotoCallRet_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "{a{b[c d]d}c}\n" );
+ m( "[a{b[c d]d}c}\n" );
+ m( "[a[b]c]d{ef{g{h}i}j}l\n" );
+ m( "{{[]}}\n" );
+ m( "a b c\n" );
+ m( "{a b c}\n" );
+ m( "[a b c]\n" );
+ m( "{]\n" );
+ m( "{{}\n" );
+ m( "[[[[[[]]]]]]\n" );
+ m( "[[[[[[]]}]]]\n" );
diff --git a/test/trans.d/case/gotocallret2_rust.rl b/test/trans.d/case/gotocallret2_rust.rl
new file mode 100644
index 00000000..4ff56f43
--- /dev/null
+++ b/test/trans.d/case/gotocallret2_rust.rl
@@ -0,0 +1,118 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut comm : u8 = 0;
+static mut top : i32 = 0;
+static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+static mut ts : i32
+ = 0;
+static mut te : i32
+ = 0;
+static mut act : i32 = 0;
+static mut val : i32 = 0;
+
+%%{
+ machine GotoCallRet;
+
+ sp = ' ';
+
+ handle := any @{print!( "{}", "handle " );
+fhold;if ( val == 1 )
+{
+ fnext *fentry(one);
+}
+if ( val == 2 )
+{
+ fnext *fentry(two);
+}
+if ( val == 3 )
+{
+ fnext main;
+}
+};
+
+ one := |*
+ '{' => {print!( "{}", "{ " );
+fcall *fentry(one);};
+ "[" => {print!( "{}", "[ " );
+fcall *fentry(two);};
+ "}" sp* => {print!( "{}", "} " );
+fret;};
+ [a-z]+ => {print!( "{}", "word " );
+val = 1;
+fgoto *fentry(handle);};
+ ' ' => {print!( "{}", "space " );
+};
+ *|;
+
+ two := |*
+ '{' => {print!( "{}", "{ " );
+fcall *fentry(one);};
+ "[" => {print!( "{}", "[ " );
+fcall *fentry(two);};
+ ']' sp* => {print!( "{}", "] " );
+fret;};
+ [a-z]+ => {print!( "{}", "word " );
+val = 2;
+fgoto *fentry(handle);};
+ ' ' => {print!( "{}", "space " );
+};
+ *|;
+
+ main := |*
+ '{' => {print!( "{}", "{ " );
+fcall one;};
+ "[" => {print!( "{}", "[ " );
+fcall two;};
+ [a-z]+ => {print!( "{}", "word " );
+val = 3;
+fgoto handle;};
+ [a-z] ' foil' => {print!( "{}", "this is the foil" );
+};
+ ' ' => {print!( "{}", "space " );
+};
+ '\n';
+ *|;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= GotoCallRet_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "{a{b[c d]d}c}\n".to_string() ); }
+ unsafe { m( "[a{b[c d]d}c}\n".to_string() ); }
+ unsafe { m( "[a[b]c]d{ef{g{h}i}j}l\n".to_string() ); }
+ unsafe { m( "{{[]}}\n".to_string() ); }
+ unsafe { m( "a b c\n".to_string() ); }
+ unsafe { m( "{a b c}\n".to_string() ); }
+ unsafe { m( "[a b c]\n".to_string() ); }
+ unsafe { m( "{]\n".to_string() ); }
+ unsafe { m( "{{}\n".to_string() ); }
+ unsafe { m( "[[[[[[]]]]]]\n".to_string() ); }
+ unsafe { m( "[[[[[[]]}]]]\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/gotocallret3.rl b/test/trans.d/case/gotocallret3.rl
new file mode 100644
index 00000000..d2c5e71a
--- /dev/null
+++ b/test/trans.d/case/gotocallret3.rl
@@ -0,0 +1,121 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ */
+
+/*
+ * Demonstrate the use of goto, call and return. This machine expects either a
+ * lower case char or a digit as a command then a space followed by the command
+ * arg. If the command is a char, then the arg must be an a string of chars.
+ * If the command is a digit, then the arg must be a string of digits. This
+ * choice is determined by action code, rather than though transition
+ * desitinations.
+ */
+
+char comm;
+int top;
+int stack[32];
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction { fentry(garble_line); }
+
+ action err_garbling_line { print_str "error: garbling line\n"; }
+ action goto_main { fnext main; }
+ action recovery_failed { print_str "error: failed to recover\n"; }
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold; fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {
+ if ( comm >= 97 ) {
+ fncall alp_comm;
+ } else {
+ fncall dig_comm;
+ }
+ }
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;} ' ' @comm_arg @{print_str "prints\n";} '\n'
+ ) @{print_str "correct command\n";};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+##### INPUT #####
+"lkajsdf\n"
+"2134\n"
+"(\n"
+"\n"
+"*234234()0909 092 -234aslkf09`1 11\n"
+"1\n"
+"909\n"
+"1 a\n"
+"11 1\n"
+"a 1\n"
+"aa a\n"
+"1 1\n"
+"1 123456\n"
+"a a\n"
+"a abcdef\n"
+"h"
+"a aa1"
+##### OUTPUT #####
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+prints
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+prints
+error: garbling line
+ACCEPT
+error: garbling line
+ACCEPT
+prints
+correct command
+ACCEPT
+prints
+correct command
+ACCEPT
+prints
+correct command
+ACCEPT
+prints
+correct command
+ACCEPT
+FAIL
+prints
+error: garbling line
+error: failed to recover
+FAIL
diff --git a/test/trans.d/case/gotocallret3_asm.rl b/test/trans.d/case/gotocallret3_asm.rl
new file mode 100644
index 00000000..01a11cc0
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_asm.rl
@@ -0,0 +1,292 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm comm,8,8
+ .text
+ .section .data
+ .comm top,8,8
+ .text
+ .section .data
+ .comm stack,8,8
+ .text
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {
+ movq $fentry(garble_line), %rax
+ pushq %rax
+ popq %rax
+
+}
+
+ action err_garbling_line {
+ .section .rodata
+1:
+ .string "error: garbling line\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action goto_main {
+ fnext main;
+
+}
+ action recovery_failed {
+ .section .rodata
+2:
+ .string "error: failed to recover\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {
+ fhold;
+fnret;
+
+}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {
+ movq comm (%rip), %rax
+ pushq %rax
+ movq $97 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ setge %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 3f
+fncall alp_comm;
+
+ jmp 4f
+3:
+fncall dig_comm;
+
+4:
+
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{
+ movsbq (%r12), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, comm (%rip)
+
+} ' ' @comm_arg @{
+ .section .rodata
+5:
+ .string "prints\n"
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+} '\n'
+ ) @{
+ .section .rodata
+6:
+ .string "correct command\n"
+ .text
+ movq $6b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{
+ fhold;
+fnext garble_line;
+
+};
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq gotocallret_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "lkajsdf\n"
+.L_inp_1:
+ .string "2134\n"
+.L_inp_2:
+ .string "(\n"
+.L_inp_3:
+ .string "\n"
+.L_inp_4:
+ .string "*234234()0909 092 -234aslkf09`1 11\n"
+.L_inp_5:
+ .string "1\n"
+.L_inp_6:
+ .string "909\n"
+.L_inp_7:
+ .string "1 a\n"
+.L_inp_8:
+ .string "11 1\n"
+.L_inp_9:
+ .string "a 1\n"
+.L_inp_10:
+ .string "aa a\n"
+.L_inp_11:
+ .string "1 1\n"
+.L_inp_12:
+ .string "1 123456\n"
+.L_inp_13:
+ .string "a a\n"
+.L_inp_14:
+ .string "a abcdef\n"
+.L_inp_15:
+ .string "h"
+.L_inp_16:
+ .string "a aa1"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+ .quad .L_inp_7
+ .quad .L_inp_8
+ .quad .L_inp_9
+ .quad .L_inp_10
+ .quad .L_inp_11
+ .quad .L_inp_12
+ .quad .L_inp_13
+ .quad .L_inp_14
+ .quad .L_inp_15
+ .quad .L_inp_16
+
+ .align 8
+inplen:
+ .quad 17
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/gotocallret3_c.rl b/test/trans.d/case/gotocallret3_c.rl
new file mode 100644
index 00000000..13195f33
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_c.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char comm ;
+int top ;
+int stack [32];
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {printf( "%s", "error: garbling line\n" );
+}
+ action goto_main {fnext main;}
+ action recovery_failed {printf( "%s", "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+{
+ fncall alp_comm;
+}
+else {
+ fncall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{printf( "%s", "prints\n" );
+} '\n'
+ ) @{printf( "%s", "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= gotocallret_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+int inplen = 17;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/gotocallret3_crack.rl b/test/trans.d/case/gotocallret3_crack.rl
new file mode 100644
index 00000000..73164ef8
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_crack.rl
@@ -0,0 +1,108 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+byte comm;
+int top;
+array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {cout.format( "error: garbling line\n" );
+}
+ action goto_main {fnext main;}
+ action recovery_failed {cout.format( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+{
+ fncall alp_comm;
+}
+else {
+ fncall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{cout.format( "prints\n" );
+} '\n'
+ ) @{cout.format( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= gotocallret_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "lkajsdf\n" );
+ m( "2134\n" );
+ m( "(\n" );
+ m( "\n" );
+ m( "*234234()0909 092 -234aslkf09`1 11\n" );
+ m( "1\n" );
+ m( "909\n" );
+ m( "1 a\n" );
+ m( "11 1\n" );
+ m( "a 1\n" );
+ m( "aa a\n" );
+ m( "1 1\n" );
+ m( "1 123456\n" );
+ m( "a a\n" );
+ m( "a abcdef\n" );
+ m( "h" );
+ m( "a aa1" );
+}
+
+main();
diff --git a/test/trans.d/case/gotocallret3_cs.rl b/test/trans.d/case/gotocallret3_cs.rl
new file mode 100644
index 00000000..4b5d34f1
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_cs.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+char comm;
+int top;
+int [] stack = new int [32];
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {Console.Write( "error: garbling line\n" );}
+ action goto_main {fnext main;}
+ action recovery_failed {Console.Write( "error: failed to recover\n" );}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+{
+ fncall alp_comm;
+}
+else {
+ fncall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{Console.Write( "prints\n" );} '\n'
+ ) @{Console.Write( "correct command\n" );};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= gotocallret_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+
+static readonly int inplen = 17;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/gotocallret3_d.rl b/test/trans.d/case/gotocallret3_d.rl
new file mode 100644
index 00000000..eb95f265
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_d.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class gotocallret
+{
+char comm;
+int top;
+int stack[32];
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {printf( "%.*s", "error: garbling line\n" );}
+ action goto_main {fnext main;}
+ action recovery_failed {printf( "%.*s", "error: failed to recover\n" );}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+{
+ fncall alp_comm;
+}
+else {
+ fncall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{printf( "%.*s", "prints\n" );} '\n'
+ ) @{printf( "%.*s", "correct command\n" );};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= gotocallret_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+];
+
+int inplen = 17;
+
+}
+int main()
+{
+ gotocallret m = new gotocallret();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/gotocallret3_go.rl b/test/trans.d/case/gotocallret3_go.rl
new file mode 100644
index 00000000..5c27bfc1
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_go.rl
@@ -0,0 +1,116 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var comm byte ;
+var top int ;
+var stack [32] int ;
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {fmt.Print( "error: garbling line\n" );}
+ action goto_main {fnext main;
+}
+ action recovery_failed {fmt.Print( "error: failed to recover\n" );}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;
+fnret;
+}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 ) {
+ fncall alp_comm;
+
+
+} else {
+ fncall dig_comm;
+
+
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{fmt.Print( "prints\n" );} '\n'
+ ) @{fmt.Print( "correct command\n" );};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;
+fnext garble_line;
+};
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= gotocallret_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/gotocallret3_java.rl b/test/trans.d/case/gotocallret3_java.rl
new file mode 100644
index 00000000..d27e33b8
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_java.rl
@@ -0,0 +1,124 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class gotocallret3_java
+{
+char comm ;
+int top ;
+int stack [] = new int[32];
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {System.out.print( "error: garbling line\n" );
+}
+ action goto_main {fnext main;}
+ action recovery_failed {System.out.print( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+{
+ fncall alp_comm;
+}
+else {
+ fncall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{System.out.print( "prints\n" );
+} '\n'
+ ) @{System.out.print( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= gotocallret_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+};
+
+static final int inplen = 17;
+
+public static void main (String[] args)
+{
+ gotocallret3_java machine = new gotocallret3_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/gotocallret3_julia.rl b/test/trans.d/case/gotocallret3_julia.rl
new file mode 100644
index 00000000..af78871b
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_julia.rl
@@ -0,0 +1,95 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {print( "error: garbling line\n" );
+}
+ action goto_main {fnext main;}
+ action recovery_failed {print( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+ fncall alp_comm;
+else
+ fncall dig_comm;
+end
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{print( "prints\n" );
+} '\n'
+ ) @{print( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+comm = 0;
+top = 0;
+stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= gotocallret_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "lkajsdf\n" );
+ m( "2134\n" );
+ m( "(\n" );
+ m( "\n" );
+ m( "*234234()0909 092 -234aslkf09`1 11\n" );
+ m( "1\n" );
+ m( "909\n" );
+ m( "1 a\n" );
+ m( "11 1\n" );
+ m( "a 1\n" );
+ m( "aa a\n" );
+ m( "1 1\n" );
+ m( "1 123456\n" );
+ m( "a a\n" );
+ m( "a abcdef\n" );
+ m( "h" );
+ m( "a aa1" );
diff --git a/test/trans.d/case/gotocallret3_ocaml.rl b/test/trans.d/case/gotocallret3_ocaml.rl
new file mode 100644
index 00000000..d4d243cc
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_ocaml.rl
@@ -0,0 +1,104 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let comm = ref 0
+let top = ref 0
+let stack = Array.make 32 0
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry( garble_line );
+}
+
+ action err_garbling_line {print_string( "error: garbling line\n" );
+}
+ action goto_main {fnext main; }
+ action recovery_failed {print_string( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold; fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if comm .contents >= 97 then
+begin
+ fncall alp_comm;
+
+end
+else
+begin
+ fncall dig_comm;
+
+end
+;
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm := fc;
+} ' ' @comm_arg @{print_string( "prints\n" );
+} '\n'
+ ) @{print_string( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= gotocallret_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "lkajsdf\n";
+ exec "2134\n";
+ exec "(\n";
+ exec "\n";
+ exec "*234234()0909 092 -234aslkf09`1 11\n";
+ exec "1\n";
+ exec "909\n";
+ exec "1 a\n";
+ exec "11 1\n";
+ exec "a 1\n";
+ exec "aa a\n";
+ exec "1 1\n";
+ exec "1 123456\n";
+ exec "a a\n";
+ exec "a abcdef\n";
+ exec "h";
+ exec "a aa1";
+ ()
+;;
+
diff --git a/test/trans.d/case/gotocallret3_ruby.rl b/test/trans.d/case/gotocallret3_ruby.rl
new file mode 100644
index 00000000..78677d33
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_ruby.rl
@@ -0,0 +1,103 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {print( "error: garbling line\n" );
+}
+ action goto_main {fnext main;}
+ action recovery_failed {print( "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+ fncall alp_comm;
+else
+ fncall dig_comm;
+end
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{print( "prints\n" );
+} '\n'
+ ) @{print( "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+comm = 1
+top = 1
+stack = Array.new
+ %% write init;
+ %% write exec;
+ if cs >= gotocallret_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"lkajsdf\n",
+"2134\n",
+"(\n",
+"\n",
+"*234234()0909 092 -234aslkf09`1 11\n",
+"1\n",
+"909\n",
+"1 a\n",
+"11 1\n",
+"a 1\n",
+"aa a\n",
+"1 1\n",
+"1 123456\n",
+"a a\n",
+"a abcdef\n",
+"h",
+"a aa1",
+]
+
+inplen = 17
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/gotocallret3_rust.rl b/test/trans.d/case/gotocallret3_rust.rl
new file mode 100644
index 00000000..74982028
--- /dev/null
+++ b/test/trans.d/case/gotocallret3_rust.rl
@@ -0,0 +1,104 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut comm : u8 = 0;
+static mut top : i32 = 0;
+static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+
+%%{
+ machine gotocallret;
+
+ # A reference to a state in an unused action caused a segfault in 5.8. */
+ action unusedAction {fentry(garble_line);
+}
+
+ action err_garbling_line {print!( "{}", "error: garbling line\n" );
+}
+ action goto_main {fnext main;}
+ action recovery_failed {print!( "{}", "error: failed to recover\n" );
+}
+
+ # Error machine, consumes to end of
+ # line, then starts the main line over.
+ garble_line := ( (any-'\n')*'\n')
+ >err_garbling_line
+ @goto_main
+ $/recovery_failed;
+
+ action hold_and_return {fhold;fnret;}
+
+ # Look for a string of alphas or of digits,
+ # on anything else, hold the character and return.
+ alp_comm := alpha+ $!hold_and_return;
+ dig_comm := digit+ $!hold_and_return;
+
+ # Choose which to machine to call into based on the command.
+ action comm_arg {if ( comm >= 97 )
+{
+ fncall alp_comm;
+}
+else {
+ fncall dig_comm;
+}
+}
+
+ # Specifies command string. Note that the arg is left out.
+ command = (
+ [a-z0-9] @{comm = fc;
+} ' ' @comm_arg @{print!( "{}", "prints\n" );
+} '\n'
+ ) @{print!( "{}", "correct command\n" );
+};
+
+ # Any number of commands. If there is an
+ # error anywhere, garble the line.
+ main := command* $!{fhold;fnext garble_line;};
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= gotocallret_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "lkajsdf\n".to_string() ); }
+ unsafe { m( "2134\n".to_string() ); }
+ unsafe { m( "(\n".to_string() ); }
+ unsafe { m( "\n".to_string() ); }
+ unsafe { m( "*234234()0909 092 -234aslkf09`1 11\n".to_string() ); }
+ unsafe { m( "1\n".to_string() ); }
+ unsafe { m( "909\n".to_string() ); }
+ unsafe { m( "1 a\n".to_string() ); }
+ unsafe { m( "11 1\n".to_string() ); }
+ unsafe { m( "a 1\n".to_string() ); }
+ unsafe { m( "aa a\n".to_string() ); }
+ unsafe { m( "1 1\n".to_string() ); }
+ unsafe { m( "1 123456\n".to_string() ); }
+ unsafe { m( "a a\n".to_string() ); }
+ unsafe { m( "a abcdef\n".to_string() ); }
+ unsafe { m( "h".to_string() ); }
+ unsafe { m( "a aa1".to_string() ); }
+}
+
diff --git a/test/trans.d/case/ncall1.rl b/test/trans.d/case/ncall1.rl
new file mode 100644
index 00000000..9268ad31
--- /dev/null
+++ b/test/trans.d/case/ncall1.rl
@@ -0,0 +1,38 @@
+/*
+ * @LANG: indep
+ */
+
+int top;
+int stack[32];
+
+int target;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ print_str "one\n";
+ fnret;
+ };
+
+ two := 'two' @{
+ print_str "two\n";
+ fnret;
+ };
+
+ main := (
+ '1' @{ target = fentry(one); fncall *target; }
+ | '2' @{ target = fentry(two); fncall *target; }
+ | '\n'
+ )*;
+}%%
+
+##### INPUT #####
+"1one2two1one\n"
+##### OUTPUT #####
+one
+two
+one
+ACCEPT
diff --git a/test/trans.d/case/ncall1_asm.rl b/test/trans.d/case/ncall1_asm.rl
new file mode 100644
index 00000000..e8b97808
--- /dev/null
+++ b/test/trans.d/case/ncall1_asm.rl
@@ -0,0 +1,180 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm top,8,8
+ .text
+ .section .data
+ .comm stack,8,8
+ .text
+ .section .data
+ .comm target,8,8
+ .text
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ .section .rodata
+1:
+ .string "one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fnret;
+
+
+};
+
+ two := 'two' @{
+ .section .rodata
+2:
+ .string "two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fnret;
+
+
+};
+
+ main := (
+ '1' @{
+ movq $fentry(one), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fncall * %rcx;
+
+}
+ | '2' @{
+ movq $fentry(two), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fncall * %rcx;
+
+}
+ | '\n'
+ )*;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq ncall1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1one2two1one\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/ncall1_c.rl b/test/trans.d/case/ncall1_c.rl
new file mode 100644
index 00000000..142781da
--- /dev/null
+++ b/test/trans.d/case/ncall1_c.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int top ;
+int stack [32];
+int target ;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%s", "one\n" );
+fnret;};
+
+ two := 'two' @{printf( "%s", "two\n" );
+fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= ncall1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1one2two1one\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/ncall1_crack.rl b/test/trans.d/case/ncall1_crack.rl
new file mode 100644
index 00000000..ee79a88a
--- /dev/null
+++ b/test/trans.d/case/ncall1_crack.rl
@@ -0,0 +1,61 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int top;
+array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+int target;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{cout.format( "one\n" );
+fnret;};
+
+ two := 'two' @{cout.format( "two\n" );
+fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= ncall1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1one2two1one\n" );
+}
+
+main();
diff --git a/test/trans.d/case/ncall1_cs.rl b/test/trans.d/case/ncall1_cs.rl
new file mode 100644
index 00000000..91abd9bb
--- /dev/null
+++ b/test/trans.d/case/ncall1_cs.rl
@@ -0,0 +1,79 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int top;
+int [] stack = new int [32];
+int target;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{Console.Write( "one\n" );fnret;};
+
+ two := 'two' @{Console.Write( "two\n" );fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= ncall1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1one2two1one\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/ncall1_d.rl b/test/trans.d/case/ncall1_d.rl
new file mode 100644
index 00000000..29ec074a
--- /dev/null
+++ b/test/trans.d/case/ncall1_d.rl
@@ -0,0 +1,78 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class ncall1
+{
+int top;
+int stack[32];
+int target;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%.*s", "one\n" );fnret;};
+
+ two := 'two' @{printf( "%.*s", "two\n" );fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= ncall1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1one2two1one\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ ncall1 m = new ncall1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/ncall1_go.rl b/test/trans.d/case/ncall1_go.rl
new file mode 100644
index 00000000..565b5d33
--- /dev/null
+++ b/test/trans.d/case/ncall1_go.rl
@@ -0,0 +1,70 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var top int ;
+var stack [32] int ;
+var target int ;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{fmt.Print( "one\n" );fnret;
+
+};
+
+ two := 'two' @{fmt.Print( "two\n" );fnret;
+
+};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;
+}
+ | '2' @{target = fentry(two);
+fncall *target;
+}
+ | '\n'
+ )*;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= ncall1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1one2two1one\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/ncall1_java.rl b/test/trans.d/case/ncall1_java.rl
new file mode 100644
index 00000000..0576f26a
--- /dev/null
+++ b/test/trans.d/case/ncall1_java.rl
@@ -0,0 +1,77 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class ncall1_java
+{
+int top ;
+int stack [] = new int[32];
+int target ;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{System.out.print( "one\n" );
+fnret;};
+
+ two := 'two' @{System.out.print( "two\n" );
+fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= ncall1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1one2two1one\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ ncall1_java machine = new ncall1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/ncall1_julia.rl b/test/trans.d/case/ncall1_julia.rl
new file mode 100644
index 00000000..ec84a20b
--- /dev/null
+++ b/test/trans.d/case/ncall1_julia.rl
@@ -0,0 +1,51 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+fnret;};
+
+ two := 'two' @{print( "two\n" );
+fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+top = 0;
+stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+target = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= ncall1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1one2two1one\n" );
diff --git a/test/trans.d/case/ncall1_ocaml.rl b/test/trans.d/case/ncall1_ocaml.rl
new file mode 100644
index 00000000..a1623c83
--- /dev/null
+++ b/test/trans.d/case/ncall1_ocaml.rl
@@ -0,0 +1,57 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let top = ref 0
+let stack = Array.make 32 0
+let target = ref 0
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{print_string( "one\n" );
+fnret;
+ };
+
+ two := 'two' @{print_string( "two\n" );
+fnret;
+ };
+
+ main := (
+ '1' @{target := fentry( one );
+fncall *target.contents;
+}
+ | '2' @{target := fentry( two );
+fncall *target.contents;
+}
+ | '\n'
+ )*;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= ncall1_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1one2two1one\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/ncall1_ruby.rl b/test/trans.d/case/ncall1_ruby.rl
new file mode 100644
index 00000000..b24f7f10
--- /dev/null
+++ b/test/trans.d/case/ncall1_ruby.rl
@@ -0,0 +1,59 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+fnret;};
+
+ two := 'two' @{print( "two\n" );
+fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+top = 1
+stack = Array.new
+target = 1
+ %% write init;
+ %% write exec;
+ if cs >= ncall1_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1one2two1one\n",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/ncall1_rust.rl b/test/trans.d/case/ncall1_rust.rl
new file mode 100644
index 00000000..77484cb4
--- /dev/null
+++ b/test/trans.d/case/ncall1_rust.rl
@@ -0,0 +1,58 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut top : i32 = 0;
+static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+static mut target : i32 = 0;
+
+%%{
+ machine ncall1;
+
+ unused := 'unused';
+
+ one := 'one' @{print!( "{}", "one\n" );
+fnret;};
+
+ two := 'two' @{print!( "{}", "two\n" );
+fnret;};
+
+ main := (
+ '1' @{target = fentry(one);
+fncall *target;}
+ | '2' @{target = fentry(two);
+fncall *target;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= ncall1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1one2two1one\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/next1.rl b/test/trans.d/case/next1.rl
new file mode 100644
index 00000000..6b53f510
--- /dev/null
+++ b/test/trans.d/case/next1.rl
@@ -0,0 +1,36 @@
+/*
+ * @LANG: indep
+ */
+
+int target;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ print_str "one\n";
+ target = fentry(main);
+ fnext *target;
+ };
+
+ two := 'two' @{
+ print_str "two\n";
+ target = fentry(main);
+ fnext *target;
+ };
+
+ main :=
+ '1' @{ target = fentry(one); fnext *target; }
+ | '2' @{ target = fentry(two); fnext *target; }
+ | '\n';
+}%%
+
+##### INPUT #####
+"1one2two1one\n"
+##### OUTPUT #####
+one
+two
+one
+ACCEPT
diff --git a/test/trans.d/case/next1_asm.rl b/test/trans.d/case/next1_asm.rl
new file mode 100644
index 00000000..3adf0962
--- /dev/null
+++ b/test/trans.d/case/next1_asm.rl
@@ -0,0 +1,187 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm target,8,8
+ .text
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ .section .rodata
+1:
+ .string "one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(main), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ two := 'two' @{
+ .section .rodata
+2:
+ .string "two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(main), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ main :=
+ '1' @{
+ movq $fentry(one), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+}
+ | '2' @{
+ movq $fentry(two), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+}
+ | '\n';
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq next1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1one2two1one\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/next1_c.rl b/test/trans.d/case/next1_c.rl
new file mode 100644
index 00000000..ddfcfa9c
--- /dev/null
+++ b/test/trans.d/case/next1_c.rl
@@ -0,0 +1,75 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int target ;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%s", "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{printf( "%s", "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1one2two1one\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/next1_crack.rl b/test/trans.d/case/next1_crack.rl
new file mode 100644
index 00000000..e79755e9
--- /dev/null
+++ b/test/trans.d/case/next1_crack.rl
@@ -0,0 +1,60 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int target;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{cout.format( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{cout.format( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= next1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1one2two1one\n" );
+}
+
+main();
diff --git a/test/trans.d/case/next1_cs.rl b/test/trans.d/case/next1_cs.rl
new file mode 100644
index 00000000..0d3719d0
--- /dev/null
+++ b/test/trans.d/case/next1_cs.rl
@@ -0,0 +1,78 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int target;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{Console.Write( "one\n" );target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{Console.Write( "two\n" );target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1one2two1one\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/next1_d.rl b/test/trans.d/case/next1_d.rl
new file mode 100644
index 00000000..dda6b675
--- /dev/null
+++ b/test/trans.d/case/next1_d.rl
@@ -0,0 +1,77 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class next1
+{
+int target;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%.*s", "one\n" );target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{printf( "%.*s", "two\n" );target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1one2two1one\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ next1 m = new next1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/next1_go.rl b/test/trans.d/case/next1_go.rl
new file mode 100644
index 00000000..030f8c20
--- /dev/null
+++ b/test/trans.d/case/next1_go.rl
@@ -0,0 +1,69 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var target int ;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{fmt.Print( "one\n" );target = fentry(main);
+fnext *target;
+
+};
+
+ two := 'two' @{fmt.Print( "two\n" );target = fentry(main);
+fnext *target;
+
+};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;
+}
+ | '2' @{target = fentry(two);
+fnext *target;
+}
+ | '\n';
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= next1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1one2two1one\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/next1_java.rl b/test/trans.d/case/next1_java.rl
new file mode 100644
index 00000000..73c2c005
--- /dev/null
+++ b/test/trans.d/case/next1_java.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class next1_java
+{
+int target ;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{System.out.print( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{System.out.print( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1one2two1one\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ next1_java machine = new next1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/next1_julia.rl b/test/trans.d/case/next1_julia.rl
new file mode 100644
index 00000000..6283255a
--- /dev/null
+++ b/test/trans.d/case/next1_julia.rl
@@ -0,0 +1,50 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{print( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+target = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= next1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1one2two1one\n" );
diff --git a/test/trans.d/case/next1_ocaml.rl b/test/trans.d/case/next1_ocaml.rl
new file mode 100644
index 00000000..1e084a3f
--- /dev/null
+++ b/test/trans.d/case/next1_ocaml.rl
@@ -0,0 +1,56 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let target = ref 0
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{print_string( "one\n" );
+target := fentry( main );
+fnext *target.contents;
+};
+
+ two := 'two' @{print_string( "two\n" );
+target := fentry( main );
+fnext *target.contents;
+};
+
+ main :=
+ '1' @{target := fentry( one );
+fnext *target.contents;
+}
+ | '2' @{target := fentry( two );
+fnext *target.contents;
+}
+ | '\n';
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= next1_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1one2two1one\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/next1_ruby.rl b/test/trans.d/case/next1_ruby.rl
new file mode 100644
index 00000000..d9611282
--- /dev/null
+++ b/test/trans.d/case/next1_ruby.rl
@@ -0,0 +1,58 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{print( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+target = 1
+ %% write init;
+ %% write exec;
+ if cs >= next1_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1one2two1one\n",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/next1_rust.rl b/test/trans.d/case/next1_rust.rl
new file mode 100644
index 00000000..85470cae
--- /dev/null
+++ b/test/trans.d/case/next1_rust.rl
@@ -0,0 +1,57 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut target : i32 = 0;
+
+%%{
+ machine next1;
+
+ unused := 'unused';
+
+ one := 'one' @{print!( "{}", "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{print!( "{}", "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ main :=
+ '1' @{target = fentry(one);
+fnext *target;}
+ | '2' @{target = fentry(two);
+fnext *target;}
+ | '\n';
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= next1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1one2two1one\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/next2.rl b/test/trans.d/case/next2.rl
new file mode 100644
index 00000000..9f8ffe2a
--- /dev/null
+++ b/test/trans.d/case/next2.rl
@@ -0,0 +1,64 @@
+/*
+ * @LANG: indep
+ */
+
+int target;
+int last;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ print_str "one\n";
+ target = fentry(main);
+ fnext *target;
+ };
+
+ two := 'two' @{
+ print_str "two\n";
+ target = fentry(main);
+ fnext *target;
+ };
+
+ three := 'three' @{
+ print_str "three\n";
+ target = fentry(main);
+ fnext *target;
+ };
+
+ main := (
+ '1' @{
+ target = fentry(one);
+ fnext *target;
+ last = 1;
+ } |
+
+ '2' @{
+ target = fentry(two);
+ fnext *target;
+ last = 2;
+ } |
+
+ # This one is conditional based on the last.
+ '3' @{
+ if ( last == 2 ) {
+ target = fentry(three);
+ fnext *target;
+ }
+
+ last = 3;
+ } 'x' |
+
+ '\n'
+ )*;
+}%%
+
+##### INPUT #####
+"1one3x2two3three\n"
+##### OUTPUT #####
+one
+two
+three
+ACCEPT
diff --git a/test/trans.d/case/next2_asm.rl b/test/trans.d/case/next2_asm.rl
new file mode 100644
index 00000000..471f9fe1
--- /dev/null
+++ b/test/trans.d/case/next2_asm.rl
@@ -0,0 +1,256 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm target,8,8
+ .text
+ .section .data
+ .comm last,8,8
+ .text
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ .section .rodata
+1:
+ .string "one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(main), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ two := 'two' @{
+ .section .rodata
+2:
+ .string "two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(main), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ three := 'three' @{
+ .section .rodata
+3:
+ .string "three\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq $fentry(main), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ main := (
+ '1' @{
+ movq $fentry(one), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+ movq $1, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, last (%rip)
+
+} |
+
+ '2' @{
+ movq $fentry(two), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+ movq $2, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, last (%rip)
+
+} |
+
+ # This one is conditional based on the last.
+ '3' @{
+ movq last (%rip), %rax
+ pushq %rax
+ movq $2 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 4f
+ movq $fentry(three), %rax
+ pushq %rax
+ popq %rax
+ movq %rax, target (%rip)
+ movq target(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+4:
+ movq $3, %rax
+ pushq %rax
+ popq %rax
+ movq %rax, last (%rip)
+
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq next2_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1one3x2two3three\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/next2_c.rl b/test/trans.d/case/next2_c.rl
new file mode 100644
index 00000000..1251e563
--- /dev/null
+++ b/test/trans.d/case/next2_c.rl
@@ -0,0 +1,94 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int target ;
+int last ;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%s", "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{printf( "%s", "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{printf( "%s", "three\n" );
+target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+{
+ target = fentry(three);
+fnext *target;
+}
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next2_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1one3x2two3three\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/next2_crack.rl b/test/trans.d/case/next2_crack.rl
new file mode 100644
index 00000000..9e90f50f
--- /dev/null
+++ b/test/trans.d/case/next2_crack.rl
@@ -0,0 +1,79 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int target;
+int last;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{cout.format( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{cout.format( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{cout.format( "three\n" );
+target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+{
+ target = fentry(three);
+fnext *target;
+}
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= next2_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1one3x2two3three\n" );
+}
+
+main();
diff --git a/test/trans.d/case/next2_cs.rl b/test/trans.d/case/next2_cs.rl
new file mode 100644
index 00000000..d0cd61d3
--- /dev/null
+++ b/test/trans.d/case/next2_cs.rl
@@ -0,0 +1,96 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int target;
+int last;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{Console.Write( "one\n" );target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{Console.Write( "two\n" );target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{Console.Write( "three\n" );target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+{
+ target = fentry(three);
+fnext *target;
+}
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next2_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1one3x2two3three\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/next2_d.rl b/test/trans.d/case/next2_d.rl
new file mode 100644
index 00000000..146fff5d
--- /dev/null
+++ b/test/trans.d/case/next2_d.rl
@@ -0,0 +1,95 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class next2
+{
+int target;
+int last;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%.*s", "one\n" );target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{printf( "%.*s", "two\n" );target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{printf( "%.*s", "three\n" );target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+{
+ target = fentry(three);
+fnext *target;
+}
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next2_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1one3x2two3three\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ next2 m = new next2();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/next2_go.rl b/test/trans.d/case/next2_go.rl
new file mode 100644
index 00000000..a019ebd4
--- /dev/null
+++ b/test/trans.d/case/next2_go.rl
@@ -0,0 +1,92 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var target int ;
+var last int ;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{fmt.Print( "one\n" );target = fentry(main);
+fnext *target;
+
+};
+
+ two := 'two' @{fmt.Print( "two\n" );target = fentry(main);
+fnext *target;
+
+};
+
+ three := 'three' @{fmt.Print( "three\n" );target = fentry(main);
+fnext *target;
+
+};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;
+
+last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;
+
+last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 ) {
+ target = fentry(three);
+fnext *target;
+
+
+}
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= next2_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1one3x2two3three\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/next2_java.rl b/test/trans.d/case/next2_java.rl
new file mode 100644
index 00000000..3fb7a4f7
--- /dev/null
+++ b/test/trans.d/case/next2_java.rl
@@ -0,0 +1,95 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class next2_java
+{
+int target ;
+int last ;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{System.out.print( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{System.out.print( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{System.out.print( "three\n" );
+target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+{
+ target = fentry(three);
+fnext *target;
+}
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= next2_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1one3x2two3three\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ next2_java machine = new next2_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/next2_julia.rl b/test/trans.d/case/next2_julia.rl
new file mode 100644
index 00000000..43ae242c
--- /dev/null
+++ b/test/trans.d/case/next2_julia.rl
@@ -0,0 +1,68 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{print( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{print( "three\n" );
+target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+ target = fentry(three);
+fnext *target;
+end
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+target = 0;
+last = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= next2_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1one3x2two3three\n" );
diff --git a/test/trans.d/case/next2_ocaml.rl b/test/trans.d/case/next2_ocaml.rl
new file mode 100644
index 00000000..6357296d
--- /dev/null
+++ b/test/trans.d/case/next2_ocaml.rl
@@ -0,0 +1,78 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let target = ref 0
+let last = ref 0
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{print_string( "one\n" );
+target := fentry( main );
+fnext *target.contents;
+};
+
+ two := 'two' @{print_string( "two\n" );
+target := fentry( main );
+fnext *target.contents;
+};
+
+ three := 'three' @{print_string( "three\n" );
+target := fentry( main );
+fnext *target.contents;
+};
+
+ main := (
+ '1' @{target := fentry( one );
+fnext *target.contents;
+last := 1;
+} |
+
+ '2' @{target := fentry( two );
+fnext *target.contents;
+last := 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if last .contents == 2 then
+begin
+ target := fentry( three );
+fnext *target.contents;
+
+end
+;
+last := 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= next2_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1one3x2two3three\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/next2_ruby.rl b/test/trans.d/case/next2_ruby.rl
new file mode 100644
index 00000000..94b8ce98
--- /dev/null
+++ b/test/trans.d/case/next2_ruby.rl
@@ -0,0 +1,76 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{print( "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{print( "three\n" );
+target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+ target = fentry(three);
+fnext *target;
+end
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+target = 1
+last = 1
+ %% write init;
+ %% write exec;
+ if cs >= next2_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1one3x2two3three\n",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/next2_rust.rl b/test/trans.d/case/next2_rust.rl
new file mode 100644
index 00000000..d712cf26
--- /dev/null
+++ b/test/trans.d/case/next2_rust.rl
@@ -0,0 +1,76 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut target : i32 = 0;
+static mut last : i32 = 0;
+
+%%{
+ machine next2;
+
+ unused := 'unused';
+
+ one := 'one' @{print!( "{}", "one\n" );
+target = fentry(main);
+fnext *target;};
+
+ two := 'two' @{print!( "{}", "two\n" );
+target = fentry(main);
+fnext *target;};
+
+ three := 'three' @{print!( "{}", "three\n" );
+target = fentry(main);
+fnext *target;};
+
+ main := (
+ '1' @{target = fentry(one);
+fnext *target;last = 1;
+} |
+
+ '2' @{target = fentry(two);
+fnext *target;last = 2;
+} |
+
+ # This one is conditional based on the last.
+ '3' @{if ( last == 2 )
+{
+ target = fentry(three);
+fnext *target;
+}
+last = 3;
+} 'x' |
+
+ '\n'
+ )*;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= next2_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1one3x2two3three\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/patact.rl b/test/trans.d/case/patact.rl
new file mode 100644
index 00000000..1e16c63a
--- /dev/null
+++ b/test/trans.d/case/patact.rl
@@ -0,0 +1,99 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ */
+
+char comm;
+int top;
+int stack[32];
+ptr ts;
+ptr te;
+int act;
+int value;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => { print_str "word\n"; };
+ [0-9]+ => { print_str "num\n"; };
+ [\n ] => { print_str "space\n"; };
+ *|;
+
+ exec_test := |*
+ [a-z]+ => { print_str "word (w/lbh)\n"; fexec te-1; fgoto other; };
+ [a-z]+ ' foil' => { print_str "word (c/lbh)\n"; };
+ [\n ] => { print_str "space\n"; };
+ '22' => { print_str "num (w/switch)\n"; };
+ [0-9]+ => { print_str "num (w/switch)\n"; fexec te-1; fgoto other;};
+ [0-9]+ ' foil' => {print_str "num (c/switch)\n"; };
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => { print_str "in semi\n"; fgoto main; };
+ *|;
+
+ main := |*
+ [a-z]+ => { print_str "word (w/lbh)\n"; fhold; fgoto other; };
+ [a-z]+ ' foil' => { print_str "word (c/lbh)\n"; };
+ [\n ] => { print_str "space\n"; };
+ '22' => { print_str "num (w/switch)\n"; };
+ [0-9]+ => { print_str "num (w/switch)\n"; fhold; fgoto other;};
+ [0-9]+ ' foil' => {print_str "num (c/switch)\n"; };
+ ';' => { print_str "going to semi\n"; fhold; fgoto semi;};
+ '!' => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+}%%
+
+##### INPUT #####
+"abcd foix\n"
+"abcd\nanother\n"
+"123 foix\n"
+"!abcd foix\n"
+"!abcd\nanother\n"
+"!123 foix\n"
+";"
+##### OUTPUT #####
+word (w/lbh)
+word
+space
+word
+space
+ACCEPT
+word (w/lbh)
+word
+space
+word
+space
+ACCEPT
+num (w/switch)
+num
+space
+word
+space
+ACCEPT
+immdiate
+word (w/lbh)
+word
+space
+word
+space
+ACCEPT
+immdiate
+word (w/lbh)
+word
+space
+word
+space
+ACCEPT
+immdiate
+num (w/switch)
+num
+space
+word
+space
+ACCEPT
+going to semi
+in semi
+ACCEPT
diff --git a/test/trans.d/case/patact_asm.rl b/test/trans.d/case/patact_asm.rl
new file mode 100644
index 00000000..246cca71
--- /dev/null
+++ b/test/trans.d/case/patact_asm.rl
@@ -0,0 +1,426 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm comm,8,8
+ .text
+ .section .data
+ .comm top,8,8
+ .text
+ .section .data
+ .comm stack,8,8
+ .text
+ .section .data
+ .comm ts,8,8
+ .text
+ .section .data
+ .comm te,8,8
+ .text
+ .section .data
+ .comm act,8,8
+ .text
+ .section .data
+ .comm value,8,8
+ .text
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {
+ .section .rodata
+1:
+ .string "word\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ [0-9]+ => {
+ .section .rodata
+2:
+ .string "num\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ [\n ] => {
+ .section .rodata
+3:
+ .string "space\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {
+ .section .rodata
+4:
+ .string "word (w/lbh)\n"
+ .text
+ movq $4b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -24(%rbp), %rax
+ pushq %rax
+ movq $1, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ subq %rcx, %rax
+ pushq %rax
+ popq %rax
+ fexec %rax;
+fgoto other;
+
+};
+ [a-z]+ ' foil' => {
+ .section .rodata
+5:
+ .string "word (c/lbh)\n"
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ [\n ] => {
+ .section .rodata
+6:
+ .string "space\n"
+ .text
+ movq $6b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '22' => {
+ .section .rodata
+7:
+ .string "num (w/switch)\n"
+ .text
+ movq $7b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ [0-9]+ => {
+ .section .rodata
+8:
+ .string "num (w/switch)\n"
+ .text
+ movq $8b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq -24(%rbp), %rax
+ pushq %rax
+ movq $1, %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ subq %rcx, %rax
+ pushq %rax
+ popq %rax
+ fexec %rax;
+fgoto other;
+
+};
+ [0-9]+ ' foil' => {
+ .section .rodata
+9:
+ .string "num (c/switch)\n"
+ .text
+ movq $9b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {
+ .section .rodata
+10:
+ .string "in semi\n"
+ .text
+ movq $10b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fgoto main;
+
+};
+ *|;
+
+ main := |*
+ [a-z]+ => {
+ .section .rodata
+11:
+ .string "word (w/lbh)\n"
+ .text
+ movq $11b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fhold;
+fgoto other;
+
+};
+ [a-z]+ ' foil' => {
+ .section .rodata
+12:
+ .string "word (c/lbh)\n"
+ .text
+ movq $12b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ [\n ] => {
+ .section .rodata
+13:
+ .string "space\n"
+ .text
+ movq $13b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ '22' => {
+ .section .rodata
+14:
+ .string "num (w/switch)\n"
+ .text
+ movq $14b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ [0-9]+ => {
+ .section .rodata
+15:
+ .string "num (w/switch)\n"
+ .text
+ movq $15b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fhold;
+fgoto other;
+
+};
+ [0-9]+ ' foil' => {
+ .section .rodata
+16:
+ .string "num (c/switch)\n"
+ .text
+ movq $16b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ ';' => {
+ .section .rodata
+17:
+ .string "going to semi\n"
+ .text
+ movq $17b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fhold;
+fgoto semi;
+
+};
+ '!' => {
+ .section .rodata
+18:
+ .string "immdiate\n"
+ .text
+ movq $18b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+fgoto exec_test;
+
+};
+ *|;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq patact_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "abcd foix\n"
+.L_inp_1:
+ .string "abcd\nanother\n"
+.L_inp_2:
+ .string "123 foix\n"
+.L_inp_3:
+ .string "!abcd foix\n"
+.L_inp_4:
+ .string "!abcd\nanother\n"
+.L_inp_5:
+ .string "!123 foix\n"
+.L_inp_6:
+ .string ";"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+ .quad .L_inp_5
+ .quad .L_inp_6
+
+ .align 8
+inplen:
+ .quad 7
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/patact_c.rl b/test/trans.d/case/patact_c.rl
new file mode 100644
index 00000000..e3a7df35
--- /dev/null
+++ b/test/trans.d/case/patact_c.rl
@@ -0,0 +1,120 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char comm ;
+int top ;
+int stack [32];
+char * ts ;
+char * te ;
+int act ;
+int value ;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {printf( "%s", "word\n" );
+};
+ [0-9]+ => {printf( "%s", "num\n" );
+};
+ [\n ] => {printf( "%s", "space\n" );
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {printf( "%s", "word (w/lbh)\n" );
+fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {printf( "%s", "word (c/lbh)\n" );
+};
+ [\n ] => {printf( "%s", "space\n" );
+};
+ '22' => {printf( "%s", "num (w/switch)\n" );
+};
+ [0-9]+ => {printf( "%s", "num (w/switch)\n" );
+fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {printf( "%s", "num (c/switch)\n" );
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {printf( "%s", "in semi\n" );
+fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {printf( "%s", "word (w/lbh)\n" );
+fhold;fgoto other;};
+ [a-z]+ ' foil' => {printf( "%s", "word (c/lbh)\n" );
+};
+ [\n ] => {printf( "%s", "space\n" );
+};
+ '22' => {printf( "%s", "num (w/switch)\n" );
+};
+ [0-9]+ => {printf( "%s", "num (w/switch)\n" );
+fhold;fgoto other;};
+ [0-9]+ ' foil' => {printf( "%s", "num (c/switch)\n" );
+};
+ ';' => {printf( "%s", "going to semi\n" );
+fhold;fgoto semi;};
+ '!' => {printf( "%s", "immdiate\n" );
+fgoto exec_test;};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= patact_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"abcd foix\n",
+"abcd\nanother\n",
+"123 foix\n",
+"!abcd foix\n",
+"!abcd\nanother\n",
+"!123 foix\n",
+";",
+};
+
+int inplen = 7;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/patact_crack.rl b/test/trans.d/case/patact_crack.rl
new file mode 100644
index 00000000..f4da2926
--- /dev/null
+++ b/test/trans.d/case/patact_crack.rl
@@ -0,0 +1,107 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+byte comm;
+int top;
+array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+int
+ ts;
+int
+ te;
+int act;
+int value;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {cout.format( "word\n" );
+};
+ [0-9]+ => {cout.format( "num\n" );
+};
+ [\n ] => {cout.format( "space\n" );
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {cout.format( "word (w/lbh)\n" );
+fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {cout.format( "word (c/lbh)\n" );
+};
+ [\n ] => {cout.format( "space\n" );
+};
+ '22' => {cout.format( "num (w/switch)\n" );
+};
+ [0-9]+ => {cout.format( "num (w/switch)\n" );
+fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {cout.format( "num (c/switch)\n" );
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {cout.format( "in semi\n" );
+fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {cout.format( "word (w/lbh)\n" );
+fhold;fgoto other;};
+ [a-z]+ ' foil' => {cout.format( "word (c/lbh)\n" );
+};
+ [\n ] => {cout.format( "space\n" );
+};
+ '22' => {cout.format( "num (w/switch)\n" );
+};
+ [0-9]+ => {cout.format( "num (w/switch)\n" );
+fhold;fgoto other;};
+ [0-9]+ ' foil' => {cout.format( "num (c/switch)\n" );
+};
+ ';' => {cout.format( "going to semi\n" );
+fhold;fgoto semi;};
+ '!' => {cout.format( "immdiate\n" );
+fgoto exec_test;};
+ *|;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= patact_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "abcd foix\n" );
+ m( "abcd\nanother\n" );
+ m( "123 foix\n" );
+ m( "!abcd foix\n" );
+ m( "!abcd\nanother\n" );
+ m( "!123 foix\n" );
+ m( ";" );
+}
+
+main();
diff --git a/test/trans.d/case/patact_cs.rl b/test/trans.d/case/patact_cs.rl
new file mode 100644
index 00000000..da82bac9
--- /dev/null
+++ b/test/trans.d/case/patact_cs.rl
@@ -0,0 +1,106 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+char comm;
+int top;
+int [] stack = new int [32];
+int ts;
+int te;
+int act;
+int value;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {Console.Write( "word\n" );};
+ [0-9]+ => {Console.Write( "num\n" );};
+ [\n ] => {Console.Write( "space\n" );};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {Console.Write( "word (w/lbh)\n" );fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {Console.Write( "word (c/lbh)\n" );};
+ [\n ] => {Console.Write( "space\n" );};
+ '22' => {Console.Write( "num (w/switch)\n" );};
+ [0-9]+ => {Console.Write( "num (w/switch)\n" );fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {Console.Write( "num (c/switch)\n" );};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {Console.Write( "in semi\n" );fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {Console.Write( "word (w/lbh)\n" );fhold;fgoto other;};
+ [a-z]+ ' foil' => {Console.Write( "word (c/lbh)\n" );};
+ [\n ] => {Console.Write( "space\n" );};
+ '22' => {Console.Write( "num (w/switch)\n" );};
+ [0-9]+ => {Console.Write( "num (w/switch)\n" );fhold;fgoto other;};
+ [0-9]+ ' foil' => {Console.Write( "num (c/switch)\n" );};
+ ';' => {Console.Write( "going to semi\n" );fhold;fgoto semi;};
+ '!' => {Console.Write( "immdiate\n" );fgoto exec_test;};
+ *|;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= patact_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"abcd foix\n",
+"abcd\nanother\n",
+"123 foix\n",
+"!abcd foix\n",
+"!abcd\nanother\n",
+"!123 foix\n",
+";",
+};
+
+
+static readonly int inplen = 7;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/patact_d.rl b/test/trans.d/case/patact_d.rl
new file mode 100644
index 00000000..94b65eb2
--- /dev/null
+++ b/test/trans.d/case/patact_d.rl
@@ -0,0 +1,106 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class patact
+{
+char comm;
+int top;
+int stack[32];
+const(char) * ts;
+const(char) * te;
+int act;
+int value;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {printf( "%.*s", "word\n" );};
+ [0-9]+ => {printf( "%.*s", "num\n" );};
+ [\n ] => {printf( "%.*s", "space\n" );};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {printf( "%.*s", "word (w/lbh)\n" );fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {printf( "%.*s", "word (c/lbh)\n" );};
+ [\n ] => {printf( "%.*s", "space\n" );};
+ '22' => {printf( "%.*s", "num (w/switch)\n" );};
+ [0-9]+ => {printf( "%.*s", "num (w/switch)\n" );fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {printf( "%.*s", "num (c/switch)\n" );};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {printf( "%.*s", "in semi\n" );fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {printf( "%.*s", "word (w/lbh)\n" );fhold;fgoto other;};
+ [a-z]+ ' foil' => {printf( "%.*s", "word (c/lbh)\n" );};
+ [\n ] => {printf( "%.*s", "space\n" );};
+ '22' => {printf( "%.*s", "num (w/switch)\n" );};
+ [0-9]+ => {printf( "%.*s", "num (w/switch)\n" );fhold;fgoto other;};
+ [0-9]+ ' foil' => {printf( "%.*s", "num (c/switch)\n" );};
+ ';' => {printf( "%.*s", "going to semi\n" );fhold;fgoto semi;};
+ '!' => {printf( "%.*s", "immdiate\n" );fgoto exec_test;};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= patact_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"abcd foix\n",
+"abcd\nanother\n",
+"123 foix\n",
+"!abcd foix\n",
+"!abcd\nanother\n",
+"!123 foix\n",
+";",
+];
+
+int inplen = 7;
+
+}
+int main()
+{
+ patact m = new patact();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/patact_go.rl b/test/trans.d/case/patact_go.rl
new file mode 100644
index 00000000..2ee97c36
--- /dev/null
+++ b/test/trans.d/case/patact_go.rl
@@ -0,0 +1,104 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var comm byte ;
+var top int ;
+var stack [32] int ;
+var ts int ;
+var te int ;
+var act int ;
+var value int ;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {fmt.Print( "word\n" );};
+ [0-9]+ => {fmt.Print( "num\n" );};
+ [\n ] => {fmt.Print( "space\n" );};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {fmt.Print( "word (w/lbh)\n" );fexec te-1;
+fgoto other;
+};
+ [a-z]+ ' foil' => {fmt.Print( "word (c/lbh)\n" );};
+ [\n ] => {fmt.Print( "space\n" );};
+ '22' => {fmt.Print( "num (w/switch)\n" );};
+ [0-9]+ => {fmt.Print( "num (w/switch)\n" );fexec te-1;
+fgoto other;
+};
+ [0-9]+ ' foil' => {fmt.Print( "num (c/switch)\n" );};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {fmt.Print( "in semi\n" );fgoto main;
+};
+ *|;
+
+ main := |*
+ [a-z]+ => {fmt.Print( "word (w/lbh)\n" );fhold;
+fgoto other;
+};
+ [a-z]+ ' foil' => {fmt.Print( "word (c/lbh)\n" );};
+ [\n ] => {fmt.Print( "space\n" );};
+ '22' => {fmt.Print( "num (w/switch)\n" );};
+ [0-9]+ => {fmt.Print( "num (w/switch)\n" );fhold;
+fgoto other;
+};
+ [0-9]+ ' foil' => {fmt.Print( "num (c/switch)\n" );};
+ ';' => {fmt.Print( "going to semi\n" );fhold;
+fgoto semi;
+};
+ '!' => {fmt.Print( "immdiate\n" );fgoto exec_test;
+};
+ *|;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= patact_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"abcd foix\n",
+"abcd\nanother\n",
+"123 foix\n",
+"!abcd foix\n",
+"!abcd\nanother\n",
+"!123 foix\n",
+";",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/patact_java.rl b/test/trans.d/case/patact_java.rl
new file mode 100644
index 00000000..7ff06d11
--- /dev/null
+++ b/test/trans.d/case/patact_java.rl
@@ -0,0 +1,123 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class patact_java
+{
+char comm ;
+int top ;
+int stack [] = new int[32];
+int
+ ts ;
+int
+ te ;
+int act ;
+int value ;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {System.out.print( "word\n" );
+};
+ [0-9]+ => {System.out.print( "num\n" );
+};
+ [\n ] => {System.out.print( "space\n" );
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {System.out.print( "word (w/lbh)\n" );
+fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {System.out.print( "word (c/lbh)\n" );
+};
+ [\n ] => {System.out.print( "space\n" );
+};
+ '22' => {System.out.print( "num (w/switch)\n" );
+};
+ [0-9]+ => {System.out.print( "num (w/switch)\n" );
+fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {System.out.print( "num (c/switch)\n" );
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {System.out.print( "in semi\n" );
+fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {System.out.print( "word (w/lbh)\n" );
+fhold;fgoto other;};
+ [a-z]+ ' foil' => {System.out.print( "word (c/lbh)\n" );
+};
+ [\n ] => {System.out.print( "space\n" );
+};
+ '22' => {System.out.print( "num (w/switch)\n" );
+};
+ [0-9]+ => {System.out.print( "num (w/switch)\n" );
+fhold;fgoto other;};
+ [0-9]+ ' foil' => {System.out.print( "num (c/switch)\n" );
+};
+ ';' => {System.out.print( "going to semi\n" );
+fhold;fgoto semi;};
+ '!' => {System.out.print( "immdiate\n" );
+fgoto exec_test;};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= patact_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"abcd foix\n",
+"abcd\nanother\n",
+"123 foix\n",
+"!abcd foix\n",
+"!abcd\nanother\n",
+"!123 foix\n",
+";",
+};
+
+static final int inplen = 7;
+
+public static void main (String[] args)
+{
+ patact_java machine = new patact_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/patact_julia.rl b/test/trans.d/case/patact_julia.rl
new file mode 100644
index 00000000..a6f69ee9
--- /dev/null
+++ b/test/trans.d/case/patact_julia.rl
@@ -0,0 +1,94 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {print( "word\n" );
+};
+ [0-9]+ => {print( "num\n" );
+};
+ [\n ] => {print( "space\n" );
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {print( "word (w/lbh)\n" );
+fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {print( "word (c/lbh)\n" );
+};
+ [\n ] => {print( "space\n" );
+};
+ '22' => {print( "num (w/switch)\n" );
+};
+ [0-9]+ => {print( "num (w/switch)\n" );
+fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {print( "num (c/switch)\n" );
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {print( "in semi\n" );
+fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {print( "word (w/lbh)\n" );
+fhold;fgoto other;};
+ [a-z]+ ' foil' => {print( "word (c/lbh)\n" );
+};
+ [\n ] => {print( "space\n" );
+};
+ '22' => {print( "num (w/switch)\n" );
+};
+ [0-9]+ => {print( "num (w/switch)\n" );
+fhold;fgoto other;};
+ [0-9]+ ' foil' => {print( "num (c/switch)\n" );
+};
+ ';' => {print( "going to semi\n" );
+fhold;fgoto semi;};
+ '!' => {print( "immdiate\n" );
+fgoto exec_test;};
+ *|;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+comm = 0;
+top = 0;
+stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+ts = 0;
+te = 0;
+act = 0;
+value = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= patact_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "abcd foix\n" );
+ m( "abcd\nanother\n" );
+ m( "123 foix\n" );
+ m( "!abcd foix\n" );
+ m( "!abcd\nanother\n" );
+ m( "!123 foix\n" );
+ m( ";" );
diff --git a/test/trans.d/case/patact_ocaml.rl b/test/trans.d/case/patact_ocaml.rl
new file mode 100644
index 00000000..1775c8ce
--- /dev/null
+++ b/test/trans.d/case/patact_ocaml.rl
@@ -0,0 +1,97 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let comm = ref 0
+let top = ref 0
+let stack = Array.make 32 0
+let ts = ref 0
+let te = ref 0
+let act = ref 0
+let value = ref 0
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {print_string( "word\n" );
+};
+ [0-9]+ => {print_string( "num\n" );
+};
+ [\n ] => {print_string( "space\n" );
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {print_string( "word (w/lbh)\n" );
+fexec te-1; fgoto other; };
+ [a-z]+ ' foil' => {print_string( "word (c/lbh)\n" );
+};
+ [\n ] => {print_string( "space\n" );
+};
+ '22' => {print_string( "num (w/switch)\n" );
+};
+ [0-9]+ => {print_string( "num (w/switch)\n" );
+fexec te-1; fgoto other;};
+ [0-9]+ ' foil' => {print_string( "num (c/switch)\n" );
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {print_string( "in semi\n" );
+fgoto main; };
+ *|;
+
+ main := |*
+ [a-z]+ => {print_string( "word (w/lbh)\n" );
+fhold; fgoto other; };
+ [a-z]+ ' foil' => {print_string( "word (c/lbh)\n" );
+};
+ [\n ] => {print_string( "space\n" );
+};
+ '22' => {print_string( "num (w/switch)\n" );
+};
+ [0-9]+ => {print_string( "num (w/switch)\n" );
+fhold; fgoto other;};
+ [0-9]+ ' foil' => {print_string( "num (c/switch)\n" );
+};
+ ';' => {print_string( "going to semi\n" );
+fhold; fgoto semi;};
+ '!' => {print_string( "immdiate\n" );
+fgoto exec_test; };
+ *|;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= patact_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "abcd foix\n";
+ exec "abcd\nanother\n";
+ exec "123 foix\n";
+ exec "!abcd foix\n";
+ exec "!abcd\nanother\n";
+ exec "!123 foix\n";
+ exec ";";
+ ()
+;;
+
diff --git a/test/trans.d/case/patact_ruby.rl b/test/trans.d/case/patact_ruby.rl
new file mode 100644
index 00000000..43a535e6
--- /dev/null
+++ b/test/trans.d/case/patact_ruby.rl
@@ -0,0 +1,102 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {print( "word\n" );
+};
+ [0-9]+ => {print( "num\n" );
+};
+ [\n ] => {print( "space\n" );
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {print( "word (w/lbh)\n" );
+fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {print( "word (c/lbh)\n" );
+};
+ [\n ] => {print( "space\n" );
+};
+ '22' => {print( "num (w/switch)\n" );
+};
+ [0-9]+ => {print( "num (w/switch)\n" );
+fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {print( "num (c/switch)\n" );
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {print( "in semi\n" );
+fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {print( "word (w/lbh)\n" );
+fhold;fgoto other;};
+ [a-z]+ ' foil' => {print( "word (c/lbh)\n" );
+};
+ [\n ] => {print( "space\n" );
+};
+ '22' => {print( "num (w/switch)\n" );
+};
+ [0-9]+ => {print( "num (w/switch)\n" );
+fhold;fgoto other;};
+ [0-9]+ ' foil' => {print( "num (c/switch)\n" );
+};
+ ';' => {print( "going to semi\n" );
+fhold;fgoto semi;};
+ '!' => {print( "immdiate\n" );
+fgoto exec_test;};
+ *|;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+comm = 1
+top = 1
+stack = Array.new
+ts = 1
+te = 1
+act = 1
+value = 1
+ %% write init;
+ %% write exec;
+ if cs >= patact_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"abcd foix\n",
+"abcd\nanother\n",
+"123 foix\n",
+"!abcd foix\n",
+"!abcd\nanother\n",
+"!123 foix\n",
+";",
+]
+
+inplen = 7
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/patact_rust.rl b/test/trans.d/case/patact_rust.rl
new file mode 100644
index 00000000..8f660e1f
--- /dev/null
+++ b/test/trans.d/case/patact_rust.rl
@@ -0,0 +1,103 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut comm : u8 = 0;
+static mut top : i32 = 0;
+static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
+static mut ts : i32
+ = 0;
+static mut te : i32
+ = 0;
+static mut act : i32 = 0;
+static mut value : i32 = 0;
+
+%%{
+ machine patact;
+
+ other := |*
+ [a-z]+ => {print!( "{}", "word\n" );
+};
+ [0-9]+ => {print!( "{}", "num\n" );
+};
+ [\n ] => {print!( "{}", "space\n" );
+};
+ *|;
+
+ exec_test := |*
+ [a-z]+ => {print!( "{}", "word (w/lbh)\n" );
+fexec te-1;fgoto other;};
+ [a-z]+ ' foil' => {print!( "{}", "word (c/lbh)\n" );
+};
+ [\n ] => {print!( "{}", "space\n" );
+};
+ '22' => {print!( "{}", "num (w/switch)\n" );
+};
+ [0-9]+ => {print!( "{}", "num (w/switch)\n" );
+fexec te-1;fgoto other;};
+ [0-9]+ ' foil' => {print!( "{}", "num (c/switch)\n" );
+};
+ '!';# => { print_str "immdiate\n"; fgoto exec_test; };
+ *|;
+
+ semi := |*
+ ';' => {print!( "{}", "in semi\n" );
+fgoto main;};
+ *|;
+
+ main := |*
+ [a-z]+ => {print!( "{}", "word (w/lbh)\n" );
+fhold;fgoto other;};
+ [a-z]+ ' foil' => {print!( "{}", "word (c/lbh)\n" );
+};
+ [\n ] => {print!( "{}", "space\n" );
+};
+ '22' => {print!( "{}", "num (w/switch)\n" );
+};
+ [0-9]+ => {print!( "{}", "num (w/switch)\n" );
+fhold;fgoto other;};
+ [0-9]+ ' foil' => {print!( "{}", "num (c/switch)\n" );
+};
+ ';' => {print!( "{}", "going to semi\n" );
+fhold;fgoto semi;};
+ '!' => {print!( "{}", "immdiate\n" );
+fgoto exec_test;};
+ *|;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= patact_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "abcd foix\n".to_string() ); }
+ unsafe { m( "abcd\nanother\n".to_string() ); }
+ unsafe { m( "123 foix\n".to_string() ); }
+ unsafe { m( "!abcd foix\n".to_string() ); }
+ unsafe { m( "!abcd\nanother\n".to_string() ); }
+ unsafe { m( "!123 foix\n".to_string() ); }
+ unsafe { m( ";".to_string() ); }
+}
+
diff --git a/test/trans.d/case/rangei.rl b/test/trans.d/case/rangei.rl
new file mode 100644
index 00000000..1b523556
--- /dev/null
+++ b/test/trans.d/case/rangei.rl
@@ -0,0 +1,28 @@
+/*
+ * @LANG: indep
+ */
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+##### INPUT #####
+"AaBbAa"
+"Aa`bAa"
+"AaB@Aa"
+"AaBbMa"
+"AaBbma"
+##### OUTPUT #####
+ACCEPT
+FAIL
+FAIL
+FAIL
+FAIL
diff --git a/test/trans.d/case/rangei_asm.rl b/test/trans.d/case/rangei_asm.rl
new file mode 100644
index 00000000..6906eb3b
--- /dev/null
+++ b/test/trans.d/case/rangei_asm.rl
@@ -0,0 +1,131 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq rangei_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "AaBbAa"
+.L_inp_1:
+ .string "Aa`bAa"
+.L_inp_2:
+ .string "AaB@Aa"
+.L_inp_3:
+ .string "AaBbMa"
+.L_inp_4:
+ .string "AaBbma"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+ .quad .L_inp_2
+ .quad .L_inp_3
+ .quad .L_inp_4
+
+ .align 8
+inplen:
+ .quad 5
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/rangei_c.rl b/test/trans.d/case/rangei_c.rl
new file mode 100644
index 00000000..da69b0c2
--- /dev/null
+++ b/test/trans.d/case/rangei_c.rl
@@ -0,0 +1,71 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= rangei_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"AaBbAa",
+"Aa`bAa",
+"AaB@Aa",
+"AaBbMa",
+"AaBbma",
+};
+
+int inplen = 5;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/rangei_crack.rl b/test/trans.d/case/rangei_crack.rl
new file mode 100644
index 00000000..7816b6cd
--- /dev/null
+++ b/test/trans.d/case/rangei_crack.rl
@@ -0,0 +1,56 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= rangei_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "AaBbAa" );
+ m( "Aa`bAa" );
+ m( "AaB@Aa" );
+ m( "AaBbMa" );
+ m( "AaBbma" );
+}
+
+main();
diff --git a/test/trans.d/case/rangei_cs.rl b/test/trans.d/case/rangei_cs.rl
new file mode 100644
index 00000000..8b0dbe7e
--- /dev/null
+++ b/test/trans.d/case/rangei_cs.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= rangei_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"AaBbAa",
+"Aa`bAa",
+"AaB@Aa",
+"AaBbMa",
+"AaBbma",
+};
+
+
+static readonly int inplen = 5;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/rangei_d.rl b/test/trans.d/case/rangei_d.rl
new file mode 100644
index 00000000..fde4987c
--- /dev/null
+++ b/test/trans.d/case/rangei_d.rl
@@ -0,0 +1,75 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class rangei
+{
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= rangei_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"AaBbAa",
+"Aa`bAa",
+"AaB@Aa",
+"AaBbMa",
+"AaBbma",
+];
+
+int inplen = 5;
+
+}
+int main()
+{
+ rangei m = new rangei();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/rangei_go.rl b/test/trans.d/case/rangei_go.rl
new file mode 100644
index 00000000..2f17a6f2
--- /dev/null
+++ b/test/trans.d/case/rangei_go.rl
@@ -0,0 +1,61 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= rangei_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"AaBbAa",
+"Aa`bAa",
+"AaB@Aa",
+"AaBbMa",
+"AaBbma",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/rangei_java.rl b/test/trans.d/case/rangei_java.rl
new file mode 100644
index 00000000..e437f259
--- /dev/null
+++ b/test/trans.d/case/rangei_java.rl
@@ -0,0 +1,72 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class rangei_java
+{
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= rangei_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"AaBbAa",
+"Aa`bAa",
+"AaB@Aa",
+"AaBbMa",
+"AaBbma",
+};
+
+static final int inplen = 5;
+
+public static void main (String[] args)
+{
+ rangei_java machine = new rangei_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/rangei_julia.rl b/test/trans.d/case/rangei_julia.rl
new file mode 100644
index 00000000..392950b3
--- /dev/null
+++ b/test/trans.d/case/rangei_julia.rl
@@ -0,0 +1,46 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= rangei_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "AaBbAa" );
+ m( "Aa`bAa" );
+ m( "AaB@Aa" );
+ m( "AaBbMa" );
+ m( "AaBbma" );
diff --git a/test/trans.d/case/rangei_ocaml.rl b/test/trans.d/case/rangei_ocaml.rl
new file mode 100644
index 00000000..dbca2463
--- /dev/null
+++ b/test/trans.d/case/rangei_ocaml.rl
@@ -0,0 +1,48 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= rangei_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "AaBbAa";
+ exec "Aa`bAa";
+ exec "AaB@Aa";
+ exec "AaBbMa";
+ exec "AaBbma";
+ ()
+;;
+
diff --git a/test/trans.d/case/rangei_ruby.rl b/test/trans.d/case/rangei_ruby.rl
new file mode 100644
index 00000000..19db2bd9
--- /dev/null
+++ b/test/trans.d/case/rangei_ruby.rl
@@ -0,0 +1,54 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= rangei_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"AaBbAa",
+"Aa`bAa",
+"AaB@Aa",
+"AaBbMa",
+"AaBbma",
+]
+
+inplen = 5
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/rangei_rust.rl b/test/trans.d/case/rangei_rust.rl
new file mode 100644
index 00000000..40ea2815
--- /dev/null
+++ b/test/trans.d/case/rangei_rust.rl
@@ -0,0 +1,53 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+%%{
+ machine rangei;
+
+ main :=
+ 'a' ../i 'z' .
+ 'A' ../i 'Z' .
+ 60 ../i 93 .
+ 94 ../i 125 .
+ 86 ../i 101 .
+ 60 ../i 125
+ '';
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= rangei_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "AaBbAa".to_string() ); }
+ unsafe { m( "Aa`bAa".to_string() ); }
+ unsafe { m( "AaB@Aa".to_string() ); }
+ unsafe { m( "AaBbMa".to_string() ); }
+ unsafe { m( "AaBbma".to_string() ); }
+}
+
diff --git a/test/trans.d/case/scan1.rl b/test/trans.d/case/scan1.rl
new file mode 100644
index 00000000..2675b601
--- /dev/null
+++ b/test/trans.d/case/scan1.rl
@@ -0,0 +1,70 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ */
+
+ptr ts;
+ptr te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ print_str "on last ";
+ if ( p+1 == te ) {
+ print_str "yes";
+ }
+ print_str "\n";
+ };
+
+ 'b'+ => {
+ print_str "on next ";
+ if ( p+1 == te ) {
+ print_str "yes";
+ }
+ print_str "\n";
+ };
+
+ 'c1' 'dxxx'? => {
+ print_str "on lag ";
+ if ( p+1 == te ) {
+ print_str "yes";
+ }
+ print_str "\n";
+ };
+
+ 'd1' => {
+ print_str "lm switch1 ";
+ if ( p+1 == te ) {
+ print_str "yes";
+ }
+ print_str "\n";
+ };
+ 'd2' => {
+ print_str "lm switch2 ";
+ if ( p+1 == te ) {
+ print_str "yes";
+ }
+ print_str "\n";
+ };
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+##### INPUT #####
+"abbc1d1d2\n"
+##### OUTPUT #####
+on last yes
+on next yes
+on lag yes
+lm switch1 yes
+lm switch2 yes
+ACCEPT
diff --git a/test/trans.d/case/scan1_asm.rl b/test/trans.d/case/scan1_asm.rl
new file mode 100644
index 00000000..999b0c4a
--- /dev/null
+++ b/test/trans.d/case/scan1_asm.rl
@@ -0,0 +1,394 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm ts,8,8
+ .text
+ .section .data
+ .comm te,8,8
+ .text
+ .section .data
+ .comm act,8,8
+ .text
+ .section .data
+ .comm token,8,8
+ .text
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ .section .rodata
+1:
+ .string "on last "
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ pushq %r12
+ movq $1 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ movq -24(%rbp), %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 2f
+ .section .rodata
+4:
+ .string "yes"
+ .text
+ movq $4b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+2:
+ .section .rodata
+5:
+ .string "\n"
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ 'b'+ => {
+ .section .rodata
+6:
+ .string "on next "
+ .text
+ movq $6b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ pushq %r12
+ movq $1 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ movq -24(%rbp), %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 7f
+ .section .rodata
+9:
+ .string "yes"
+ .text
+ movq $9b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+7:
+ .section .rodata
+10:
+ .string "\n"
+ .text
+ movq $10b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ 'c1' 'dxxx'? => {
+ .section .rodata
+11:
+ .string "on lag "
+ .text
+ movq $11b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ pushq %r12
+ movq $1 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ movq -24(%rbp), %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 12f
+ .section .rodata
+14:
+ .string "yes"
+ .text
+ movq $14b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+12:
+ .section .rodata
+15:
+ .string "\n"
+ .text
+ movq $15b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ 'd1' => {
+ .section .rodata
+16:
+ .string "lm switch1 "
+ .text
+ movq $16b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ pushq %r12
+ movq $1 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ movq -24(%rbp), %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 17f
+ .section .rodata
+19:
+ .string "yes"
+ .text
+ movq $19b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+17:
+ .section .rodata
+20:
+ .string "\n"
+ .text
+ movq $20b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ 'd2' => {
+ .section .rodata
+21:
+ .string "lm switch2 "
+ .text
+ movq $21b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ pushq %r12
+ movq $1 , %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ addq %rcx, %rax
+ pushq %rax
+ movq -24(%rbp), %rax
+ pushq %rax
+ popq %rcx
+ popq %rax
+ cmp %rcx, %rax
+ sete %al
+ movsbq %al, %rax
+ pushq %rax
+ popq %rax
+ test %rax, %rax
+ jz 22f
+ .section .rodata
+24:
+ .string "yes"
+ .text
+ movq $24b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+22:
+ .section .rodata
+25:
+ .string "\n"
+ .text
+ movq $25b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq scanner_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "abbc1d1d2\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/scan1_c.rl b/test/trans.d/case/scan1_c.rl
new file mode 100644
index 00000000..5ecbf243
--- /dev/null
+++ b/test/trans.d/case/scan1_c.rl
@@ -0,0 +1,114 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char * ts ;
+char * te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%s", "on last " );
+if ( p + 1 == te )
+{
+ printf( "%s", "yes" );
+
+}
+printf( "%s", "\n" );
+};
+
+ 'b'+ => {printf( "%s", "on next " );
+if ( p + 1 == te )
+{
+ printf( "%s", "yes" );
+
+}
+printf( "%s", "\n" );
+};
+
+ 'c1' 'dxxx'? => {printf( "%s", "on lag " );
+if ( p + 1 == te )
+{
+ printf( "%s", "yes" );
+
+}
+printf( "%s", "\n" );
+};
+
+ 'd1' => {printf( "%s", "lm switch1 " );
+if ( p + 1 == te )
+{
+ printf( "%s", "yes" );
+
+}
+printf( "%s", "\n" );
+};
+ 'd2' => {printf( "%s", "lm switch2 " );
+if ( p + 1 == te )
+{
+ printf( "%s", "yes" );
+
+}
+printf( "%s", "\n" );
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"abbc1d1d2\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan1_crack.rl b/test/trans.d/case/scan1_crack.rl
new file mode 100644
index 00000000..c2d9de1a
--- /dev/null
+++ b/test/trans.d/case/scan1_crack.rl
@@ -0,0 +1,101 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int
+ ts;
+int
+ te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {cout.format( "on last " );
+if ( p + 1 == te )
+{
+ cout.format( "yes" );
+
+}
+cout.format( "\n" );
+};
+
+ 'b'+ => {cout.format( "on next " );
+if ( p + 1 == te )
+{
+ cout.format( "yes" );
+
+}
+cout.format( "\n" );
+};
+
+ 'c1' 'dxxx'? => {cout.format( "on lag " );
+if ( p + 1 == te )
+{
+ cout.format( "yes" );
+
+}
+cout.format( "\n" );
+};
+
+ 'd1' => {cout.format( "lm switch1 " );
+if ( p + 1 == te )
+{
+ cout.format( "yes" );
+
+}
+cout.format( "\n" );
+};
+ 'd2' => {cout.format( "lm switch2 " );
+if ( p + 1 == te )
+{
+ cout.format( "yes" );
+
+}
+cout.format( "\n" );
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "abbc1d1d2\n" );
+}
+
+main();
diff --git a/test/trans.d/case/scan1_cs.rl b/test/trans.d/case/scan1_cs.rl
new file mode 100644
index 00000000..7f5a98f6
--- /dev/null
+++ b/test/trans.d/case/scan1_cs.rl
@@ -0,0 +1,103 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int ts;
+int te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {Console.Write( "on last " );if ( p + 1 == te )
+{
+ Console.Write( "yes" );
+}
+Console.Write( "\n" );};
+
+ 'b'+ => {Console.Write( "on next " );if ( p + 1 == te )
+{
+ Console.Write( "yes" );
+}
+Console.Write( "\n" );};
+
+ 'c1' 'dxxx'? => {Console.Write( "on lag " );if ( p + 1 == te )
+{
+ Console.Write( "yes" );
+}
+Console.Write( "\n" );};
+
+ 'd1' => {Console.Write( "lm switch1 " );if ( p + 1 == te )
+{
+ Console.Write( "yes" );
+}
+Console.Write( "\n" );};
+ 'd2' => {Console.Write( "lm switch2 " );if ( p + 1 == te )
+{
+ Console.Write( "yes" );
+}
+Console.Write( "\n" );};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"abbc1d1d2\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/scan1_d.rl b/test/trans.d/case/scan1_d.rl
new file mode 100644
index 00000000..adbcb66d
--- /dev/null
+++ b/test/trans.d/case/scan1_d.rl
@@ -0,0 +1,103 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class scanner
+{
+const(char) * ts;
+const(char) * te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%.*s", "on last " );if ( p + 1 == te )
+{
+ printf( "%.*s", "yes" );
+}
+printf( "%.*s", "\n" );};
+
+ 'b'+ => {printf( "%.*s", "on next " );if ( p + 1 == te )
+{
+ printf( "%.*s", "yes" );
+}
+printf( "%.*s", "\n" );};
+
+ 'c1' 'dxxx'? => {printf( "%.*s", "on lag " );if ( p + 1 == te )
+{
+ printf( "%.*s", "yes" );
+}
+printf( "%.*s", "\n" );};
+
+ 'd1' => {printf( "%.*s", "lm switch1 " );if ( p + 1 == te )
+{
+ printf( "%.*s", "yes" );
+}
+printf( "%.*s", "\n" );};
+ 'd2' => {printf( "%.*s", "lm switch2 " );if ( p + 1 == te )
+{
+ printf( "%.*s", "yes" );
+}
+printf( "%.*s", "\n" );};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"abbc1d1d2\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ scanner m = new scanner();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan1_go.rl b/test/trans.d/case/scan1_go.rl
new file mode 100644
index 00000000..66ca5f0c
--- /dev/null
+++ b/test/trans.d/case/scan1_go.rl
@@ -0,0 +1,84 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var ts int ;
+var te int ;
+var act int ;
+var token int ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {fmt.Print( "on last " );if ( p + 1 == te ) {
+ fmt.Print( "yes" );
+}
+fmt.Print( "\n" );};
+
+ 'b'+ => {fmt.Print( "on next " );if ( p + 1 == te ) {
+ fmt.Print( "yes" );
+}
+fmt.Print( "\n" );};
+
+ 'c1' 'dxxx'? => {fmt.Print( "on lag " );if ( p + 1 == te ) {
+ fmt.Print( "yes" );
+}
+fmt.Print( "\n" );};
+
+ 'd1' => {fmt.Print( "lm switch1 " );if ( p + 1 == te ) {
+ fmt.Print( "yes" );
+}
+fmt.Print( "\n" );};
+ 'd2' => {fmt.Print( "lm switch2 " );if ( p + 1 == te ) {
+ fmt.Print( "yes" );
+}
+fmt.Print( "\n" );};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= scanner_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"abbc1d1d2\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/scan1_java.rl b/test/trans.d/case/scan1_java.rl
new file mode 100644
index 00000000..93562703
--- /dev/null
+++ b/test/trans.d/case/scan1_java.rl
@@ -0,0 +1,117 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class scan1_java
+{
+int
+ ts ;
+int
+ te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {System.out.print( "on last " );
+if ( p + 1 == te )
+{
+ System.out.print( "yes" );
+
+}
+System.out.print( "\n" );
+};
+
+ 'b'+ => {System.out.print( "on next " );
+if ( p + 1 == te )
+{
+ System.out.print( "yes" );
+
+}
+System.out.print( "\n" );
+};
+
+ 'c1' 'dxxx'? => {System.out.print( "on lag " );
+if ( p + 1 == te )
+{
+ System.out.print( "yes" );
+
+}
+System.out.print( "\n" );
+};
+
+ 'd1' => {System.out.print( "lm switch1 " );
+if ( p + 1 == te )
+{
+ System.out.print( "yes" );
+
+}
+System.out.print( "\n" );
+};
+ 'd2' => {System.out.print( "lm switch2 " );
+if ( p + 1 == te )
+{
+ System.out.print( "yes" );
+
+}
+System.out.print( "\n" );
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"abbc1d1d2\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ scan1_java machine = new scan1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/scan1_julia.rl b/test/trans.d/case/scan1_julia.rl
new file mode 100644
index 00000000..537e22c3
--- /dev/null
+++ b/test/trans.d/case/scan1_julia.rl
@@ -0,0 +1,83 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "on last " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ 'b'+ => {print( "on next " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ 'c1' 'dxxx'? => {print( "on lag " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ 'd1' => {print( "lm switch1 " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+ 'd2' => {print( "lm switch2 " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+ts = 0;
+te = 0;
+act = 0;
+token = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "abbc1d1d2\n" );
diff --git a/test/trans.d/case/scan1_ocaml.rl b/test/trans.d/case/scan1_ocaml.rl
new file mode 100644
index 00000000..d3a156e6
--- /dev/null
+++ b/test/trans.d/case/scan1_ocaml.rl
@@ -0,0 +1,96 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let ts = ref 0
+let te = ref 0
+let act = ref 0
+let token = ref 0
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print_string( "on last " );
+if p.contents + 1 == te .contents then
+begin
+ print_string( "yes" );
+
+end
+;
+print_string( "\n" );
+};
+
+ 'b'+ => {print_string( "on next " );
+if p.contents + 1 == te .contents then
+begin
+ print_string( "yes" );
+
+end
+;
+print_string( "\n" );
+};
+
+ 'c1' 'dxxx'? => {print_string( "on lag " );
+if p.contents + 1 == te .contents then
+begin
+ print_string( "yes" );
+
+end
+;
+print_string( "\n" );
+};
+
+ 'd1' => {print_string( "lm switch1 " );
+if p.contents + 1 == te .contents then
+begin
+ print_string( "yes" );
+
+end
+;
+print_string( "\n" );
+};
+ 'd2' => {print_string( "lm switch2 " );
+if p.contents + 1 == te .contents then
+begin
+ print_string( "yes" );
+
+end
+;
+print_string( "\n" );
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= scanner_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "abbc1d1d2\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/scan1_ruby.rl b/test/trans.d/case/scan1_ruby.rl
new file mode 100644
index 00000000..3c983fe5
--- /dev/null
+++ b/test/trans.d/case/scan1_ruby.rl
@@ -0,0 +1,91 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "on last " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ 'b'+ => {print( "on next " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ 'c1' 'dxxx'? => {print( "on lag " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ 'd1' => {print( "lm switch1 " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+ 'd2' => {print( "lm switch2 " );
+if ( p + 1 == te )
+ print( "yes" );
+
+end
+print( "\n" );
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ts = 1
+te = 1
+act = 1
+token = 1
+ %% write init;
+ %% write exec;
+ if cs >= scanner_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"abbc1d1d2\n",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/scan1_rust.rl b/test/trans.d/case/scan1_rust.rl
new file mode 100644
index 00000000..aa67bcd5
--- /dev/null
+++ b/test/trans.d/case/scan1_rust.rl
@@ -0,0 +1,97 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut ts : i32
+ = 0;
+static mut te : i32
+ = 0;
+static mut act : i32 = 0;
+static mut token : i32 = 0;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print!( "{}", "on last " );
+if ( p + 1 == te )
+{
+ print!( "{}", "yes" );
+
+}
+print!( "{}", "\n" );
+};
+
+ 'b'+ => {print!( "{}", "on next " );
+if ( p + 1 == te )
+{
+ print!( "{}", "yes" );
+
+}
+print!( "{}", "\n" );
+};
+
+ 'c1' 'dxxx'? => {print!( "{}", "on lag " );
+if ( p + 1 == te )
+{
+ print!( "{}", "yes" );
+
+}
+print!( "{}", "\n" );
+};
+
+ 'd1' => {print!( "{}", "lm switch1 " );
+if ( p + 1 == te )
+{
+ print!( "{}", "yes" );
+
+}
+print!( "{}", "\n" );
+};
+ 'd2' => {print!( "{}", "lm switch2 " );
+if ( p + 1 == te )
+{
+ print!( "{}", "yes" );
+
+}
+print!( "{}", "\n" );
+};
+
+ [d0-9]+ '.';
+
+ '\n';
+ *|;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "abbc1d1d2\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/scan2.rl b/test/trans.d/case/scan2.rl
new file mode 100644
index 00000000..167b2c8c
--- /dev/null
+++ b/test/trans.d/case/scan2.rl
@@ -0,0 +1,34 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ */
+ptr ts;
+ptr te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ print_str "pat1\n";
+ };
+
+ [ab]+ . 'c' => {
+ print_str "pat2\n";
+ };
+
+ any => {
+ print_str "any\n";
+ };
+ *|;
+}%%
+
+##### INPUT #####
+"a"
+##### OUTPUT #####
+pat1
+ACCEPT
diff --git a/test/trans.d/case/scan2_asm.rl b/test/trans.d/case/scan2_asm.rl
new file mode 100644
index 00000000..72500c64
--- /dev/null
+++ b/test/trans.d/case/scan2_asm.rl
@@ -0,0 +1,168 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm ts,8,8
+ .text
+ .section .data
+ .comm te,8,8
+ .text
+ .section .data
+ .comm act,8,8
+ .text
+ .section .data
+ .comm token,8,8
+ .text
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ .section .rodata
+1:
+ .string "pat1\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ [ab]+ . 'c' => {
+ .section .rodata
+2:
+ .string "pat2\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ any => {
+ .section .rodata
+3:
+ .string "any\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ *|;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq scanner_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "a"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/scan2_c.rl b/test/trans.d/case/scan2_c.rl
new file mode 100644
index 00000000..61638e8f
--- /dev/null
+++ b/test/trans.d/case/scan2_c.rl
@@ -0,0 +1,75 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char * ts ;
+char * te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%s", "pat1\n" );
+};
+
+ [ab]+ . 'c' => {printf( "%s", "pat2\n" );
+};
+
+ any => {printf( "%s", "any\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"a",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan2_crack.rl b/test/trans.d/case/scan2_crack.rl
new file mode 100644
index 00000000..dcc88144
--- /dev/null
+++ b/test/trans.d/case/scan2_crack.rl
@@ -0,0 +1,62 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int
+ ts;
+int
+ te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {cout.format( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {cout.format( "pat2\n" );
+};
+
+ any => {cout.format( "any\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "a" );
+}
+
+main();
diff --git a/test/trans.d/case/scan2_cs.rl b/test/trans.d/case/scan2_cs.rl
new file mode 100644
index 00000000..b49e6ef2
--- /dev/null
+++ b/test/trans.d/case/scan2_cs.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int ts;
+int te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {Console.Write( "pat1\n" );};
+
+ [ab]+ . 'c' => {Console.Write( "pat2\n" );};
+
+ any => {Console.Write( "any\n" );};
+ *|;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"a",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/scan2_d.rl b/test/trans.d/case/scan2_d.rl
new file mode 100644
index 00000000..79a6eda5
--- /dev/null
+++ b/test/trans.d/case/scan2_d.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class scanner
+{
+const(char) * ts;
+const(char) * te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%.*s", "pat1\n" );};
+
+ [ab]+ . 'c' => {printf( "%.*s", "pat2\n" );};
+
+ any => {printf( "%.*s", "any\n" );};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"a",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ scanner m = new scanner();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan2_go.rl b/test/trans.d/case/scan2_go.rl
new file mode 100644
index 00000000..d52c4e39
--- /dev/null
+++ b/test/trans.d/case/scan2_go.rl
@@ -0,0 +1,62 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var ts int ;
+var te int ;
+var act int ;
+var token int ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {fmt.Print( "pat1\n" );};
+
+ [ab]+ . 'c' => {fmt.Print( "pat2\n" );};
+
+ any => {fmt.Print( "any\n" );};
+ *|;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= scanner_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"a",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/scan2_java.rl b/test/trans.d/case/scan2_java.rl
new file mode 100644
index 00000000..eb07ac70
--- /dev/null
+++ b/test/trans.d/case/scan2_java.rl
@@ -0,0 +1,78 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class scan2_java
+{
+int
+ ts ;
+int
+ te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {System.out.print( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {System.out.print( "pat2\n" );
+};
+
+ any => {System.out.print( "any\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"a",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ scan2_java machine = new scan2_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/scan2_julia.rl b/test/trans.d/case/scan2_julia.rl
new file mode 100644
index 00000000..2d0c095e
--- /dev/null
+++ b/test/trans.d/case/scan2_julia.rl
@@ -0,0 +1,49 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print( "pat2\n" );
+};
+
+ any => {print( "any\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+ts = 0;
+te = 0;
+act = 0;
+token = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "a" );
diff --git a/test/trans.d/case/scan2_ocaml.rl b/test/trans.d/case/scan2_ocaml.rl
new file mode 100644
index 00000000..c43e5547
--- /dev/null
+++ b/test/trans.d/case/scan2_ocaml.rl
@@ -0,0 +1,52 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let ts = ref 0
+let te = ref 0
+let act = ref 0
+let token = ref 0
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print_string( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print_string( "pat2\n" );
+};
+
+ any => {print_string( "any\n" );
+};
+ *|;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= scanner_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "a";
+ ()
+;;
+
diff --git a/test/trans.d/case/scan2_ruby.rl b/test/trans.d/case/scan2_ruby.rl
new file mode 100644
index 00000000..ba082b3f
--- /dev/null
+++ b/test/trans.d/case/scan2_ruby.rl
@@ -0,0 +1,57 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print( "pat2\n" );
+};
+
+ any => {print( "any\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ts = 1
+te = 1
+act = 1
+token = 1
+ %% write init;
+ %% write exec;
+ if cs >= scanner_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"a",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/scan2_rust.rl b/test/trans.d/case/scan2_rust.rl
new file mode 100644
index 00000000..c0ef13ae
--- /dev/null
+++ b/test/trans.d/case/scan2_rust.rl
@@ -0,0 +1,58 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut ts : i32
+ = 0;
+static mut te : i32
+ = 0;
+static mut act : i32 = 0;
+static mut token : i32 = 0;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print!( "{}", "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print!( "{}", "pat2\n" );
+};
+
+ any => {print!( "{}", "any\n" );
+};
+ *|;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "a".to_string() ); }
+}
+
diff --git a/test/trans.d/case/scan3.rl b/test/trans.d/case/scan3.rl
new file mode 100644
index 00000000..80ab4815
--- /dev/null
+++ b/test/trans.d/case/scan3.rl
@@ -0,0 +1,33 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ */
+
+ptr ts;
+ptr te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ print_str "pat1\n";
+ };
+ 'b' => {
+ print_str "pat2\n";
+ };
+ [ab] any* => {
+ print_str "pat3\n";
+ };
+ *|;
+}%%
+
+##### INPUT #####
+"ab89"
+##### OUTPUT #####
+pat3
+ACCEPT
diff --git a/test/trans.d/case/scan3_asm.rl b/test/trans.d/case/scan3_asm.rl
new file mode 100644
index 00000000..0f95a1e3
--- /dev/null
+++ b/test/trans.d/case/scan3_asm.rl
@@ -0,0 +1,166 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm ts,8,8
+ .text
+ .section .data
+ .comm te,8,8
+ .text
+ .section .data
+ .comm act,8,8
+ .text
+ .section .data
+ .comm token,8,8
+ .text
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ .section .rodata
+1:
+ .string "pat1\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ 'b' => {
+ .section .rodata
+2:
+ .string "pat2\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ [ab] any* => {
+ .section .rodata
+3:
+ .string "pat3\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+ *|;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq scanner_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "ab89"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/scan3_c.rl b/test/trans.d/case/scan3_c.rl
new file mode 100644
index 00000000..ccd0fcea
--- /dev/null
+++ b/test/trans.d/case/scan3_c.rl
@@ -0,0 +1,73 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char * ts ;
+char * te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%s", "pat1\n" );
+};
+ 'b' => {printf( "%s", "pat2\n" );
+};
+ [ab] any* => {printf( "%s", "pat3\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"ab89",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan3_crack.rl b/test/trans.d/case/scan3_crack.rl
new file mode 100644
index 00000000..8fbc734e
--- /dev/null
+++ b/test/trans.d/case/scan3_crack.rl
@@ -0,0 +1,60 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int
+ ts;
+int
+ te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {cout.format( "pat1\n" );
+};
+ 'b' => {cout.format( "pat2\n" );
+};
+ [ab] any* => {cout.format( "pat3\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "ab89" );
+}
+
+main();
diff --git a/test/trans.d/case/scan3_cs.rl b/test/trans.d/case/scan3_cs.rl
new file mode 100644
index 00000000..0a802b65
--- /dev/null
+++ b/test/trans.d/case/scan3_cs.rl
@@ -0,0 +1,74 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int ts;
+int te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {Console.Write( "pat1\n" );};
+ 'b' => {Console.Write( "pat2\n" );};
+ [ab] any* => {Console.Write( "pat3\n" );};
+ *|;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"ab89",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/scan3_d.rl b/test/trans.d/case/scan3_d.rl
new file mode 100644
index 00000000..334d9291
--- /dev/null
+++ b/test/trans.d/case/scan3_d.rl
@@ -0,0 +1,74 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class scanner
+{
+const(char) * ts;
+const(char) * te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%.*s", "pat1\n" );};
+ 'b' => {printf( "%.*s", "pat2\n" );};
+ [ab] any* => {printf( "%.*s", "pat3\n" );};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"ab89",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ scanner m = new scanner();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan3_go.rl b/test/trans.d/case/scan3_go.rl
new file mode 100644
index 00000000..4bc7363f
--- /dev/null
+++ b/test/trans.d/case/scan3_go.rl
@@ -0,0 +1,60 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var ts int ;
+var te int ;
+var act int ;
+var token int ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {fmt.Print( "pat1\n" );};
+ 'b' => {fmt.Print( "pat2\n" );};
+ [ab] any* => {fmt.Print( "pat3\n" );};
+ *|;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= scanner_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"ab89",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/scan3_java.rl b/test/trans.d/case/scan3_java.rl
new file mode 100644
index 00000000..b4caad5d
--- /dev/null
+++ b/test/trans.d/case/scan3_java.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class scan3_java
+{
+int
+ ts ;
+int
+ te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {System.out.print( "pat1\n" );
+};
+ 'b' => {System.out.print( "pat2\n" );
+};
+ [ab] any* => {System.out.print( "pat3\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"ab89",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ scan3_java machine = new scan3_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/scan3_julia.rl b/test/trans.d/case/scan3_julia.rl
new file mode 100644
index 00000000..c79e3c42
--- /dev/null
+++ b/test/trans.d/case/scan3_julia.rl
@@ -0,0 +1,47 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "pat1\n" );
+};
+ 'b' => {print( "pat2\n" );
+};
+ [ab] any* => {print( "pat3\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+ts = 0;
+te = 0;
+act = 0;
+token = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "ab89" );
diff --git a/test/trans.d/case/scan3_ocaml.rl b/test/trans.d/case/scan3_ocaml.rl
new file mode 100644
index 00000000..fb783612
--- /dev/null
+++ b/test/trans.d/case/scan3_ocaml.rl
@@ -0,0 +1,50 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let ts = ref 0
+let te = ref 0
+let act = ref 0
+let token = ref 0
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print_string( "pat1\n" );
+};
+ 'b' => {print_string( "pat2\n" );
+};
+ [ab] any* => {print_string( "pat3\n" );
+};
+ *|;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= scanner_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "ab89";
+ ()
+;;
+
diff --git a/test/trans.d/case/scan3_ruby.rl b/test/trans.d/case/scan3_ruby.rl
new file mode 100644
index 00000000..dc104d8f
--- /dev/null
+++ b/test/trans.d/case/scan3_ruby.rl
@@ -0,0 +1,55 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "pat1\n" );
+};
+ 'b' => {print( "pat2\n" );
+};
+ [ab] any* => {print( "pat3\n" );
+};
+ *|;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ts = 1
+te = 1
+act = 1
+token = 1
+ %% write init;
+ %% write exec;
+ if cs >= scanner_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"ab89",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/scan3_rust.rl b/test/trans.d/case/scan3_rust.rl
new file mode 100644
index 00000000..f8644ad1
--- /dev/null
+++ b/test/trans.d/case/scan3_rust.rl
@@ -0,0 +1,56 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut ts : i32
+ = 0;
+static mut te : i32
+ = 0;
+static mut act : i32 = 0;
+static mut token : i32 = 0;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print!( "{}", "pat1\n" );
+};
+ 'b' => {print!( "{}", "pat2\n" );
+};
+ [ab] any* => {print!( "{}", "pat3\n" );
+};
+ *|;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "ab89".to_string() ); }
+}
+
diff --git a/test/trans.d/case/scan4.rl b/test/trans.d/case/scan4.rl
new file mode 100644
index 00000000..44f24b16
--- /dev/null
+++ b/test/trans.d/case/scan4.rl
@@ -0,0 +1,34 @@
+/*
+ * @LANG: indep
+ * @NEEDS_EOF: yes
+ */
+
+ptr ts;
+ptr te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ print_str "pat1\n";
+ };
+
+ [ab]+ . 'c' => {
+ print_str "pat2\n";
+ };
+
+ any;
+ *|;
+}%%
+
+##### INPUT #####
+"ba a"
+##### OUTPUT #####
+pat1
+pat1
+ACCEPT
diff --git a/test/trans.d/case/scan4_asm.rl b/test/trans.d/case/scan4_asm.rl
new file mode 100644
index 00000000..fe31624e
--- /dev/null
+++ b/test/trans.d/case/scan4_asm.rl
@@ -0,0 +1,156 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm ts,8,8
+ .text
+ .section .data
+ .comm te,8,8
+ .text
+ .section .data
+ .comm act,8,8
+ .text
+ .section .data
+ .comm token,8,8
+ .text
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {
+ .section .rodata
+1:
+ .string "pat1\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ [ab]+ . 'c' => {
+ .section .rodata
+2:
+ .string "pat2\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+};
+
+ any;
+ *|;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+ movq %r13, -8(%rbp)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq scanner_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "ba a"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/scan4_c.rl b/test/trans.d/case/scan4_c.rl
new file mode 100644
index 00000000..16156454
--- /dev/null
+++ b/test/trans.d/case/scan4_c.rl
@@ -0,0 +1,74 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+char * ts ;
+char * te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%s", "pat1\n" );
+};
+
+ [ab]+ . 'c' => {printf( "%s", "pat2\n" );
+};
+
+ any;
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ char *eof = pe;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"ba a",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan4_crack.rl b/test/trans.d/case/scan4_crack.rl
new file mode 100644
index 00000000..5b3df31a
--- /dev/null
+++ b/test/trans.d/case/scan4_crack.rl
@@ -0,0 +1,61 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int
+ ts;
+int
+ te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {cout.format( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {cout.format( "pat2\n" );
+};
+
+ any;
+ *|;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+ int eof = pe;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "ba a" );
+}
+
+main();
diff --git a/test/trans.d/case/scan4_cs.rl b/test/trans.d/case/scan4_cs.rl
new file mode 100644
index 00000000..d0c4ad2c
--- /dev/null
+++ b/test/trans.d/case/scan4_cs.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int ts;
+int te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {Console.Write( "pat1\n" );};
+
+ [ab]+ . 'c' => {Console.Write( "pat2\n" );};
+
+ any;
+ *|;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"ba a",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/scan4_d.rl b/test/trans.d/case/scan4_d.rl
new file mode 100644
index 00000000..4e942a3c
--- /dev/null
+++ b/test/trans.d/case/scan4_d.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class scanner
+{
+const(char) * ts;
+const(char) * te;
+int act;
+int token;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {printf( "%.*s", "pat1\n" );};
+
+ [ab]+ . 'c' => {printf( "%.*s", "pat2\n" );};
+
+ any;
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ const(char) *eof = pe;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"ba a",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ scanner m = new scanner();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/scan4_go.rl b/test/trans.d/case/scan4_go.rl
new file mode 100644
index 00000000..bb7ee8bd
--- /dev/null
+++ b/test/trans.d/case/scan4_go.rl
@@ -0,0 +1,62 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var ts int ;
+var te int ;
+var act int ;
+var token int ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {fmt.Print( "pat1\n" );};
+
+ [ab]+ . 'c' => {fmt.Print( "pat2\n" );};
+
+ any;
+ *|;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ var eof int = pe
+ %% write exec;
+}
+func finish() {
+ if cs >= scanner_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"ba a",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/scan4_java.rl b/test/trans.d/case/scan4_java.rl
new file mode 100644
index 00000000..852676d9
--- /dev/null
+++ b/test/trans.d/case/scan4_java.rl
@@ -0,0 +1,77 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class scan4_java
+{
+int
+ ts ;
+int
+ te ;
+int act ;
+int token ;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {System.out.print( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {System.out.print( "pat2\n" );
+};
+
+ any;
+ *|;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ int eof = len;
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= scanner_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"ba a",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ scan4_java machine = new scan4_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/scan4_julia.rl b/test/trans.d/case/scan4_julia.rl
new file mode 100644
index 00000000..f23b5efa
--- /dev/null
+++ b/test/trans.d/case/scan4_julia.rl
@@ -0,0 +1,48 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print( "pat2\n" );
+};
+
+ any;
+ *|;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+ts = 0;
+te = 0;
+act = 0;
+token = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "ba a" );
diff --git a/test/trans.d/case/scan4_ocaml.rl b/test/trans.d/case/scan4_ocaml.rl
new file mode 100644
index 00000000..21e13be8
--- /dev/null
+++ b/test/trans.d/case/scan4_ocaml.rl
@@ -0,0 +1,51 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let ts = ref 0
+let te = ref 0
+let act = ref 0
+let token = ref 0
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print_string( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print_string( "pat2\n" );
+};
+
+ any;
+ *|;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ let eof = pe in
+ %% write init;
+ %% write exec;
+ if !cs >= scanner_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "ba a";
+ ()
+;;
+
diff --git a/test/trans.d/case/scan4_ruby.rl b/test/trans.d/case/scan4_ruby.rl
new file mode 100644
index 00000000..3fd484ce
--- /dev/null
+++ b/test/trans.d/case/scan4_ruby.rl
@@ -0,0 +1,56 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print( "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print( "pat2\n" );
+};
+
+ any;
+ *|;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ts = 1
+te = 1
+act = 1
+token = 1
+ %% write init;
+ %% write exec;
+ if cs >= scanner_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"ba a",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/scan4_rust.rl b/test/trans.d/case/scan4_rust.rl
new file mode 100644
index 00000000..84e03aea
--- /dev/null
+++ b/test/trans.d/case/scan4_rust.rl
@@ -0,0 +1,57 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut ts : i32
+ = 0;
+static mut te : i32
+ = 0;
+static mut act : i32 = 0;
+static mut token : i32 = 0;
+
+%%{
+ machine scanner;
+
+ # Warning: changing the patterns or the input string will affect the
+ # coverage of the scanner action types.
+ main := |*
+ 'a' => {print!( "{}", "pat1\n" );
+};
+
+ [ab]+ . 'c' => {print!( "{}", "pat2\n" );
+};
+
+ any;
+ *|;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= scanner_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "ba a".to_string() ); }
+}
+
diff --git a/test/trans.d/case/stateact1.rl b/test/trans.d/case/stateact1.rl
new file mode 100644
index 00000000..e5878b7c
--- /dev/null
+++ b/test/trans.d/case/stateact1.rl
@@ -0,0 +1,47 @@
+/*
+ * @LANG: indep
+ *
+ * Test in and out state actions.
+ */
+
+%%{
+ machine state_act;
+
+ action a1 { print_str "a1\n"; }
+ action a2 { print_str "a2\n"; }
+ action b1 { print_str "b1\n"; }
+ action b2 { print_str "b2\n"; }
+ action c1 { print_str "c1\n"; }
+ action c2 { print_str "c2\n"; }
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+##### INPUT #####
+
+"hi\nhi\n"
+
+##### OUTPUT #####
+a2
+b2
+c1
+c2
+b1
+b2
+c1
+c2
+b1
+FAIL
diff --git a/test/trans.d/case/stateact1_asm.rl b/test/trans.d/case/stateact1_asm.rl
new file mode 100644
index 00000000..1d2f9486
--- /dev/null
+++ b/test/trans.d/case/stateact1_asm.rl
@@ -0,0 +1,208 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {
+ .section .rodata
+1:
+ .string "a1\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action a2 {
+ .section .rodata
+2:
+ .string "a2\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action b1 {
+ .section .rodata
+3:
+ .string "b1\n"
+ .text
+ movq $3b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action b2 {
+ .section .rodata
+4:
+ .string "b2\n"
+ .text
+ movq $4b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action c1 {
+ .section .rodata
+5:
+ .string "c1\n"
+ .text
+ movq $5b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action c2 {
+ .section .rodata
+6:
+ .string "c2\n"
+ .text
+ movq $6b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+
+}
+ action next_again {
+ fnext again;
+
+}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq state_act_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "hi\nhi\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/stateact1_c.rl b/test/trans.d/case/stateact1_c.rl
new file mode 100644
index 00000000..3f6bc0fa
--- /dev/null
+++ b/test/trans.d/case/stateact1_c.rl
@@ -0,0 +1,87 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {printf( "%s", "a1\n" );
+}
+ action a2 {printf( "%s", "a2\n" );
+}
+ action b1 {printf( "%s", "b1\n" );
+}
+ action b2 {printf( "%s", "b2\n" );
+}
+ action c1 {printf( "%s", "c1\n" );
+}
+ action c2 {printf( "%s", "c2\n" );
+}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_act_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"hi\nhi\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/stateact1_crack.rl b/test/trans.d/case/stateact1_crack.rl
new file mode 100644
index 00000000..3bdb22aa
--- /dev/null
+++ b/test/trans.d/case/stateact1_crack.rl
@@ -0,0 +1,72 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {cout.format( "a1\n" );
+}
+ action a2 {cout.format( "a2\n" );
+}
+ action b1 {cout.format( "b1\n" );
+}
+ action b2 {cout.format( "b2\n" );
+}
+ action c1 {cout.format( "c1\n" );
+}
+ action c2 {cout.format( "c2\n" );
+}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= state_act_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "hi\nhi\n" );
+}
+
+main();
diff --git a/test/trans.d/case/stateact1_cs.rl b/test/trans.d/case/stateact1_cs.rl
new file mode 100644
index 00000000..d2d37010
--- /dev/null
+++ b/test/trans.d/case/stateact1_cs.rl
@@ -0,0 +1,86 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {Console.Write( "a1\n" );}
+ action a2 {Console.Write( "a2\n" );}
+ action b1 {Console.Write( "b1\n" );}
+ action b2 {Console.Write( "b2\n" );}
+ action c1 {Console.Write( "c1\n" );}
+ action c2 {Console.Write( "c2\n" );}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_act_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"hi\nhi\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/stateact1_d.rl b/test/trans.d/case/stateact1_d.rl
new file mode 100644
index 00000000..fb728430
--- /dev/null
+++ b/test/trans.d/case/stateact1_d.rl
@@ -0,0 +1,85 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class state_act
+{
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {printf( "%.*s", "a1\n" );}
+ action a2 {printf( "%.*s", "a2\n" );}
+ action b1 {printf( "%.*s", "b1\n" );}
+ action b2 {printf( "%.*s", "b2\n" );}
+ action c1 {printf( "%.*s", "c1\n" );}
+ action c2 {printf( "%.*s", "c2\n" );}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_act_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"hi\nhi\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ state_act m = new state_act();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/stateact1_go.rl b/test/trans.d/case/stateact1_go.rl
new file mode 100644
index 00000000..3514bbc7
--- /dev/null
+++ b/test/trans.d/case/stateact1_go.rl
@@ -0,0 +1,72 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {fmt.Print( "a1\n" );}
+ action a2 {fmt.Print( "a2\n" );}
+ action b1 {fmt.Print( "b1\n" );}
+ action b2 {fmt.Print( "b2\n" );}
+ action c1 {fmt.Print( "c1\n" );}
+ action c2 {fmt.Print( "c2\n" );}
+ action next_again {fnext again;
+}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= state_act_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"hi\nhi\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/stateact1_java.rl b/test/trans.d/case/stateact1_java.rl
new file mode 100644
index 00000000..3b94ecf0
--- /dev/null
+++ b/test/trans.d/case/stateact1_java.rl
@@ -0,0 +1,88 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class stateact1_java
+{
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {System.out.print( "a1\n" );
+}
+ action a2 {System.out.print( "a2\n" );
+}
+ action b1 {System.out.print( "b1\n" );
+}
+ action b2 {System.out.print( "b2\n" );
+}
+ action c1 {System.out.print( "c1\n" );
+}
+ action c2 {System.out.print( "c2\n" );
+}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= state_act_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"hi\nhi\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ stateact1_java machine = new stateact1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/stateact1_julia.rl b/test/trans.d/case/stateact1_julia.rl
new file mode 100644
index 00000000..b750493d
--- /dev/null
+++ b/test/trans.d/case/stateact1_julia.rl
@@ -0,0 +1,62 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {print( "a1\n" );
+}
+ action a2 {print( "a2\n" );
+}
+ action b1 {print( "b1\n" );
+}
+ action b2 {print( "b2\n" );
+}
+ action c1 {print( "c1\n" );
+}
+ action c2 {print( "c2\n" );
+}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= state_act_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "hi\nhi\n" );
diff --git a/test/trans.d/case/stateact1_ocaml.rl b/test/trans.d/case/stateact1_ocaml.rl
new file mode 100644
index 00000000..86371297
--- /dev/null
+++ b/test/trans.d/case/stateact1_ocaml.rl
@@ -0,0 +1,64 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {print_string( "a1\n" );
+}
+ action a2 {print_string( "a2\n" );
+}
+ action b1 {print_string( "b1\n" );
+}
+ action b2 {print_string( "b2\n" );
+}
+ action c1 {print_string( "c1\n" );
+}
+ action c2 {print_string( "c2\n" );
+}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= state_act_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "hi\nhi\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/stateact1_ruby.rl b/test/trans.d/case/stateact1_ruby.rl
new file mode 100644
index 00000000..d8ecb208
--- /dev/null
+++ b/test/trans.d/case/stateact1_ruby.rl
@@ -0,0 +1,70 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {print( "a1\n" );
+}
+ action a2 {print( "a2\n" );
+}
+ action b1 {print( "b1\n" );
+}
+ action b2 {print( "b2\n" );
+}
+ action c1 {print( "c1\n" );
+}
+ action c2 {print( "c2\n" );
+}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= state_act_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"hi\nhi\n",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/stateact1_rust.rl b/test/trans.d/case/stateact1_rust.rl
new file mode 100644
index 00000000..f723f96a
--- /dev/null
+++ b/test/trans.d/case/stateact1_rust.rl
@@ -0,0 +1,69 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine state_act;
+
+ action a1 {print!( "{}", "a1\n" );
+}
+ action a2 {print!( "{}", "a2\n" );
+}
+ action b1 {print!( "{}", "b1\n" );
+}
+ action b2 {print!( "{}", "b2\n" );
+}
+ action c1 {print!( "{}", "c1\n" );
+}
+ action c2 {print!( "{}", "c2\n" );
+}
+ action next_again {fnext again;}
+
+ hi = 'hi';
+ line = again:
+ hi
+ >to b1
+ >from b2
+ '\n'
+ >to c1
+ >from c2
+ @next_again;
+
+ main := line*
+ >to a1
+ >from a2;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= state_act_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "hi\nhi\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/targs1.rl b/test/trans.d/case/targs1.rl
new file mode 100644
index 00000000..b97a550e
--- /dev/null
+++ b/test/trans.d/case/targs1.rl
@@ -0,0 +1,35 @@
+/*
+ * @LANG: indep
+ */
+
+int return_to;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ print_str "one\n";
+ fnext *return_to;
+ };
+
+ two := 'two' @{
+ print_str "two\n";
+ fnext *return_to;
+ };
+
+ main := (
+ '1' @{ return_to = ftargs; fnext one; }
+ | '2' @{ return_to = ftargs; fnext two; }
+ | '\n'
+ )*;
+}%%
+
+##### INPUT #####
+"1one2two1one\n"
+##### OUTPUT #####
+one
+two
+one
+ACCEPT
diff --git a/test/trans.d/case/targs1_asm.rl b/test/trans.d/case/targs1_asm.rl
new file mode 100644
index 00000000..7d4df5f6
--- /dev/null
+++ b/test/trans.d/case/targs1_asm.rl
@@ -0,0 +1,172 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+ .section .data
+ .comm return_to,8,8
+ .text
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{
+ .section .rodata
+1:
+ .string "one\n"
+ .text
+ movq $1b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq return_to(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ two := 'two' @{
+ .section .rodata
+2:
+ .string "two\n"
+ .text
+ movq $2b, %rax
+ pushq %rax
+ movq $.L_fmt_str, %rdi
+ popq %rsi
+ movq $0, %rax
+ call printf
+ movq return_to(%rip), %rax
+ pushq %rax
+movq $0, %rax
+popq %rcx
+fnext * %rcx;
+
+};
+
+ main := (
+ '1' @{
+ ftargs;
+ pushq %rax
+ popq %rax
+ movq %rax, return_to (%rip)
+fnext one;
+
+}
+ | '2' @{
+ ftargs;
+ pushq %rax
+ popq %rax
+ movq %rax, return_to (%rip)
+fnext two;
+
+}
+ | '\n'
+ )*;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq targs1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string "1one2two1one\n"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+
+ .align 8
+inplen:
+ .quad 1
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/targs1_c.rl b/test/trans.d/case/targs1_c.rl
new file mode 100644
index 00000000..c0ae2539
--- /dev/null
+++ b/test/trans.d/case/targs1_c.rl
@@ -0,0 +1,74 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+int return_to ;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%s", "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{printf( "%s", "two\n" );
+fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= targs1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"1one2two1one\n",
+};
+
+int inplen = 1;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/targs1_crack.rl b/test/trans.d/case/targs1_crack.rl
new file mode 100644
index 00000000..ebd0036a
--- /dev/null
+++ b/test/trans.d/case/targs1_crack.rl
@@ -0,0 +1,59 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+int return_to;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{cout.format( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{cout.format( "two\n" );
+fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= targs1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "1one2two1one\n" );
+}
+
+main();
diff --git a/test/trans.d/case/targs1_cs.rl b/test/trans.d/case/targs1_cs.rl
new file mode 100644
index 00000000..d655b7cd
--- /dev/null
+++ b/test/trans.d/case/targs1_cs.rl
@@ -0,0 +1,77 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+int return_to;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{Console.Write( "one\n" );fnext *return_to;};
+
+ two := 'two' @{Console.Write( "two\n" );fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= targs1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"1one2two1one\n",
+};
+
+
+static readonly int inplen = 1;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/targs1_d.rl b/test/trans.d/case/targs1_d.rl
new file mode 100644
index 00000000..82387206
--- /dev/null
+++ b/test/trans.d/case/targs1_d.rl
@@ -0,0 +1,76 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class targs1
+{
+int return_to;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{printf( "%.*s", "one\n" );fnext *return_to;};
+
+ two := 'two' @{printf( "%.*s", "two\n" );fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= targs1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"1one2two1one\n",
+];
+
+int inplen = 1;
+
+}
+int main()
+{
+ targs1 m = new targs1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/targs1_go.rl b/test/trans.d/case/targs1_go.rl
new file mode 100644
index 00000000..28d8de64
--- /dev/null
+++ b/test/trans.d/case/targs1_go.rl
@@ -0,0 +1,68 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+var return_to int ;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{fmt.Print( "one\n" );fnext *return_to;
+
+};
+
+ two := 'two' @{fmt.Print( "two\n" );fnext *return_to;
+
+};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;
+}
+ | '2' @{return_to = ftargs;
+fnext two;
+}
+ | '\n'
+ )*;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= targs1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"1one2two1one\n",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/targs1_java.rl b/test/trans.d/case/targs1_java.rl
new file mode 100644
index 00000000..ddf2df9e
--- /dev/null
+++ b/test/trans.d/case/targs1_java.rl
@@ -0,0 +1,75 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class targs1_java
+{
+int return_to ;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{System.out.print( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{System.out.print( "two\n" );
+fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= targs1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"1one2two1one\n",
+};
+
+static final int inplen = 1;
+
+public static void main (String[] args)
+{
+ targs1_java machine = new targs1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/targs1_julia.rl b/test/trans.d/case/targs1_julia.rl
new file mode 100644
index 00000000..445d407e
--- /dev/null
+++ b/test/trans.d/case/targs1_julia.rl
@@ -0,0 +1,49 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{print( "two\n" );
+fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+return_to = 0;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= targs1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "1one2two1one\n" );
diff --git a/test/trans.d/case/targs1_ocaml.rl b/test/trans.d/case/targs1_ocaml.rl
new file mode 100644
index 00000000..9fd43577
--- /dev/null
+++ b/test/trans.d/case/targs1_ocaml.rl
@@ -0,0 +1,53 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+let return_to = ref 0
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print_string( "one\n" );
+fnext *return_to.contents;
+};
+
+ two := 'two' @{print_string( "two\n" );
+fnext *return_to.contents;
+};
+
+ main := (
+ '1' @{return_to := ftargs;
+fnext one; }
+ | '2' @{return_to := ftargs;
+fnext two; }
+ | '\n'
+ )*;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= targs1_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "1one2two1one\n";
+ ()
+;;
+
diff --git a/test/trans.d/case/targs1_ruby.rl b/test/trans.d/case/targs1_ruby.rl
new file mode 100644
index 00000000..afb64592
--- /dev/null
+++ b/test/trans.d/case/targs1_ruby.rl
@@ -0,0 +1,57 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print( "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{print( "two\n" );
+fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+return_to = 1
+ %% write init;
+ %% write exec;
+ if cs >= targs1_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"1one2two1one\n",
+]
+
+inplen = 1
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/targs1_rust.rl b/test/trans.d/case/targs1_rust.rl
new file mode 100644
index 00000000..6fc75120
--- /dev/null
+++ b/test/trans.d/case/targs1_rust.rl
@@ -0,0 +1,56 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+static mut return_to : i32 = 0;
+
+%%{
+ machine targs1;
+
+ unused := 'unused';
+
+ one := 'one' @{print!( "{}", "one\n" );
+fnext *return_to;};
+
+ two := 'two' @{print!( "{}", "two\n" );
+fnext *return_to;};
+
+ main := (
+ '1' @{return_to = ftargs;
+fnext one;}
+ | '2' @{return_to = ftargs;
+fnext two;}
+ | '\n'
+ )*;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= targs1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "1one2two1one\n".to_string() ); }
+}
+
diff --git a/test/trans.d/case/zlen1.rl b/test/trans.d/case/zlen1.rl
new file mode 100644
index 00000000..279818a0
--- /dev/null
+++ b/test/trans.d/case/zlen1.rl
@@ -0,0 +1,15 @@
+/*
+ * @LANG: indep
+ */
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+##### INPUT #####
+""
+"x"
+##### OUTPUT #####
+ACCEPT
+FAIL
diff --git a/test/trans.d/case/zlen1_asm.rl b/test/trans.d/case/zlen1_asm.rl
new file mode 100644
index 00000000..a0e6e010
--- /dev/null
+++ b/test/trans.d/case/zlen1_asm.rl
@@ -0,0 +1,115 @@
+#
+# @LANG: asm
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+ .text
+ .comm buf, 1024, 32
+ .comm bpos, 8, 8
+ .comm stack_data, 1024, 32
+ .section .rodata
+
+.L_str_accept:
+ .string "ACCEPT"
+.L_str_fail:
+ .string "FAIL"
+.L_fmt_int:
+ .string "%ld"
+.L_fmt_str:
+ .string "%s"
+
+ %% write data;
+
+ .text
+exec:
+ pushq %rbp
+ movq %rsp, %rbp
+ subq $96, %rsp
+
+ movq $stack_data, -56(%rbp)
+
+ pushq %r12
+ pushq %r13
+ movq %rdi, %r12
+
+ # Get the length.
+ movq %r12, %rdi
+ call strlen
+ movq %r12, %r13
+ movslq %eax, %rax
+ addq %rax, %r13
+
+ movq $0, bpos(%rip)
+
+ %% write init;
+ %% write exec;
+
+ # current state is in r11.
+ movq zlen1_first_final(%rip), %rax
+ cmpq %rax, %r11
+ jl .L_exec_fail
+ movq $.L_str_accept, %rdi
+ call puts
+ jmp .L_exec_done
+.L_exec_fail:
+ movq $.L_str_fail, %rdi
+ call puts
+.L_exec_done:
+ popq %r13
+ popq %r12
+ leave
+ ret
+ .section .rodata
+.L_debug_msg:
+ .string "debug %d\n"
+.L_inp_0:
+ .string ""
+.L_inp_1:
+ .string "x"
+
+ .align 8
+inp:
+ .quad .L_inp_0
+ .quad .L_inp_1
+
+ .align 8
+inplen:
+ .quad 2
+
+ .text
+ .globl main
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ pushq %r12
+ movq $0, %r12
+.L_again:
+ movq inplen(%rip), %rax
+ cmpq %r12, %rax
+ je .L_done
+ movq inp(,%r12,8), %rdi
+ call exec
+ incq %r12
+ jmp .L_again
+.L_done:
+ popq %r12
+ mov $0, %rax
+ leave
+ ret
+debug:
+ movl %edi, %esi
+ movq $0, %rax
+ movq $.L_debug_msg, %rdi
+ call printf
+ ret
+
diff --git a/test/trans.d/case/zlen1_c.rl b/test/trans.d/case/zlen1_c.rl
new file mode 100644
index 00000000..fbeda2a0
--- /dev/null
+++ b/test/trans.d/case/zlen1_c.rl
@@ -0,0 +1,61 @@
+/*
+ * @LANG: c
+ * @GENERATED: true
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char *data, int len )
+{
+ char *p = data;
+ char *pe = data + len;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= zlen1_first_final )
+ printf( "ACCEPT\n" );
+ else
+ printf( "FAIL\n" );
+}
+
+char *inp[] = {
+"",
+"x",
+};
+
+int inplen = 2;
+
+int main( )
+{
+ int i;
+ for ( i = 0; i < inplen; i++ ) {
+ init();
+ exec( inp[i], strlen(inp[i]) );
+ finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/zlen1_crack.rl b/test/trans.d/case/zlen1_crack.rl
new file mode 100644
index 00000000..c4bfc983
--- /dev/null
+++ b/test/trans.d/case/zlen1_crack.rl
@@ -0,0 +1,46 @@
+//
+// @LANG: crack
+// @GENERATED: true
+//
+
+import crack.io cout;
+import crack.lang Buffer;
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+%% write data;
+
+void m( String s )
+{
+ byteptr data = s.buffer;
+ int p = 0;
+ int pe = s.size;
+ int cs;
+ String buffer;
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= zlen1_first_final ) {
+ cout `ACCEPT\n`;
+ }
+ else {
+ cout `FAIL\n`;
+ }
+}
+
+void main()
+{
+ m( "" );
+ m( "x" );
+}
+
+main();
diff --git a/test/trans.d/case/zlen1_cs.rl b/test/trans.d/case/zlen1_cs.rl
new file mode 100644
index 00000000..fd5e7835
--- /dev/null
+++ b/test/trans.d/case/zlen1_cs.rl
@@ -0,0 +1,66 @@
+/*
+ * @LANG: csharp
+ * @GENERATED: true
+ */
+
+using System;
+// Disables lots of warnings that appear in the test suite
+#pragma warning disable 0168, 0169, 0219, 0162, 0414
+namespace Test {
+class Test
+{
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char[] data, int len )
+{
+ int p = 0;
+ int pe = len;
+ int eof = len;
+ string _s;
+ char [] buffer = new char [1024];
+ int blen = 0;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= zlen1_first_final )
+ Console.WriteLine( "ACCEPT" );
+ else
+ Console.WriteLine( "FAIL" );
+}
+
+static readonly string[] inp = {
+"",
+"x",
+};
+
+
+static readonly int inplen = 2;
+
+public static void Main (string[] args)
+{
+ Test machine = new Test();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].ToCharArray(), inp[i].Length );
+ machine.finish();
+ }
+}
+}
+}
diff --git a/test/trans.d/case/zlen1_d.rl b/test/trans.d/case/zlen1_d.rl
new file mode 100644
index 00000000..61f43b11
--- /dev/null
+++ b/test/trans.d/case/zlen1_d.rl
@@ -0,0 +1,65 @@
+/*
+ * @LANG: d
+ * @GENERATED: true
+ */
+
+import std.stdio;
+import std.string;
+
+class zlen1
+{
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+%% write data;
+int cs;
+int blen;
+char buffer[1024];
+
+void init()
+{
+ %% write init;
+}
+void exec( const(char) data[] )
+{
+ const(char) *p = data.ptr;
+ const(char) *pe = data.ptr + data.length;
+ char _s[];
+
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= zlen1_first_final )
+ writefln( "ACCEPT" );
+ else
+ writefln( "FAIL" );
+}
+static const char[][] inp = [
+"",
+"x",
+];
+
+int inplen = 2;
+
+}
+int main()
+{
+ zlen1 m = new zlen1();
+ int i;
+ for ( i = 0; i < m.inplen; i++ ) {
+ m.init();
+ m.exec( m.inp[i] );
+ m.finish();
+ }
+ return 0;
+}
+
diff --git a/test/trans.d/case/zlen1_go.rl b/test/trans.d/case/zlen1_go.rl
new file mode 100644
index 00000000..5c0446c8
--- /dev/null
+++ b/test/trans.d/case/zlen1_go.rl
@@ -0,0 +1,51 @@
+/*
+ * @LANG: go
+ * @GENERATED: true
+ */
+
+package main
+import "fmt"
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+var cs int;
+var blen int;
+var buffer [1024] byte;
+
+%% write data;
+
+func prepare() {
+ %% write init;
+}
+
+func exec(data string) {
+ var p int = 0
+ var pe int = len(data)
+ %% write exec;
+}
+func finish() {
+ if cs >= zlen1_first_final {
+ fmt.Println("ACCEPT")
+ } else {
+ fmt.Println("FAIL")
+ }
+}
+var inp []string = []string {
+"",
+"x",
+};
+
+func main() {
+ for _, data := range inp {
+ prepare()
+ exec(data)
+ finish()
+ }
+}
diff --git a/test/trans.d/case/zlen1_java.rl b/test/trans.d/case/zlen1_java.rl
new file mode 100644
index 00000000..71c483b6
--- /dev/null
+++ b/test/trans.d/case/zlen1_java.rl
@@ -0,0 +1,62 @@
+/*
+ * @LANG: java
+ * @GENERATED: true
+ */
+
+
+class zlen1_java
+{
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+%% write data;
+int cs;
+
+void init()
+{
+ %% write init;
+}
+
+void exec( char data[], int len )
+{
+ char buffer [] = new char[1024];
+ int blen = 0;
+ int p = 0;
+ int pe = len;
+
+ String _s;
+ %% write exec;
+}
+
+void finish( )
+{
+ if ( cs >= zlen1_first_final )
+ System.out.println( "ACCEPT" );
+ else
+ System.out.println( "FAIL" );
+}
+
+static final String inp[] = {
+"",
+"x",
+};
+
+static final int inplen = 2;
+
+public static void main (String[] args)
+{
+ zlen1_java machine = new zlen1_java();
+ for ( int i = 0; i < inplen; i++ ) {
+ machine.init();
+ machine.exec( inp[i].toCharArray(), inp[i].length() );
+ machine.finish();
+ }
+}
+}
diff --git a/test/trans.d/case/zlen1_julia.rl b/test/trans.d/case/zlen1_julia.rl
new file mode 100644
index 00000000..c216470d
--- /dev/null
+++ b/test/trans.d/case/zlen1_julia.rl
@@ -0,0 +1,36 @@
+//
+// @LANG: julia
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+%% write data;
+
+function m( data::AbstractString )
+ p = 0
+ pe = length(data)
+ eof = length(data)
+ cs = 0
+ buffer = ""
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= zlen1_first_final )
+ println( "ACCEPT" );
+ else
+ println( "FAIL" );
+ end
+end
+
+ m( "" );
+ m( "x" );
diff --git a/test/trans.d/case/zlen1_ocaml.rl b/test/trans.d/case/zlen1_ocaml.rl
new file mode 100644
index 00000000..814d8657
--- /dev/null
+++ b/test/trans.d/case/zlen1_ocaml.rl
@@ -0,0 +1,38 @@
+(*
+ * @LANG: ocaml
+ * @GENERATED: true
+ *)
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+
+%% write data;
+
+let exec data =
+ let buffer = String.create(1024) in
+ let blen :int ref = ref 0 in
+ let cs = ref 0 in
+ let p = ref 0 in
+ let pe = ref (String.length data) in
+ %% write init;
+ %% write exec;
+ if !cs >= zlen1_first_final then
+ print_string "ACCEPT\n"
+ else
+ print_string "FAIL\n"
+;;
+
+let () =
+ exec "";
+ exec "x";
+ ()
+;;
+
diff --git a/test/trans.d/case/zlen1_ruby.rl b/test/trans.d/case/zlen1_ruby.rl
new file mode 100644
index 00000000..8f3d75ad
--- /dev/null
+++ b/test/trans.d/case/zlen1_ruby.rl
@@ -0,0 +1,44 @@
+#
+# @LANG: ruby
+# @GENERATED: true
+#
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+%% write data;
+
+def run_machine( data )
+ p = 0
+ pe = data.length
+ eof = data.length
+ cs = 0;
+ _m =
+ _a =
+ buffer = Array.new
+ blen = 0
+ %% write init;
+ %% write exec;
+ if cs >= zlen1_first_final
+ puts "ACCEPT"
+ else
+ puts "FAIL"
+ end
+end
+
+inp = [
+"",
+"x",
+]
+
+inplen = 2
+
+inp.each { |str| run_machine(str) }
+
diff --git a/test/trans.d/case/zlen1_rust.rl b/test/trans.d/case/zlen1_rust.rl
new file mode 100644
index 00000000..b47751ca
--- /dev/null
+++ b/test/trans.d/case/zlen1_rust.rl
@@ -0,0 +1,43 @@
+//
+// @LANG: rust
+// @GENERATED: true
+//
+
+
+
+
+%%{
+ machine zlen1;
+ main := zlen;
+}%%
+
+
+
+%% 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();
+
+ %% write init;
+ %% write exec;
+
+ if ( cs >= zlen1_first_final ) {
+ println!( "ACCEPT" );
+ }
+ else {
+ println!( "FAIL" );
+ }
+}
+
+fn main()
+{
+ unsafe { m( "".to_string() ); }
+ unsafe { m( "x".to_string() ); }
+}
+
diff --git a/test/trans.d/gentests b/test/trans.d/gentests
new file mode 100755
index 00000000..130c4b23
--- /dev/null
+++ b/test/trans.d/gentests
@@ -0,0 +1,45 @@
+#!/bin/bash
+#
+
+. ../colm.sh
+
+langs='asm crack c cs d go java julia ocaml'
+
+mkdir -p working
+
+echo working/* | xargs rm -f
+
+[ $# = 0 ] && set -- `find case -type f -and -not -name '*_*' | sort`
+
+for fn; do
+
+ prohibit_languages=`sed '/@PROHIBIT_LANGUAGES:/s/^.*: *//p;d' $fn`
+
+ for l in $langs; do
+
+ echo "$prohibit_languages" | grep -q "\<$l\>" && continue;
+
+ out=${fn%.rl}_$l.out
+ out=working/${out#case/}
+
+ class=${fn%.rl}
+ class=${class#case/}_$l
+
+ exp=${fn%.rl}_$l.rl
+
+ diff=${fn%.rl}_$l.out
+ diff=working/${diff#case/}
+
+ sh=${fn%.rl}_$l.sh
+ sh=working/${sh#case/}
+
+ rm -f $sh
+
+ echo echo testing $l $fn >> $sh
+ echo ./trans $l $out $fn $class >> $sh
+ echo diff $exp $out '>' $diff >> $sh
+
+ echo $sh
+ done
+done
+
diff --git a/test/trans.d/main.c b/test/trans.d/main.c
new file mode 100644
index 00000000..7d3b0824
--- /dev/null
+++ b/test/trans.d/main.c
@@ -0,0 +1,16 @@
+#include <colm/colm.h>
+
+extern struct colm_sections trans_object;
+
+int main( int argc, const char **argv )
+{
+ struct colm_program *prg;
+ int exit_status;
+
+ prg = colm_new_program( &trans_object );
+ colm_set_debug( prg, 0 );
+ colm_run_program( prg, argc, argv );
+ exit_status = colm_delete_program( prg );
+ return exit_status;
+}
+
diff --git a/test/trans.d/ragel-c.lm b/test/trans.d/ragel-c.lm
new file mode 100644
index 00000000..ccc2dc93
--- /dev/null
+++ b/test/trans.d/ragel-c.lm
@@ -0,0 +1,175 @@
+namespace c_inline
+ lex
+ literal `fpc `fc `fcurs `ftargs
+ `fentry `fhold `fexec `fgoto `fnext
+ `fcall `fret `fbreak `fncall `fnret `fnbreak
+
+ token ident /ident/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ / c_comment | cpp_comment /
+
+ token string
+ / s_literal | d_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ literal
+ `{ `} `:: `* `, `( `) `;
+
+ token var_ref
+ / "$" [a-zA-Z_][a-zA-Z_0-9]* /
+ {
+ if GblActionParams
+ {
+ input->push( make_token(
+ typeid<var_ref>, input->pull( match_length ) ) )
+ }
+ else
+ {
+ # Just pull one char. Don't consume the word because it may
+ # be a keyword.
+ input->push( make_token(
+ typeid<c_any>, input->pull( 1 ) ) )
+ }
+ }
+
+ token c_any
+ / any /
+ end
+
+ def inline_expr
+ [expr_item_list] :List
+
+ def expr_item_list
+ [expr_item_list expr_item] :Rec
+ | [] :Empty
+
+ def expr_item
+ [expr_any] :ExprAny
+ | [expr_symbol] :ExprSymbol
+ | [expr_interpret] :ExprInterpret
+
+ def expr_any
+ [whitespace] :WS
+ | [comment] :Comment
+ | [string] :String
+ | [number] :Number
+ | [hex_number] :Hex
+ | [ident] :Ident
+ | [c_any] :Any
+
+ def expr_symbol
+ [`,] :Comma | [`(] :Open | [`)] :Close | [`*] :Star | [`::] :DoubleColon
+
+ def expr_interpret
+ [`fpc] :Fpc
+ | [`fc] :Fc
+ | [`fcurs] :Fcurs
+ | [`ftargs] :Ftargs
+ | [`fentry `( state_ref srlex::`)] :Fentry
+ | [var_ref] :VarRef
+
+ def state_ref
+ [opt_name_sep state_ref_names] :Ref
+
+ def opt_name_sep
+ [srlex::`::] :ColonColon
+ | [] :Empty
+
+ # List of names separated by ::
+ def state_ref_names
+ [state_ref_names srlex::`:: srlex::word] :Rec
+ | [srlex::word] :Base
+
+ def inline_block
+ [block_item_list] :List
+
+ def block_item_list
+ [block_item block_item_list] :Rec
+ | [] :Base
+
+ def block_item
+ [expr_any] :ExprAny
+ | [block_symbol] :BlockSymbol
+ | [block_interpret] :BlockInterpret
+ | [`{ inline_block `}] :RecBlock
+
+ def block_symbol
+ [`,] :B1 | [`;] :B2 | [`(] :B3 | [`)] :B4 | [`*] :B5 | [`::] :B6
+
+ def block_interpret
+ [expr_interpret] :ExprInterpret
+ | [`fhold whitespace? `;] :Fhold
+ | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr
+ | [`fnext whitespace? `* inline_expr `;] :FnextExpr
+ | [`fcall whitespace? `* inline_expr `;] :FcallExpr
+ | [`fncall whitespace? `* inline_expr `;] :FncallExpr
+ | [`fexec inline_expr `;] :Fexec
+ | [`fgoto state_ref srlex::`;] :FgotoSr
+ | [`fnext state_ref srlex::`;] :FnextSr
+ | [`fcall state_ref srlex::`;] :FcallSr
+ | [`fncall state_ref srlex::`;] :FncallSr
+ | [`fret `;] :Fret
+ | [`fnret `;] :Fnret
+ | [`fbreak `;] :Fbreak
+ | [`fnbreak `;] :Fnbreak
+end
+
+
+namespace c_host
+ lex
+ literal `%%{
+
+ token slr / '%%' [^{] [^\n]* '\n' /
+ {
+ # Translates single line to multi-line
+ input->pull( 2 )
+ R: str = input->pull( match_length - 3 )
+ input->push( "\n}%%" )
+ input->push( R )
+ input->push( "%%{" )
+ }
+
+ rl NL / '\n' /
+
+ rl s_literal
+ / "'" ([^'\\\n] | '\\' (any | NL))* "'" /
+
+ rl d_literal
+ / '"' ([^"\\] | NL | '\\' (any | NL))* '"' /
+
+ token ident /ident "'"?/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ / c_comment | cpp_comment /
+
+ token string
+ / s_literal | d_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ token c_any / any /
+ end
+
+ def tok
+ [ident] :Ident
+ | [number] :Number
+ | [hex_number] :HexNumber
+ | [comment] :Comment
+ | [string] :String
+ | [whitespace] :Whitespace
+ | [c_any] :Any
+
+ def section
+ [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine
+ | [tok] :Tok
+end
+
+
diff --git a/test/trans.d/ragel-crack.lm b/test/trans.d/ragel-crack.lm
new file mode 100644
index 00000000..b6480012
--- /dev/null
+++ b/test/trans.d/ragel-crack.lm
@@ -0,0 +1,150 @@
+namespace crack_inline
+ lex
+ literal `fpc `fc `fcurs `ftargs
+ `fentry `fhold `fexec `fgoto `fnext
+ `fcall `fret `fbreak `fncall `fnret `fnbreak
+
+ token ident /ident/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ / c_comment | cpp_comment /
+
+ token string
+ / s_literal | d_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ literal
+ `{ `} `:: `* `, `( `) `;
+
+ token c_any / any /
+ end
+
+ def inline_expr
+ [expr_item*]
+
+ def expr_item
+ [expr_any] :ExprAny
+ | [expr_symbol] :ExprSymbol
+ | [expr_interpret] :ExprInterpret
+
+ def expr_any
+ [whitespace]
+ | [comment]
+ | [string]
+ | [number]
+ | [hex_number]
+ | [ident]
+ | [c_any]
+
+ def expr_symbol
+ [`,] | [`(] | [`)] | [`*] | [`::]
+
+ def expr_interpret
+ [`fpc] :Fpc
+ | [`fc] :Fc
+ | [`fcurs] :Fcurs
+ | [`ftargs] :Ftargs
+ | [`fentry `( state_ref srlex::`)] :Fentry
+
+ def state_ref
+ [opt_name_sep state_ref_names]
+
+ def opt_name_sep
+ [srlex::`::] :ColonColon
+ | [] :Empty
+
+ # List of names separated by ::
+ def state_ref_names
+ [state_ref_names srlex::`:: srlex::word] :Rec
+ | [srlex::word] :Base
+
+ def inline_block
+ [block_item*]
+
+ def block_item
+ [expr_any] :ExprAny
+ | [block_symbol] :BlockSymbol
+ | [block_interpret] :BlockInterpret
+ | [`{ inline_block `}] :RecBlock
+
+ def block_symbol
+ [`,] | [`;] | [`(] | [`)] | [`*] | [`::]
+
+ def block_interpret
+ [expr_interpret] :ExprInterpret
+ | [`fhold whitespace? `;] :Fhold
+ | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr
+ | [`fnext whitespace? `* inline_expr `;] :FnextExpr
+ | [`fcall whitespace? `* inline_expr `;] :FcallExpr
+ | [`fncall whitespace? `* inline_expr `;] :FncallExpr
+ | [`fexec inline_expr `;] :Fexec
+ | [`fgoto state_ref srlex::`;] :FgotoSr
+ | [`fnext state_ref srlex::`;] :FnextSr
+ | [`fcall state_ref srlex::`;] :FcallSr
+ | [`fncall state_ref srlex::`;] :FncallSr
+ | [`fret `;] :Fret
+ | [`fnret `;] :Fnret
+ | [`fbreak `;] :Fbreak
+ | [`fnbreak `;] :Fnbreak
+end
+
+
+namespace crack_host
+ lex
+ literal `%%{
+
+ token slr /'%%' [^{] [^\n]* '\n'/
+ {
+ input->pull( 2 )
+ R: str = input->pull( match_length - 3 )
+ input->push( "\n}%%" )
+ input->push( R )
+ input->push( "%%{" )
+ }
+
+ rl NL / '\n' /
+
+ rl s_literal
+ / "'" ([^'\\\n] | '\\' (any | NL))* "'" /
+
+ rl d_literal
+ / '"' ([^"\\] | NL | '\\' (any | NL))* '"' /
+
+ rl bt_literal
+ / '`' ([^`\\] | NL | '\\' (any | NL))* '`' /
+
+ token ident /ident "'"?/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ /c_comment | cpp_comment/
+
+ token string
+ / s_literal | d_literal | bt_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ token c_any / any /
+ end
+
+ def tok
+ [ident]
+ | [number]
+ | [hex_number]
+ | [comment]
+ | [string]
+ | [whitespace]
+ | [c_any]
+
+ def section
+ [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine
+ | [tok] :Tok
+end
+
+
diff --git a/test/trans.d/ragel-ocaml.lm b/test/trans.d/ragel-ocaml.lm
new file mode 100644
index 00000000..2b89535b
--- /dev/null
+++ b/test/trans.d/ragel-ocaml.lm
@@ -0,0 +1,147 @@
+namespace ocaml_inline
+ lex
+ literal `fpc `fc `fcurs `ftargs
+ `fentry `fhold `fexec `fgoto `fnext
+ `fcall `fret `fbreak `fncall `fnret `fnbreak
+
+ token ident /ident/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ / c_comment | cpp_comment /
+
+ token string
+ / s_literal | d_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ literal
+ `{ `} `:: `* `, `( `) `;
+
+ token c_any / any /
+ end
+
+ def inline_expr
+ [expr_item*]
+
+ def expr_item
+ [expr_any] :ExprAny
+ | [expr_symbol] :ExprSymbol
+ | [expr_interpret] :ExprInterpret
+
+ def expr_any
+ [whitespace]
+ | [comment]
+ | [string]
+ | [number]
+ | [hex_number]
+ | [ident]
+ | [c_any]
+
+ def expr_symbol
+ [`,] | [`(] | [`)] | [`*] | [`::]
+
+ def expr_interpret
+ [`fpc] :Fpc
+ | [`fc] :Fc
+ | [`fcurs] :Fcurs
+ | [`ftargs] :Ftargs
+ | [`fentry `( state_ref srlex::`)] :Fentry
+
+ def state_ref
+ [opt_name_sep state_ref_names]
+
+ def opt_name_sep
+ [srlex::`::] :ColonColon
+ | [] :Empty
+
+ # List of names separated by ::
+ def state_ref_names
+ [state_ref_names srlex::`:: srlex::word] :Rec
+ | [srlex::word] :Base
+
+ def inline_block
+ [block_item*]
+
+ def block_item
+ [expr_any] :ExprAny
+ | [block_symbol] :BlockSymbol
+ | [block_interpret] :BlockInterpret
+ | [`{ inline_block `}] :RecBlock
+
+ def block_symbol
+ [`,] | [`;] | [`(] | [`)] | [`*] | [`::]
+
+ def block_interpret
+ [expr_interpret] :ExprInterpret
+ | [`fhold whitespace? `;] :Fhold
+ | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr
+ | [`fnext whitespace? `* inline_expr `;] :FnextExpr
+ | [`fcall whitespace? `* inline_expr `;] :FcallExpr
+ | [`fncall whitespace? `* inline_expr `;] :FncallExpr
+ | [`fexec inline_expr `;] :Fexec
+ | [`fgoto state_ref srlex::`;] :FgotoSr
+ | [`fnext state_ref srlex::`;] :FnextSr
+ | [`fcall state_ref srlex::`;] :FcallSr
+ | [`fncall state_ref srlex::`;] :FncallSr
+ | [`fret `;] :Fret
+ | [`fnret `;] :Fnret
+ | [`fbreak `;] :Fbreak
+ | [`fnbreak `;] :Fnbreak
+end
+
+
+namespace ocaml_host
+ lex
+ literal `%%{
+
+ token slr /'%%' [^{] [^\n]* '\n'/
+ {
+ input->pull( 2 )
+ R: str = input->pull( match_length - 3 )
+ input->push( "\n}%%" )
+ input->push( R )
+ input->push( "%%{" )
+ }
+
+ rl NL / '\n' /
+
+ rl s_literal
+ / "'" ([^'\\\n] | '\\' (any | NL))* "'" /
+
+ rl d_literal
+ / '"' ([^"\\] | NL | '\\' (any | NL))* '"' /
+
+ token ident /ident "'"?/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ /c_comment | cpp_comment/
+
+ token string
+ / s_literal | d_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ token ocaml_any / any /
+ end
+
+ def tok
+ [ident]
+ | [number]
+ | [hex_number]
+ | [comment]
+ | [string]
+ | [whitespace]
+ | [ocaml_any]
+
+ def section
+ [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine
+ | [tok] :Tok
+end
+
+
diff --git a/test/trans.d/ragel-ruby.lm b/test/trans.d/ragel-ruby.lm
new file mode 100644
index 00000000..29e36887
--- /dev/null
+++ b/test/trans.d/ragel-ruby.lm
@@ -0,0 +1,146 @@
+namespace ruby_inline
+ lex
+ literal `fpc `fc `fcurs `ftargs
+ `fentry `fhold `fexec `fgoto `fnext
+ `fcall `fret `fbreak `fncall `fnret `fnbreak
+
+ token ident /ident/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ / ruby_comment /
+
+ token string
+ / s_literal | d_literal | host_re_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ literal
+ `{ `} `:: `* `, `( `) `;
+
+ token ruby_any / any /
+ end
+
+ def inline_expr
+ [expr_item*]
+
+ def expr_item
+ [expr_any] :ExprAny
+ | [expr_symbol] :ExprSymbol
+ | [expr_interpret] :ExprInterpret
+
+ def expr_any
+ [whitespace]
+ | [comment]
+ | [string]
+ | [number]
+ | [hex_number]
+ | [ident]
+ | [ruby_any]
+
+ def expr_symbol
+ [`,] | [`(] | [`)] | [`*] | [`::]
+
+ def expr_interpret
+ [`fpc] :Fpc
+ | [`fc] :Fc
+ | [`fcurs] :Fcurs
+ | [`ftargs] :Ftargs
+ | [`fentry `( state_ref srlex::`)] :Fentry
+
+ def state_ref
+ [opt_name_sep state_ref_names]
+
+ def opt_name_sep
+ [srlex::`::] :ColonColon
+ | [] :Empty
+
+ # List of names separated by ::
+ def state_ref_names
+ [state_ref_names srlex::`:: srlex::word] :Rec
+ | [srlex::word] :Base
+
+ def inline_block
+ [block_item*]
+
+ def block_item
+ [expr_any] :ExprAny
+ | [block_symbol] :BlockSymbol
+ | [block_interpret] :BlockInterpret
+ | [`{ inline_block `}] :RecBlock
+
+ def block_symbol
+ [`,] | [`;] | [`(] | [`)] | [`*] | [`::]
+
+ def block_interpret
+ [expr_interpret] :ExprInterpret
+ | [`fhold whitespace? `;] :Fhold
+ | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr
+ | [`fnext whitespace? `* inline_expr `;] :FnextExpr
+ | [`fcall whitespace? `* inline_expr `;] :FcallExpr
+ | [`fncall whitespace? `* inline_expr `;] :FncallExpr
+ | [`fexec inline_expr `;] :Fexec
+ | [`fgoto state_ref srlex::`;] :FgotoSr
+ | [`fnext state_ref srlex::`;] :FnextSr
+ | [`fcall state_ref srlex::`;] :FcallSr
+ | [`fncall state_ref srlex::`;] :FncallSr
+ | [`fret `;] :Fret
+ | [`fnret `;] :Fnret
+ | [`fbreak `;] :Fbreak
+ | [`fnbreak `;] :Fnbreak
+end
+
+namespace ruby_host
+ lex
+ literal `%%{
+
+ token slr /'%%' [^{] [^\n]* '\n'/
+ {
+ input->pull( 2 )
+ R: str = input->pull( match_length - 3 )
+ input->push( "\n}%%" )
+ input->push( R )
+ input->push( "%%{" )
+ }
+
+ rl NL / '\n' /
+
+ rl s_literal
+ / "'" ([^'\\\n] | '\\' (any | NL))* "'" /
+
+ rl d_literal
+ / '"' ([^"\\] | NL | '\\' (any | NL))* '"' /
+
+ token ident /ident/
+ token number /digit+/
+ token hex_number /'0x' [0-9a-fA-F]+/
+
+ token comment
+ / ruby_comment /
+
+ token string
+ / s_literal | d_literal | host_re_literal /
+
+ token whitespace
+ / ( [ \t] | NL )+ /
+
+ token ruby_any / any /
+ end
+
+ def tok
+ [ident]
+ | [number]
+ | [hex_number]
+ | [comment]
+ | [string]
+ | [whitespace]
+ | [ruby_any]
+
+ def section
+ [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine
+ | [tok] :Tok
+end
+
+
diff --git a/test/trans.d/ragel.lm b/test/trans.d/ragel.lm
new file mode 100644
index 00000000..64d5bb6a
--- /dev/null
+++ b/test/trans.d/ragel.lm
@@ -0,0 +1,559 @@
+global GblActionParams: bool = false
+global GblSectionPass: bool = false
+
+bool action_params_find( Machine: str, Action: str )
+= cc_action_params_find
+
+bool action_params_insert( Machine: str, Action: str )
+= cc_action_params_insert
+
+rl ident
+ /( alpha | '_' ) ( alpha | digit | '_' )*/
+
+rl number
+ / digit+ /
+
+rl hex_number
+ / '0x' [0-9a-fA-F]+ /
+
+rl hex_char
+ / '0x' [0-9a-fA-F]{2} /
+
+## Optimization for hex chars that appear near to each other. Converts the
+## string of 2-digit hex chars into a single string. The parse tree walker
+## concatenates the chars.
+#rl hex_string /
+# hex_char
+# (
+# (
+# [\t\n ]+ |
+# [\t\n ]* '.' [\t\n ]*
+# )
+# hex_char
+# )+
+#/
+
+rl NL / '\n' /
+
+rl c_comment
+ / '/*' ( any | NL )* :>> '*/' /
+
+rl cpp_comment
+ / '//' [^\n]* NL /
+
+rl ruby_comment
+ / '#' [^\n]* NL /
+
+rl s_literal
+ / "'" ([^'\\\n] | '\\' (any | NL))* "'" /
+
+rl d_literal
+ / '"' ([^"\\] | NL | '\\' (any | NL))* '"' /
+
+rl host_re_literal
+ / '/' ([^/\\] | NL | '\\' (any | NL))* '/' /
+
+namespace srlex
+ lex
+ ignore /[\t\n ]+/
+ literal `:: `; `)
+ token word /[a-zA-Z_][a-zA-Z0-9_]*/
+ end
+end
+
+struct machine
+ Name: str
+ ActionParams: map<str, str>
+end
+
+global MachineMap: map<str, machine> = new map<str, machine>()
+global CurMachine: machine
+
+global Lang: str
+
+lex
+ token select /''/
+ {
+ if Lang == "ruby"
+ input->push( make_token( typeid<ruby_select>, '' ) )
+ elsif Lang == "ocaml"
+ input->push( make_token( typeid<ocaml_select>, '' ) )
+ elsif Lang == "crack"
+ input->push( make_token( typeid<crack_select>, '' ) )
+ else
+ input->push( make_token( typeid<c_select>, '' ) )
+ }
+
+ token c_select //
+ token ruby_select //
+ token ocaml_select //
+ token crack_select //
+end
+
+
+namespace ragel
+ lex
+ literal `}%% -ni
+
+ ignore /[\t\n ]+/
+ ignore /'#' any* :> '\n'/
+
+ literal `^ `| `- `, `: `! `? `.
+ literal `( `) `{ -ni ni- `} `* `& `+
+
+ literal `-- `:> `:>> `<: `-> `**
+
+ literal `|* `*| `=>
+
+ literal `@ `> `< `% `$
+ literal `from `to `eof `lerr `err
+ literal `when `inwhen `outwhen `>? `$? `%?
+
+ literal `:= `|= `= `; `.. `../i `::
+
+ literal `>~ `$~ `%~ `<~ `@~ `<>~
+ literal `>* `$* `%* `<* `@* `<>*
+ literal `>/ `$/ `%/ `</ `@/ `<>/
+ literal `>! `$! `%! `<! `@! `<>!
+ literal `>^ `$^ `%^ `<^ `@^ `<>^
+ literal `<>
+
+ literal `machine `action `variable `alphtype
+ `access `write `getkey `export `import
+ `include `prepush `postpop `nfaprepush `nfapostpop
+
+ literal `:nfa `:cond `:condplus `:condstar `):
+
+ token string /
+ '"' ( [^"\\] | '\\' any )* '"' 'i'? |
+ "'" ( [^'\\] | '\\' any )* "'" 'i'?
+ /
+
+ # token hex_string / hex_string /
+
+ token lex_regex_open /'/'/ -ni
+ token lex_sqopen_pos /'['/ -ni
+ token lex_sqopen_neg /'[^'/ -ni
+
+ token word / [a-zA-Z_][a-zA-Z0-9_]* /
+ token uint / number /
+ token hex / hex_number /
+ end
+
+ lex
+ token re_dot / '.' /
+ token re_star / '*' /
+ token re_char / ^( '\\' | '.' | '*' | '[' | '/' ) | '\\' . any /
+ token re_close / '/' 'i'? /
+ token re_sqopen_pos /'['/
+ token re_sqopen_neg /'[^'/
+ end
+
+ lex
+ token re_or_dash / '-' /
+ token re_or_char / ^( '\\' | '-' | ']' ) | '\\' . any /
+ token re_or_sqclose / ']' /
+ end
+
+ # Not cannot start with '{', terminated by ';', rewritten into { inline_expr }
+ token _inline_expr_reparse
+ /[^{;] [^;]* ';'/ {
+ R: str = input->pull( match_length - 1 )
+ input->pull( 1 )
+ input->push( "}" )
+ input->push( R )
+ input->push( "{" )
+ }
+
+ token variable_name /ident/
+
+ def inline_expr_reparse
+ [_inline_expr_reparse] :Reparse
+ | [action_expr] :ActionExpr
+
+ def join
+ [join `, expression] :Rec
+ | [expression] :Base
+
+ def expression
+ [expr_left expression_op_list] :Expression
+
+ def expression_op_list
+ [expression_op expression_op_list] :Op
+ | [] :Empty
+
+ def expression_op
+ [`| term] :Or
+ | [`& term] :And
+ | [`- term] :Sub
+ | [`-- term] :Ssub
+
+ def expr_left
+ [term] :Term
+
+ def term
+ [term_left term_op_list_short] :Term
+
+ def term_left
+ [factor_label] :FactorLabel
+
+ # This list is done manually to get shortest match.
+ def term_op_list_short
+ [] :Empty
+ | [term_op term_op_list_short] :Terms
+
+ def term_op
+ [factor_label] :None
+ | [`. factor_label] :Dot
+ | [`:> factor_label] :ColonLt
+ | [`:>> factor_label] :ColonLtLt
+ | [`<: factor_label] :GtColon
+
+ def factor_label
+ [word `: factor_label] :Label
+ | [factor_ep] :Ep
+
+ def factor_ep
+ [factor_aug `-> epsilon_target] :Epsilon
+ | [factor_aug] :Base
+
+ def epsilon_target
+ [epsilon_target `:: word] :Rec
+ | [word] :Base
+
+ def action_expr
+ [`{ c_select CInlineExpr: c_inline::inline_expr c_inline::`}] :C
+ | [`{ ruby_select RubyInlineExpr: ruby_inline::inline_expr ruby_inline::`}]
+ | [`{ ocaml_select OCamlInlineExpr: ocaml_inline::inline_expr ocaml_inline::`}]
+ | [`{ crack_select CrackInlineExpr: crack_inline::inline_expr crack_inline::`}]
+
+ def action_block
+ [`{ c_select CInlineBlock: c_inline::inline_block c_inline::`}] :C
+ | [`{ ruby_select RubyInlineBlock: ruby_inline::inline_block ruby_inline::`}]
+ | [`{ ocaml_select OCamlInlineBlock: ocaml_inline::inline_block ocaml_inline::`}]
+ | [`{ crack_select CrackInlineBlock: crack_inline::inline_block crack_inline::`}]
+
+ def action_arg_list
+ [action_arg_list `, action_ref] :Rec
+ | [action_ref] :Base
+
+ def opt_action_arg_list
+ [action_arg_list] :List
+ | [] :Empty
+
+ def named_action_ref
+ [word] :Plain
+ {
+ if ! GblSectionPass {
+ if action_params_find( CurMachine->Name, $lhs.word )
+ reject
+ }
+ }
+ | [word `( opt_action_arg_list `)] :Args
+ {
+ if ! GblSectionPass {
+ if ! action_params_find( CurMachine->Name, $lhs.word )
+ reject
+ }
+ }
+
+ def action_ref
+ [named_action_ref] :NamedRef
+ | [`( named_action_ref `)] :ParenNamed
+ | [action_block] :Block
+
+ def priority_name
+ [word] :Word
+
+ def error_name
+ [word] :Word
+
+ def priority_aug
+ [uint] :NoSign
+ | [`+ uint] :Plus
+ | [`- uint] :Minus
+
+ def aug_base
+ [`@] :Finish | [`>] :Enter | [`%] :Leave | [`$] :All
+
+ def aug_cond
+ [`>?] :Start1 | [`$?] :All1 | [`%?] :Leave1
+ | [`> `when] :Start2 | [`$ `when] :All2 | [`% `when] :Leave2
+ | [`inwhen] :Start3 | [`when] :All3 | [`outwhen] :Leave3
+
+ def aug_to_state
+ [`>~] :Start1 | [`<~] :NotStart1 | [`$~] :All1
+ | [`%~] :Final1 | [`@~] :NotFinal1 | [`<>~] :Middle1
+ | [`> `to] :Start2 | [`< `to] :NotStart2 | [`$ `to] :All2
+ | [`% `to] :Final2 | [`@ `to] :NotFinal2 | [`<> `to] :Middle2
+
+ def aug_from_state
+ [`>*] :Start1 | [`<*] :NotStart1 | [`$*] :All1
+ | [`%*] :Final1 | [`@*] :NotFinal1 | [`<>*] :Middle1
+ | [`> `from] :Start2 | [`< `from] :NotStart2 | [`$ `from] :All2
+ | [`% `from] :Final2 | [`@ `from] :NotFinal2 | [`<> `from] :Middle2
+
+ def aug_eof
+ [`>/] :Start1 | [`</] :NotStart1 | [`$/] :All1
+ | [`%/] :Final1 | [`@/] :NotFinal1 | [`<>/] :Middle1
+ | [`> `eof] :Start2 | [`< `eof] :NotStart2 | [`$ `eof] :All2
+ | [`% `eof] :Final2 | [`@ `eof] :NotFinal2 | [`<> `eof] :Middle2
+
+ def aug_gbl_error
+ [`>!] :Start1 | [`<!] :NotStart1 | [`$!] :All1
+ | [`%!] :Final1 | [`@!] :NotFinal1 | [`<>!] :Middle1
+ | [`> `err] :Start2 | [`< `err] :NotStart2 | [`$ `err] :All2
+ | [`% `err] :Final2 | [`@ `err] :NotFinal2 | [`<> `err] :Middle2
+
+ def aug_local_error
+ [`>^] :Start1 | [`<^] :NotStart1 | [`$^] :All1
+ | [`%^] :Final1 | [`@^] :NotFinal1 | [`<>^] :Middle1
+ | [`> `lerr] :Start2 | [`< `lerr] :NotStart2 | [`$ `lerr] :All2
+ | [`% `lerr] :Final2 | [`@ `lerr] :NotFinal2 | [`<> `lerr] :Middle2
+
+ def factor_aug
+ [factor_aug aug_base action_ref] :ActionRef
+ | [factor_aug aug_base priority_aug] :PriorEmbed
+ | [factor_aug aug_base `( priority_name `, priority_aug `)] :NamedPriorEmbed
+ | [factor_aug aug_cond action_ref] :CondEmbed
+ | [factor_aug aug_cond `! action_ref] :NegCondEmbed
+ | [factor_aug aug_to_state action_ref] :ToStateAction
+ | [factor_aug aug_from_state action_ref] :FromStateAction
+ | [factor_aug aug_eof action_ref] :EofAction
+ | [factor_aug aug_gbl_error action_ref] :GblErrorAction
+ | [factor_aug aug_local_error action_ref] :LocalErrorDef
+ | [factor_aug aug_local_error `( error_name `, action_ref `)] :LocalErrorName
+ | [factor_rep] :Base
+
+ def factor_rep
+ [factor_neg factor_rep_op_list] :Op
+
+ def factor_rep_op_list
+ [factor_rep_op factor_rep_op_list] :Rec
+ | [] :Base
+
+ def factor_rep_op
+ [`*] :Star
+ | [`**] :StarStar
+ | [`?] :Optional
+ | [`+] :Plus
+ | [`{ factor_rep_num `}] :ExactRep
+ | [`{ `, factor_rep_num `}] :MaxRep
+ | [`{ factor_rep_num `, `}] :MinRep
+ | [`{ LowRep: factor_rep_num `, HighRep: factor_rep_num `}] :RangeRep
+
+ def factor_rep_num
+ [uint] :RepNum
+
+ def factor_neg
+ [`! factor_neg] :Bang
+ | [`^ factor_neg] :Caret
+ | [factor] :Base
+
+ def opt_max_arg
+ [`, action_ref] :Action
+ | [] :Empty
+
+ def nfastar
+ [`:nfa]
+
+ def colon_cond
+ [`:cond] :Cond
+ | [`:condstar] :CondStar
+ | [`:condplus] :CondPlus
+
+ def factor
+ [alphabet_num] :AlphabetNum
+ | [word] :Word
+ | [string] :String
+ #| [hex_string] :HexString
+ | [lex_sqopen_pos reg_or_data re_or_sqclose] :PosOrBlock
+ | [lex_sqopen_neg reg_or_data re_or_sqclose] :NegOrBlock
+ | [lex_regex_open regex re_close] :Regex
+ | [RL1: range_lit `.. RL2: range_lit] :Range
+ | [RL1: range_lit `../i RL2: range_lit] :RangeIndep
+ | [nfastar `( expression `,
+ Push: action_ref `, Pop: action_ref `, Init: action_ref `, Stay: action_ref `,
+ Repeat: action_ref `, Exit: action_ref `):] :Nfa
+ | [colon_cond `( expression `,
+ Init: action_ref `, Inc: action_ref `, Min: action_ref OptMax: opt_max_arg `):] :Cond
+ | [`( join `)] :Join
+
+ def regex
+ [reg_item_rep_list] :List
+
+ def reg_item_rep_list
+ [reg_item_rep_list reg_item_rep] :Rec
+ | [] :Base
+
+ def reg_item_rep
+ [reg_item re_star] :Star
+ | [reg_item] :Base
+
+ def reg_item
+ [re_sqopen_pos reg_or_data re_or_sqclose] :PosOrBlock
+ | [re_sqopen_neg reg_or_data re_or_sqclose] :NegOrBlock
+ | [re_dot] :Dot
+ | [re_char] :Char
+
+ def reg_or_data
+ [reg_or_data reg_or_char] :Data
+ | [] :Base
+
+ def reg_or_char
+ [re_or_char] :Char
+ | [Low: re_or_char re_or_dash High: re_or_char] :Range
+
+ def range_lit
+ [string] :String
+ | [alphabet_num] :AN
+
+ def alphabet_num
+ [uint] :Uint
+ | [`- uint] :Neg
+ | [hex] :Hex
+
+ def lm_act
+ [`=> action_ref] :ActionRef
+ | [action_block] :ActionBlock
+
+ def opt_lm_act
+ [lm_act] :Act
+ | [] :Empty
+
+ def lm_stmt
+ [join opt_lm_act `;] :LmStmt commit
+ | [assignment] :Assignment
+ | [action_spec] :ActionSpec
+
+ def lm_stmt_list
+ [lm_stmt_list lm_stmt] :Rec
+ | [lm_stmt] :Base
+
+ def lm
+ [join] :Join
+ | [`|* lm_stmt_list `*|] :Lm
+
+ #
+ # Actions
+ #
+ def action_param
+ [word] :Word
+
+ def action_param_list
+ [action_param_list `, action_param] :Rec
+ | [action_param] :Base
+
+ def opt_action_param_list
+ [action_param_list] :List
+ | [] :Empty
+
+ def action_params
+ [`( opt_action_param_list `)] :List
+ {
+ GblActionParams = true
+ }
+
+ def action_spec
+ [`action word action_params action_block] :ActionSpecParams commit
+ {
+ if ! GblSectionPass {
+ # Track that this action has params so we can parse appropriately
+ # when reducing.
+ # CurMachine->ActionParams->insert( $lhs.word, $lhs.word )
+ action_params_insert( CurMachine->Name, $lhs.word )
+ }
+
+ # Reset after parsing the block.
+ GblActionParams = false
+ }
+ | [`action word action_block] :ActionSpec commit
+ {
+ GblActionParams = false
+ }
+
+ def def_name
+ [word] :Word
+
+ #
+ # Machine Instantiations.
+ #
+ def assignment
+ [opt_export def_name `= join `;] :Assignment commit
+
+ def instantiation
+ [opt_export def_name `:= lm `;] :Instantiation commit
+
+ def nfa_expr
+ [nfa_expr `| term] :Union
+ | [term] :Base
+
+ def nfa_round_spec
+ [Depth: uint `, Group: uint] :Spec
+
+ def nfa_round_list
+ [nfa_round_list `, nfa_round_spec] :Recurse
+ | [nfa_round_spec] :Base
+
+ def nfa_rounds
+ [`( nfa_round_list `)] :Rounds
+
+ def nfa_union
+ [def_name `|= nfa_rounds nfa_expr `;] :NfaUnion commit
+
+ def alphtype_type
+ [W1: word] :One
+ | [W1: word W2: word] :Two
+
+ def include_spec
+ [word] :Machine
+ | [string] :File
+ | [word string] :MachineFile
+
+ def opt_export
+ [`export] :Export
+ | [] :Base
+
+ def write_arg
+ [word] :Word
+
+ def machine_name
+ [`machine word `;] :MachineName
+ {
+ Machine: machine = MachineMap->find( $lhs.word )
+
+ if !Machine
+ {
+ Machine = new machine()
+ Machine->Name = $lhs.word
+ Machine->ActionParams = new map<str, str>()
+ MachineMap->insert( Machine->Name, Machine )
+ }
+
+ CurMachine = Machine
+ }
+
+ def statement
+ [assignment] :Assignment
+ | [instantiation] :Instantiation
+ | [nfa_union] :NfaUnion
+ | [action_spec] :ActionSpec
+ | [`prepush action_block] :PrePush commit
+ | [`postpop action_block] :PostPop commit
+ | [`variable variable_name inline_expr_reparse] :Variable commit
+ | [`alphtype alphtype_type `;] :AlphType commit
+ | [`access inline_expr_reparse] :Access commit
+ | [`write Cmd: word ArgList: write_arg* `;] :Write commit
+ | [`getkey inline_expr_reparse] :GetKey commit
+ | [`import string `;] :Import commit
+ | [`include include_spec `;] :Include commit
+ | [`nfaprepush action_block] :NfaPrePush commit
+ | [`nfapostpop action_block] :NfaPostPop commit
+
+ def opt_machine_name
+ [machine_name] :MachineName
+ | [] :Empty
+
+ def ragel_start
+ [opt_machine_name statement*]
+end
diff --git a/test/trans.d/trans-asm.lm b/test/trans.d/trans-asm.lm
new file mode 100644
index 00000000..1adcb6af
--- /dev/null
+++ b/test/trans.d/trans-asm.lm
@@ -0,0 +1,601 @@
+global Label: int = 1
+
+int rw_asm_factor( Factor: indep::factor )
+{
+ switch 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)] )
+ #}
+ case [`< type `> `( expr `)] {
+ rw_asm_expr( Factor.expr )
+ }
+ case [`( expr `)] {
+ rw_asm_expr( Factor.expr )
+ }
+ case ['true'] {
+ send Out
+ " movq $1, %rax
+ " pushq %rax
+ }
+ case ['false'] {
+ send Out
+ " movq $0, %rax
+ " pushq %rax
+ }
+ case [`fentry `( E: expr `)] {
+ send Out
+ " movq $fentry([E]), %rax
+ " pushq %rax
+ }
+ case [`fc] {
+ send Out
+ " movsbq (%r12), %rax
+ " pushq %rax
+ }
+ case [`fcurs] {
+ send Out
+ " fcurs;
+ " pushq %rax
+ }
+ case [`ftargs] {
+ send Out
+ " ftargs;
+ " pushq %rax
+ }
+ case ["p"] {
+ send Out
+ " pushq %r12
+ }
+ case ["te"] {
+ send Out
+ " movq -24(%rbp), %rax
+ " pushq %rax
+ }
+ case [Ident: tk_ident] {
+ send Out
+ " movq [Ident](%rip), %rax
+ " pushq %rax
+ }
+ case [Number: tk_number] {
+ send Out
+ " movq $[Number], %rax
+ " pushq %rax
+ }
+ case [`- Number: tk_number] {
+ send Out
+ " movq $-[Number], %rax
+ " pushq %rax
+
+ }
+ case "'0'" {
+ send Out
+ " movq $48, %rax
+ " pushq %rax
+ }
+ case "'a'" {
+ send Out
+ " movq $97, %rax
+ " pushq %rax
+ }
+ case [String: string] {
+ send Out
+ " .section .rodata
+ "[Label]:
+ " .string [String]
+ " .text
+ " movq $[Label]b, %rax
+ " pushq %rax
+ Label = Label + 1
+ }
+ case [`buffer] {
+ send Out
+ " movq $buf, %rax
+ " pushq %rax
+ }
+ case [`blen] {
+ send Out
+ " movq bpos(%rip), %rax
+ " pushq %rax
+ }
+ case [`first_token_char]
+ {
+ # Tokstart: -16
+ send Out
+ " movq -16(%rbp), %rax
+ " movsbq (%rax), %rcx
+ " pushq %rcx
+ }
+ default {
+ send Out
+ "NOT IMPELMENTED
+ "[Factor]
+ }
+ #else
+ #{
+ # send Out [$Factor]
+ #}
+}
+
+void rw_asm_abs_expr( Expr: indep::abs_expr )
+{
+ if ( Expr.Op ) {
+ rw_asm_abs_expr( Expr.E1 )
+ rw_asm_abs_expr( Expr.E2 )
+
+ send Out
+ " popq %rcx
+ " popq %rax
+
+ switch Expr.Op
+ case [`+] {
+ send Out
+ " addq %rcx, %rax
+ }
+ case [`-] {
+ send Out
+ " subq %rcx, %rax
+ }
+ case [`*] {
+ send Out
+ " imul %rcx, %rax
+ }
+ case [`==] {
+ send Out
+ " cmp %rcx, %rax
+ " sete %al
+ " movsbq %al, %rax
+ }
+ case [`!=] {
+ send Out
+ " cmp %rcx, %rax
+ " setne %al
+ " movsbq %al, %rax
+ }
+ case [`>=] {
+ send Out
+ " cmp %rcx, %rax
+ " setge %al
+ " movsbq %al, %rax
+ }
+
+ send Out
+ " pushq %rax
+ }
+ else {
+ rw_asm_factor( Expr.factor )
+ }
+}
+
+void rw_asm_expr( Expr: indep::expr )
+{
+ AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative )
+ rw_asm_abs_expr( AbsExpr )
+}
+
+int rw_asm_print_stmt( Stmt: indep::print_stmt )
+{
+ switch Stmt
+ case [`print_int expr `;] {
+ rw_asm_expr( Stmt.expr )
+
+ send Out
+ " movq $.L_fmt_int, %rdi
+ " popq %rsi
+ " movq $0, %rax
+ " call printf
+ }
+ case [`print_buf E1: expr `, E2: expr `;] {
+ #send Out
+ # "fwrite( [rw_c_expr(E1)], 1, [rw_c_expr(E2)], stdout );"
+ }
+ case [`print_str expr `;] {
+ rw_asm_expr( Stmt.expr )
+
+ send Out
+ " movq $.L_fmt_str, %rdi
+ " popq %rsi
+ " movq $0, %rax
+ " call printf
+ }
+ case [`print_token `;] {
+ L1: int = Label
+ Label = Label + 1
+
+ L2: int = Label
+ Label = Label + 1
+
+ send Out
+ " movq -16(%rbp), %rax # ts
+ " movq -24(%rbp), %rcx # te
+ " subq %rax, %rcx # length
+ "[L1]:
+ " cmp $0, %rcx
+ " je [L2]f
+ " movsbl (%rax), %edi
+ " push %rax
+ " push %rcx
+ " call putchar
+ " pop %rcx
+ " pop %rax
+ " addq $1, %rax
+ " subq $1, %rcx
+ " jmp [L1]b
+ "[L2]:
+ "
+ }
+}
+
+int rw_asm_expr_stmt( ExprStmt: indep::expr_stmt )
+{
+ switch ExprStmt
+ case [tk_ident opt_sub `= expr `;]
+ {
+ rw_asm_expr( ExprStmt.expr )
+
+ send Out
+ " popq %rax
+ " movq %rax, [ExprStmt.tk_ident](%rip)
+ }
+ case [expr `;]
+ {
+ rw_asm_expr( ExprStmt.expr )
+ send Out
+ " popq %rax
+ }
+}
+
+int rw_asm_if_stmt( IfStmt: indep::if_stmt )
+{
+ L1: int = Label
+ Label = Label + 1
+
+ L2: int = Label
+ Label = Label + 1
+
+ rw_asm_expr( IfStmt.expr )
+
+ send Out
+ " popq %rax
+ " test %rax, %rax
+ " jz [L1]f
+
+ rw_asm_stmt_list( IfStmt._repeat_stmt )
+
+ if ( IfStmt.opt_else._repeat_stmt ) {
+ send Out
+ " jmp [L2]f
+ "[L1]:
+
+ rw_asm_stmt_list( IfStmt.opt_else._repeat_stmt )
+
+ send Out
+ "[L2]:
+ }
+ else {
+ send Out
+ "[L1]:
+ }
+
+}
+
+void rw_asm_buf_stmt( BufStmt: indep::buf_stmt )
+{
+ switch BufStmt
+ case [`buf_clear `( `) `;] {
+ send Out
+ " movq $0, bpos(%rip)
+ }
+ case [`buf_append `( `) `;] {
+ send Out
+ " movq bpos(%rip), %rax
+ " movb (%r12), %cl
+ ' movb %cl, buf(%rax)
+ " addq $1, %rax
+ " movb $0, buf(%rax)
+ " movq %rax, bpos(%rip)
+ }
+}
+
+int rw_asm_ragel_stmt( Stmt: indep::ragel_stmt )
+{
+ switch Stmt
+ case [`fexec E: expr `;] {
+ rw_asm_expr( E )
+
+ send Out
+ " popq %rax
+ " fexec %rax;
+ }
+ case [`fgoto `* E: expr `;] {
+ rw_asm_expr( E )
+ send Out
+ "movq $0, %rax
+ "popq %rcx
+ "fgoto * %rcx;
+ }
+ case [`fnext `* E: expr `;] {
+ rw_asm_expr( E )
+ send Out
+ "movq $0, %rax
+ "popq %rcx
+ "fnext * %rcx;
+ }
+ case [`fcall `* E: expr `;] {
+ rw_asm_expr( E )
+ send Out
+ "movq $0, %rax
+ "popq %rcx
+ "fcall * %rcx;
+ }
+ case [`fncall `* E: expr `;] {
+ rw_asm_expr( E )
+ send Out
+ "movq $0, %rax
+ "popq %rcx
+ "fncall * %rcx;
+ }
+ default {
+ send Out
+ "[Stmt]
+ }
+}
+
+int rw_asm_stmt( Stmt: indep::stmt )
+{
+ switch Stmt
+ case [var_decl] {
+ #rw_c_var_decl( Stmt.var_decl )
+ }
+ case [expr_stmt]
+ rw_asm_expr_stmt( Stmt.expr_stmt )
+ case [if_stmt]
+ rw_asm_if_stmt( Stmt.if_stmt )
+ case [print_stmt]
+ rw_asm_print_stmt( Stmt.print_stmt )
+ case [buf_stmt]
+ rw_asm_buf_stmt( Stmt.buf_stmt )
+ case [ragel_stmt]
+ rw_asm_ragel_stmt( Stmt.ragel_stmt )
+}
+
+void rw_asm_stmt_list( StmtList: indep::stmt* )
+{
+ for Stmt: indep::stmt in repeat( StmtList )
+ rw_asm_stmt( Stmt )
+}
+
+out_code::lines rw_asm_asm_action_block( ActionBlock: indep::action_block, ActionNum: int )
+{
+ Out = new parser<out_code::lines>()
+ if match ActionBlock [`{ stmt* `}] {
+ send Out
+ "{
+ " [rw_asm_stmt_list( ActionBlock._repeat_stmt )]
+ "}
+ }
+ else if match ActionBlock [`{ expr `}] {
+ send Out
+ "{
+ " [rw_asm_expr( ActionBlock.expr )]
+ " popq %rax
+ "}
+ }
+ send Out [] eos
+ return Out->tree
+}
+
+int rw_asm_var_decl( VarDecl: indep::var_decl )
+{
+ send Out
+ " .section .data
+ " .comm [VarDecl.tk_ident],8,8
+ " .text
+}
+
+
+void rw_asm( Output: stream )
+{
+ send Output
+ "#
+ "# @LANG: asm
+ "# @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<out_code::lines>()
+ rw_asm_var_decl( Decl )
+ send Out [] eos
+
+ send Output
+ [Out->tree]
+ }
+ }
+
+ ActionNum: int = 0
+ 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_asm_asm_action_block( IndepActionBlock, ActionNum )
+
+ # Reparse back to ragel action block.
+ Action = parse ragel::action_block[Lines]
+ if ( !Action ) {
+ print( error, ': could not reparse action: ', Lines, '\n' )
+ exit(1)
+ }
+
+ ActionNum = ActionNum + 1
+ }
+
+ send Output
+ "
+ "[@Section]
+ "
+ " .text
+ " .comm buf, 1024, 32
+ " .comm bpos, 8, 8
+ " .comm stack_data, 1024, 32
+ " .section .rodata
+ "
+ ".L_str_accept:
+ " .string \"ACCEPT\"
+ ".L_str_fail:
+ " .string \"FAIL\"
+ ".L_fmt_int:
+ " .string \"%ld\"
+ ".L_fmt_str:
+ " .string \"%s\"
+ "
+ " %% write data;
+ "
+ " .text
+ "exec:
+ " pushq %rbp
+ " movq %rsp, %rbp
+ " subq $96, %rsp
+ "
+ " movq $stack_data, -56(%rbp)
+ "
+ " pushq %r12
+ " pushq %r13
+ " movq %rdi, %r12
+
+
+ for Stmt: indep::stmt in Init {
+ if match Stmt [ExprStmt: expr_stmt] {
+ Out = new parser<out_code::lines>()
+ rw_asm_expr_stmt( ExprStmt )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ "
+ " # Get the length.
+ " movq %r12, %rdi
+ " call strlen
+ " movq %r12, %r13
+ " movslq %eax, %rax
+ " addq %rax, %r13
+ "
+ " movq $0, bpos(%rip)
+
+ if NeedsEof {
+ send Output
+ " movq %r13, -8(%rbp)
+ }
+
+ send Output
+ "
+ " %% write init;
+ " %% write exec;
+ "
+ " # current state is in r11.
+ " movq [MachineName.word]_first_final(%rip), %rax
+ " cmpq %rax, %r11
+ " jl .L_exec_fail
+ " movq $.L_str_accept, %rdi
+ " call puts
+ " jmp .L_exec_done
+ ".L_exec_fail:
+ " movq $.L_str_fail, %rdi
+ " call puts
+ ".L_exec_done:
+ " popq %r13
+ " popq %r12
+ " leave
+ " ret
+
+ send Output
+ " .section .rodata
+ ".L_debug_msg:
+ " .string \"debug %d\\n\"
+
+ NR: int = 0
+ for InputString: indep::input_string in RagelTree {
+ send Output
+ ".L_inp_[NR]:
+ " .string [^InputString]
+ NR = NR + 1
+ }
+
+ send Output
+ "
+ " .align 8
+ "inp:
+
+ NR = 0
+ for InputString: indep::input_string in RagelTree {
+ send Output
+ " .quad .L_inp_[NR]
+ NR = NR + 1
+ }
+
+ send Output
+ "
+
+
+ send Output
+ " .align 8
+ "inplen:
+ " .quad [NR]
+ "
+
+ send Output
+ " .text
+ " .globl main
+ "main:
+ " pushq %rbp
+ " movq %rsp, %rbp
+ " pushq %r12
+ " movq $0, %r12
+ ".L_again:
+ " movq inplen(%rip), %rax
+ " cmpq %r12, %rax
+ " je .L_done
+ " movq inp(,%r12,8), %rdi
+ " call exec
+ " incq %r12
+ " jmp .L_again
+ ".L_done:
+ " popq %r12
+ " mov $0, %rax
+ " leave
+ " ret
+ "debug:
+ " movl %edi, %esi
+ " movq $0, %rax
+ " movq $.L_debug_msg, %rdi
+ " call printf
+ " ret
+ "
+}
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]
+}
diff --git a/test/trans.d/trans-crack.lm b/test/trans.d/trans-crack.lm
new file mode 100644
index 00000000..f9506cb6
--- /dev/null
+++ b/test/trans.d/trans-crack.lm
@@ -0,0 +1,346 @@
+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<out_code::lines>()
+ 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<out_code::lines>()
+ 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<out_code::lines>()
+ 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
diff --git a/test/trans.d/trans-csharp.lm b/test/trans.d/trans-csharp.lm
new file mode 100644
index 00000000..5cd31085
--- /dev/null
+++ b/test/trans.d/trans-csharp.lm
@@ -0,0 +1,346 @@
+int rw_cs_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]\[ [rw_cs_expr(Factor.expr)] \]
+ }
+ else if match Factor [tk_ident `( expr `)]
+ {
+ send Out
+ "[$Factor.tk_ident]( [rw_cs_expr(Factor.expr)] )
+ }
+ elsif match Factor [`< type `> `( expr `)]
+ {
+ send Out
+ "( [rw_cs_type(Factor.type)] ) ( [rw_cs_expr(Factor.expr)] )
+ }
+ elsif match Factor [`( expr `)]
+ {
+ send Out
+ "( [rw_cs_expr(Factor.expr)] )
+ }
+ elsif match Factor ['true']
+ {
+ send Out '1'
+ }
+ elsif match Factor ['false']
+ {
+ send Out '0'
+ }
+ elsif match Factor [`buffer]
+ {
+ send Out
+ "new String( buffer, 0, blen )
+ }
+ else
+ {
+ send Out [$Factor]
+ }
+}
+
+void rw_cs_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 "int"
+ }
+ elsif match Type [`byte]
+ {
+ send Out "unsigned char"
+ }
+}
+
+void rw_cs_abs_expr( Expr: indep::abs_expr )
+{
+ if ( Expr.Op ) {
+ send Out
+ "[rw_cs_abs_expr(Expr.E1)] [$Expr.Op] [rw_cs_abs_expr( Expr.E2 )]"
+ }
+ else {
+ rw_cs_factor( Expr.factor )
+ }
+}
+
+void rw_cs_expr( Expr: indep::expr )
+{
+ AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative )
+ rw_cs_abs_expr( AbsExpr )
+}
+
+void rw_cs_opt_array( OptArr: indep::opt_arr )
+{
+ if OptArr.expr
+ send Out "\[[rw_cs_expr( OptArr.expr )]\]"
+}
+
+int rw_cs_var_decl( VarDecl: indep::var_decl )
+{
+ if ( VarDecl.opt_arr.expr ) {
+ send Out
+ "[rw_cs_type( VarDecl.type )] \[\] [$VarDecl.tk_ident]"
+ " = new [rw_cs_type( VarDecl.type )] [rw_cs_opt_array(VarDecl.opt_arr) ];
+ }
+ else {
+ send Out
+ "[rw_cs_type( VarDecl.type )] [$VarDecl.tk_ident];
+ }
+}
+
+void rw_cs_opt_sub( OptSub: indep::opt_sub )
+{
+ if ( OptSub.expr ) {
+ send Out "\[[rw_cs_expr(OptSub.expr)]\]
+ }
+}
+
+int rw_cs_expr_stmt( ExprStmt: indep::expr_stmt )
+{
+ if match ExprStmt [tk_ident opt_sub `= expr `;]
+ {
+ send Out
+ "[$ExprStmt.tk_ident rw_cs_opt_sub(ExprStmt.opt_sub)] = [rw_cs_expr(ExprStmt.expr)];
+ }
+ else if match ExprStmt [expr `;]
+ {
+ send Out
+ "[rw_cs_expr(ExprStmt.expr)];
+ }
+}
+
+int rw_cs_if_stmt( IfStmt: indep::if_stmt )
+{
+ send Out
+ "if ( [rw_cs_expr( IfStmt.expr )] )
+ "{
+ " [rw_cs_stmt_list( IfStmt._repeat_stmt )]
+ "}
+
+ if ( IfStmt.opt_else._repeat_stmt ) {
+ send Out
+ "else {
+ " [rw_cs_stmt_list( IfStmt.opt_else._repeat_stmt )]
+ "}
+ }
+}
+
+int rw_cs_print_stmt( Stmt: indep::print_stmt )
+{
+ if match Stmt [`print_int expr `;] {
+ send Out
+ "Console.Write( [rw_cs_expr(Stmt.expr)] );"
+ }
+ else if match Stmt [`print_buf E1: expr `, E2: expr `;]
+ {
+ send Out
+ "Console.Write( new String( [rw_cs_expr(E1)], 0, [rw_cs_expr(E2)] ) );"
+ }
+ else if match Stmt [`print_str expr `;]
+ {
+ send Out
+ "Console.Write( [rw_cs_expr( Stmt.expr )] );"
+ }
+ else if match Stmt [`print_token `;]
+ {
+ send Out
+ "Console.Write( new String( data , ts , te - ts ) );
+ }
+}
+
+void rw_cs_buf_stmt( BufStmt: indep::buf_stmt )
+{
+ switch BufStmt
+ case [`buf_clear `( `) `;] {
+ send Out
+ " blen = 0;
+ }
+ case [`buf_append `( `) `;] {
+ send Out
+ " buffer\[blen++\] = fc;
+ }
+}
+
+
+int rw_cs_ragel_stmt( Stmt: indep::ragel_stmt )
+{
+ send Out
+ [$Stmt]
+}
+
+int rw_cs_stmt( Stmt: indep::stmt )
+{
+ if match Stmt [var_decl]
+ rw_cs_var_decl( Stmt.var_decl )
+ else if match Stmt [expr_stmt]
+ rw_cs_expr_stmt( Stmt.expr_stmt )
+ else if match Stmt [if_stmt]
+ rw_cs_if_stmt( Stmt.if_stmt )
+ else if match Stmt [print_stmt]
+ rw_cs_print_stmt( Stmt.print_stmt )
+ else if match Stmt [buf_stmt]
+ rw_cs_buf_stmt( Stmt.buf_stmt )
+ else if match Stmt [ragel_stmt]
+ rw_cs_ragel_stmt( Stmt.ragel_stmt )
+}
+
+void rw_cs_stmt_list( StmtList: indep::stmt* )
+{
+ for Stmt: indep::stmt in repeat( StmtList )
+ rw_cs_stmt( Stmt )
+}
+
+int rw_cs_action_block( ActionBlock: indep::action_block )
+{
+ Out = new parser<out_code::lines>()
+ if match ActionBlock [`{ stmt* `}] {
+ send Out
+ "{[rw_cs_stmt_list( ActionBlock._repeat_stmt )]}
+ }
+ else if match ActionBlock [`{ expr `}] {
+ send Out
+ "{[rw_cs_expr( ActionBlock.expr )]}
+ }
+ send Out [] eos
+}
+
+void rw_csharp( Output: stream )
+{
+ send Output
+ "/*
+ " * @LANG: csharp
+
+ if ProhibitGenflags {
+ send Output
+ " * @PROHIBIT_GENFLAGS:[ProhibitGenflags]
+ }
+
+ send Output
+ " * @GENERATED: true
+ " */
+ "
+ "using System;
+ "// Disables lots of warnings that appear in the test suite
+ "#pragma warning disable 0168, 0169, 0219, 0162, 0414
+ "namespace Test {
+ "class Test
+ "{
+
+ Init: indep::stmt* = RagelTree.Init
+ for Stmt: indep::stmt in Init {
+ if match Stmt [Decl: var_decl] {
+ Out = new parser<out_code::lines>()
+ rw_cs_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)
+ }
+
+ # Translate to specific language.
+ rw_cs_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
+ ["\n" @Section "\n"]
+
+ send Output
+ "%% write data;
+ "int cs;
+ "
+ "void init()
+ "{
+
+ for Stmt: indep::stmt in Init {
+ if match Stmt [ExprStmt: expr_stmt] {
+ Out = new parser<out_code::lines>()
+ rw_cs_expr_stmt( ExprStmt )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ " %% write init;
+ "}
+ "
+ "void exec( char\[\] data, int len )
+ "{
+ " int p = 0;
+ " int pe = len;
+ " int eof = len;
+ " string _s;
+ " char \[\] buffer = new char \[1024\];
+ " int blen = 0;
+ " %% write exec;
+ "}
+ "
+ "void finish( )
+ "{
+ " if ( cs >= [$MachineName.word]_first_final )
+ " Console.WriteLine( \"ACCEPT\" );
+ " else
+ " Console.WriteLine( \"FAIL\" );
+ "}
+ "
+
+ send Output
+ "static readonly string\[\] inp = {
+
+ NR: int = 0
+ for InputString: indep::input_string in RagelTree {
+ send Output
+ [^InputString ",\n"]
+ NR = NR + 1
+ }
+
+ send Output
+ "};
+ "
+
+ send Output
+ "
+ "static readonly int inplen = [NR];
+ "
+ "public static void Main (string\[\] args)
+ "{
+ " Test machine = new Test();
+ " for ( int i = 0; i < inplen; i++ ) {
+ " machine.init();
+ " machine.exec( inp\[i\].ToCharArray(), inp\[i\].Length );
+ " machine.finish();
+ " }
+ "}
+ "}
+ "}
+}
diff --git a/test/trans.d/trans-d.lm b/test/trans.d/trans-d.lm
new file mode 100644
index 00000000..674b0555
--- /dev/null
+++ b/test/trans.d/trans-d.lm
@@ -0,0 +1,332 @@
+int rw_d_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_d_expr(Factor.expr)] \]
+ }
+ else if match Factor [tk_ident `( expr `)]
+ {
+ send Out
+ "[$Factor.tk_ident]( [rw_d_expr(Factor.expr)] )
+ }
+ elsif match Factor [`< type `> `( expr `)]
+ {
+ send Out
+ "cast( [rw_d_type(Factor.type)] ) ( [rw_d_expr(Factor.expr)] )
+ }
+ elsif match Factor [`( expr `)]
+ {
+ send Out
+ "( [rw_d_expr(Factor.expr)] )
+ }
+ elsif match Factor ['true']
+ {
+ send Out '1'
+ }
+ elsif match Factor ['false']
+ {
+ send Out '0'
+ }
+ else
+ {
+ send Out [$Factor]
+ }
+}
+
+void rw_d_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 "const(char) *"
+ }
+ elsif match Type [`byte]
+ {
+ send Out "unsigned char"
+ }
+}
+
+void rw_d_abs_expr( Expr: indep::abs_expr )
+{
+ if ( Expr.Op ) {
+ send Out
+ "[rw_d_abs_expr(Expr.E1)] [$Expr.Op] [rw_d_abs_expr( Expr.E2 )]"
+ }
+ else {
+ rw_d_factor( Expr.factor )
+ }
+}
+
+void rw_d_expr( Expr: indep::expr )
+{
+ AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative )
+ rw_d_abs_expr( AbsExpr )
+}
+
+void rw_d_opt_array( OptArr: indep::opt_arr )
+{
+ if OptArr.expr {
+ send Out "\[[rw_d_expr( OptArr.expr )]\]"
+ }
+}
+
+int rw_d_var_decl( VarDecl: indep::var_decl )
+{
+ send Out
+ "[rw_d_type( VarDecl.type )] [$VarDecl.tk_ident][rw_d_opt_array(VarDecl.opt_arr)];
+}
+
+void rw_d_opt_sub( OptSub: indep::opt_sub )
+{
+ if ( OptSub.expr )
+ send Out "\[[rw_d_expr(OptSub.expr)]\]"
+}
+
+int rw_d_expr_stmt( ExprStmt: indep::expr_stmt )
+{
+ if match ExprStmt [tk_ident opt_sub `= expr `;]
+ {
+ send Out
+ "[$ExprStmt.tk_ident rw_d_opt_sub(ExprStmt.opt_sub)] = [rw_d_expr(ExprStmt.expr)];
+ }
+ else if match ExprStmt [expr `;]
+ {
+ send Out
+ "[rw_d_expr(ExprStmt.expr)];
+ }
+}
+
+int rw_d_if_stmt( IfStmt: indep::if_stmt )
+{
+ send Out
+ "if ( [rw_d_expr( IfStmt.expr )] )
+ "{
+ " [rw_d_stmt_list( IfStmt._repeat_stmt )]
+ "}
+
+ if ( IfStmt.opt_else._repeat_stmt ) {
+ send Out
+ "else {
+ " [rw_d_stmt_list( IfStmt.opt_else._repeat_stmt )]
+ "}
+ }
+}
+
+int rw_d_print_stmt( Stmt: indep::print_stmt )
+{
+ if match Stmt [`print_int expr `;] {
+ send Out
+ "printf( \"%d\", [rw_d_expr(Stmt.expr)] );
+ }
+ else if match Stmt [`print_buf E1: expr `, E2: expr `;]
+ {
+ send Out
+ "printf( \"%.*s\", [rw_d_expr(E1)]\[0..([rw_d_expr(E2)])\] );"
+ }
+ else if match Stmt [`print_str expr `;]
+ {
+ send Out
+ "printf( \"%.*s\", [rw_d_expr(Stmt.expr)] );"
+ }
+ else if match Stmt [`print_token `;]
+ {
+ send Out
+ "printf( \"%.*s\", ts\[0..(te - ts)\] );"
+ }
+}
+
+void rw_d_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_d_ragel_stmt( Stmt: indep::ragel_stmt )
+{
+ send Out
+ [$Stmt]
+}
+
+int rw_d_stmt( Stmt: indep::stmt )
+{
+ if match Stmt [var_decl]
+ rw_d_var_decl( Stmt.var_decl )
+ else if match Stmt [expr_stmt]
+ rw_d_expr_stmt( Stmt.expr_stmt )
+ else if match Stmt [if_stmt]
+ rw_d_if_stmt( Stmt.if_stmt )
+ else if match Stmt [print_stmt]
+ rw_d_print_stmt( Stmt.print_stmt )
+ else if match Stmt [buf_stmt]
+ rw_d_buf_stmt( Stmt.buf_stmt )
+ else if match Stmt [ragel_stmt]
+ rw_d_ragel_stmt( Stmt.ragel_stmt )
+}
+
+void rw_d_stmt_list( StmtList: indep::stmt* )
+{
+ for Stmt: indep::stmt in repeat( StmtList )
+ rw_d_stmt( Stmt )
+}
+
+int rw_d_action_block( ActionBlock: indep::action_block )
+{
+ Out = new parser<out_code::lines>()
+ if match ActionBlock [`{ stmt* `}] {
+ send Out
+ "{[rw_d_stmt_list( ActionBlock._repeat_stmt )]}
+ }
+ else if match ActionBlock [`{ expr `}] {
+ send Out
+ "{[rw_d_expr( ActionBlock.expr )]}
+ }
+ send Out [] eos
+}
+
+void rw_d( Output: stream )
+{
+ send Output
+ "/*
+ " * @LANG: d
+
+ if ProhibitGenflags {
+ send Output
+ " * @PROHIBIT_GENFLAGS:[ProhibitGenflags]
+ }
+
+ send Output
+ " * @GENERATED: true
+ " */
+ "
+ "import std.stdio;
+ "import std.string;
+ "
+ "class [MachineName.word]
+ "{
+
+ Init: indep::stmt* = RagelTree.Init
+ for Stmt: indep::stmt in Init {
+ if match Stmt [Decl: var_decl] {
+ Out = new parser<out_code::lines>()
+ rw_d_var_decl( Decl )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ # Colm bug.
+ Section: indep::section = RagelTree.section
+ for Action: ragel::action_block in Section {
+ # Reparse as lang-independent code.
+ parse IndepActionBlock: indep::action_block[$Action]
+
+ rw_d_action_block( IndepActionBlock )
+
+ # Reparse back to ragel action block.
+ Action = parse ragel::action_block[$Out->tree]
+ }
+
+ 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_d_expr_stmt( ExprStmt )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ " %% write init;
+ "}
+
+ send Output
+ "void exec( const(char) data\[\] )
+ "{
+ " const(char) *p = data.ptr;
+ " const(char) *pe = data.ptr + data.length;
+
+ if NeedsEof {
+ send Output
+ " const(char) *eof = pe;
+ }
+
+ send Output
+ " char _s\[\];
+ "
+ " %% write exec;
+ "}
+ "
+ "void finish( )
+ "{
+ " if ( cs >= [MachineName.word]_first_final )
+ " writefln( \"ACCEPT\" );
+ " else
+ " writefln( \"FAIL\" );
+ "}
+
+ send Output
+ ~static const char[][] inp = [
+
+ NR: int = 0
+ for InputString: indep::input_string in RagelTree {
+ send Output [^InputString ",\n"]
+ NR = NR + 1
+ }
+
+ send Output
+ "\];
+ "
+ "int inplen = [NR];
+ "
+ "}
+
+ send Output
+ "int main()
+ "{
+ " [MachineName.word] m = new [MachineName.word]();
+ " int i;
+ " for ( i = 0; i < m.inplen; i++ ) {
+ " m.init();
+ " m.exec( m.inp\[i\] );
+ " m.finish();
+ " }
+ " return 0;
+ "}
+ "
+}
diff --git a/test/trans.d/trans-go.lm b/test/trans.d/trans-go.lm
new file mode 100644
index 00000000..30a5600f
--- /dev/null
+++ b/test/trans.d/trans-go.lm
@@ -0,0 +1,322 @@
+int rw_go_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]\[ [rw_go_expr(Factor.expr)] \]
+ }
+ else if match Factor [tk_ident `( expr `)]
+ {
+ send Out
+ "[$Factor.tk_ident]( [rw_go_expr(Factor.expr)] )
+ }
+ elsif match Factor [`< type `> `( expr `)]
+ {
+ send Out
+ "( [rw_go_type(Factor.type)] ) ( [rw_go_expr(Factor.expr)] )
+ }
+ elsif match Factor [`( expr `)]
+ {
+ send Out
+ "( [rw_go_expr(Factor.expr)] )
+ }
+ elsif match Factor ['true']
+ {
+ send Out '1'
+ }
+ elsif match Factor ['false']
+ {
+ send Out '0'
+ }
+ elsif match Factor [`buffer]
+ {
+ send Out
+ "string ( buffer\[:blen\] )"
+ }
+ else
+ {
+ send Out [$Factor]
+ }
+}
+
+void rw_go_type( Type: indep::type )
+{
+ if match Type [`int]
+ {
+ send Out "int"
+ }
+ elsif match Type [`bool]
+ {
+ send Out "int"
+ }
+ elsif match Type [`char]
+ {
+ send Out "byte"
+ }
+ elsif match Type [`ptr]
+ {
+ send Out "int"
+ }
+ elsif match Type [`byte]
+ {
+ send Out "unsigned char"
+ }
+}
+
+void rw_go_abs_expr( Expr: indep::abs_expr )
+{
+ if ( Expr.Op ) {
+ send Out
+ "[rw_go_abs_expr(Expr.E1)] [$Expr.Op] [rw_go_abs_expr( Expr.E2 )]"
+ }
+ else {
+ rw_go_factor( Expr.factor )
+ }
+}
+
+void rw_go_expr( Expr: indep::expr )
+{
+ AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative )
+ rw_go_abs_expr( AbsExpr )
+}
+
+void rw_go_opt_array( OptArr: indep::opt_arr )
+{
+ if OptArr.expr {
+ send Out "\[[rw_go_expr( OptArr.expr )]\]"
+ }
+}
+
+int rw_go_var_decl( VarDecl: indep::var_decl )
+{
+ send Out
+ "var [$VarDecl.tk_ident] [rw_go_opt_array(VarDecl.opt_arr)] [rw_go_type( VarDecl.type )] ;
+}
+
+void rw_go_opt_sub( OptSub: indep::opt_sub )
+{
+ if ( OptSub.expr )
+ send Out "\[[rw_go_expr(OptSub.expr)]\]"
+}
+
+int rw_go_expr_stmt( ExprStmt: indep::expr_stmt )
+{
+ if match ExprStmt [tk_ident opt_sub `= expr `;]
+ {
+ send Out
+ "[$ExprStmt.tk_ident rw_go_opt_sub(ExprStmt.opt_sub)] = [rw_go_expr(ExprStmt.expr)];
+ }
+ else if match ExprStmt [expr `;]
+ {
+ send Out
+ "[rw_go_expr(ExprStmt.expr)];
+ }
+}
+
+int rw_go_if_stmt( IfStmt: indep::if_stmt )
+{
+ send Out
+ "if ( [rw_go_expr( IfStmt.expr )] ) {
+ " [rw_go_stmt_list( IfStmt._repeat_stmt )]
+ "}"
+
+ if ( IfStmt.opt_else._repeat_stmt ) {
+ send Out
+ " else {
+ " [rw_go_stmt_list( IfStmt.opt_else._repeat_stmt )]
+ "}"
+ }
+
+ send Out "
+}
+
+int rw_go_print_stmt( Stmt: indep::print_stmt )
+{
+ if match Stmt [`print_int expr `;] {
+ send Out
+ "fmt.Print( [rw_go_expr(Stmt.expr)] );"
+ }
+ else if match Stmt [`print_buf E1: expr `, E2: expr `;]
+ {
+ send Out
+ "fmt.Print( string ( [rw_go_expr(E1)]\[:[rw_go_expr(E2)]\] ));"
+ }
+ else if match Stmt [`print_str expr `;]
+ {
+ send Out
+ "fmt.Print( [rw_go_expr( Stmt.expr )] );"
+ }
+ else if match Stmt [`print_token `;]
+ {
+ send Out
+ "fmt.Print( data\[ts:te\] );"
+ }
+}
+
+int rw_go_ragel_stmt( Stmt: indep::ragel_stmt )
+{
+ send Out
+ "[Stmt]
+}
+
+void rw_go_buf_stmt( BufStmt: indep::buf_stmt )
+{
+ switch BufStmt
+ case [`buf_clear `( `) `;] {
+ send Out
+ " blen = 0;
+ }
+ case [`buf_append `( `) `;] {
+ send Out
+ " buffer\[blen\] = fc;
+ " blen += 1;
+ " buffer\[blen\] = 0;
+ }
+}
+
+
+int rw_go_stmt( Stmt: indep::stmt )
+{
+ if match Stmt [var_decl]
+ rw_go_var_decl( Stmt.var_decl )
+ else if match Stmt [expr_stmt]
+ rw_go_expr_stmt( Stmt.expr_stmt )
+ else if match Stmt [if_stmt]
+ rw_go_if_stmt( Stmt.if_stmt )
+ else if match Stmt [print_stmt]
+ rw_go_print_stmt( Stmt.print_stmt )
+ else if match Stmt [buf_stmt]
+ rw_go_buf_stmt( Stmt.buf_stmt )
+ else if match Stmt [ragel_stmt]
+ rw_go_ragel_stmt( Stmt.ragel_stmt )
+}
+
+void rw_go_stmt_list( StmtList: indep::stmt* )
+{
+ for Stmt: indep::stmt in repeat( StmtList )
+ rw_go_stmt( Stmt )
+}
+
+int rw_go_action_block( ActionBlock: indep::action_block )
+{
+ Out = new parser<out_code::lines>()
+ if match ActionBlock [`{ stmt* `}] {
+ send Out
+ "{[rw_go_stmt_list( ActionBlock._repeat_stmt )]}
+ }
+ else if match ActionBlock [`{ expr `}] {
+ send Out
+ "{[rw_go_expr( ActionBlock.expr )]}
+ }
+ send Out [] eos
+}
+
+void rw_go( Output: stream )
+{
+ send Output
+ "/*
+ " * @LANG: go
+
+ if ProhibitGenflags {
+ send Output
+ " * @PROHIBIT_GENFLAGS:[ProhibitGenflags]
+ }
+
+ send Output
+ " * @GENERATED: true
+ " */
+ "
+ "package main
+ "import \"fmt\"
+ "
+
+ Init: indep::stmt* = RagelTree.Init
+ for Stmt: indep::stmt in Init {
+ if match Stmt [Decl: var_decl] {
+ Out = new parser<out_code::lines>()
+ rw_go_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]
+
+ # Translate to specific language.
+ rw_go_action_block( IndepActionBlock )
+
+ # Reparse back to ragel action block.
+ Action = parse ragel::action_block[$Out->tree]
+ }
+
+ send Output ['\n' @Section '\n']
+
+ send Output
+ "var cs int;
+ "var blen int;
+ "var buffer \[1024\] byte;
+ "
+ "%% write data;
+ "
+ "func prepare() {
+
+ for Stmt: indep::stmt in Init {
+ if match Stmt [ExprStmt: expr_stmt] {
+ Out = new parser<out_code::lines>()
+ rw_go_expr_stmt( ExprStmt )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ " %% write init;
+ "}
+ "
+ "func exec(data string) {
+ " var p int = 0
+ " var pe int = len(data)
+
+ if NeedsEof {
+ send Output
+ " var eof int = pe
+ }
+
+ send Output
+ " %% write exec;
+ "}
+ "func finish() {
+ " if cs >= [MachineName.word]_first_final {
+ " fmt.Println(\"ACCEPT\")
+ " } else {
+ " fmt.Println(\"FAIL\")
+ " }
+ "}
+
+ send Output
+ ~var inp []string = []string {
+
+ for InputString: indep::input_string in RagelTree {
+ send Output [^InputString ",\n"]
+ }
+
+ send Output
+ "};
+ "
+
+ send Output
+ "func main() {
+ " for _, data := range inp {
+ " prepare()
+ " exec(data)
+ " finish()
+ " }
+ "}
+}
diff --git a/test/trans.d/trans-java.lm b/test/trans.d/trans-java.lm
new file mode 100644
index 00000000..99c1b486
--- /dev/null
+++ b/test/trans.d/trans-java.lm
@@ -0,0 +1,346 @@
+int rw_java_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]\[ [rw_java_expr(Factor.expr)] \]
+ }
+ else if match Factor [tk_ident `( expr `)]
+ {
+ send Out
+ "[$Factor.tk_ident]( [rw_java_expr(Factor.expr)] )
+ }
+ elsif match Factor [`< type `> `( expr `)]
+ {
+ send Out
+ "( [rw_java_type(Factor.type)] ) ( [rw_java_expr(Factor.expr)] )
+ }
+ elsif match Factor [`( expr `)]
+ {
+ send Out
+ "( [rw_java_expr(Factor.expr)] )
+ }
+ elsif match Factor ['true']
+ {
+ send Out '1'
+ }
+ elsif match Factor ['false']
+ {
+ send Out '0'
+ }
+ elsif match Factor [`buffer]
+ {
+ send Out
+ "new String( buffer, 0, blen )"
+ }
+ else
+ {
+ send Out [$Factor]
+ }
+}
+
+void rw_java_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 "int
+ }
+ elsif match Type [`byte]
+ {
+ send Out "unsigned char"
+ }
+}
+
+void rw_java_abs_expr( Expr: indep::abs_expr )
+{
+ if ( Expr.Op ) {
+ send Out
+ "[rw_java_abs_expr(Expr.E1)] [$Expr.Op] [rw_java_abs_expr( Expr.E2 )]"
+ }
+ else {
+ rw_java_factor( Expr.factor )
+ }
+}
+
+void rw_java_expr( Expr: indep::expr )
+{
+ AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative )
+ rw_java_abs_expr( AbsExpr )
+}
+
+void rw_java_opt_array( OptArr: indep::opt_arr, Type: indep::type )
+{
+ if OptArr.expr {
+ send Out "\[\] = new [rw_java_type( Type )]\[[rw_java_expr( OptArr.expr )]\]"
+ }
+}
+
+int rw_java_var_decl( VarDecl: indep::var_decl )
+{
+ send Out
+ "[rw_java_type( VarDecl.type )] [$VarDecl.tk_ident] [rw_java_opt_array(VarDecl.opt_arr, VarDecl.type)];
+}
+
+void rw_java_opt_sub( OptSub: indep::opt_sub )
+{
+ if ( OptSub.expr )
+ send Out "\[[rw_java_expr(OptSub.expr)]\]"
+}
+
+int rw_java_expr_stmt( ExprStmt: indep::expr_stmt )
+{
+ if match ExprStmt [tk_ident opt_sub `= expr `;]
+ {
+ send Out
+ "[$ExprStmt.tk_ident rw_java_opt_sub(ExprStmt.opt_sub)] = [rw_java_expr(ExprStmt.expr)];
+ }
+ else if match ExprStmt [expr `;]
+ {
+ send Out
+ "[rw_java_expr(ExprStmt.expr)];
+ }
+}
+
+int rw_java_if_stmt( IfStmt: indep::if_stmt )
+{
+ send Out
+ "if ( [rw_java_expr( IfStmt.expr )] )
+ "{
+ " [rw_java_stmt_list( IfStmt._repeat_stmt )]
+ "}
+
+ if ( IfStmt.opt_else._repeat_stmt ) {
+ send Out
+ "else {
+ " [rw_java_stmt_list( IfStmt.opt_else._repeat_stmt )]
+ "}
+ }
+}
+
+int rw_java_print_stmt( Stmt: indep::print_stmt )
+{
+ if match Stmt [`print_int expr `;] {
+ send Out
+ "System.out.print( [rw_java_expr(Stmt.expr)] );
+ }
+ else if match Stmt [`print_buf E1: expr `, E2: expr `;]
+ {
+ send Out
+ "_s = new String( [rw_java_expr(E1)], 0, [rw_java_expr(E2)] );
+ "System.out.print( _s );
+ }
+ else if match Stmt [`print_str expr `;]
+ {
+ send Out
+ "System.out.print( [rw_java_expr( Stmt.expr )] );
+ }
+ else if match Stmt [`print_token `;]
+ {
+ send Out
+ "_s = new String( data, ts, te - ts );
+ "System.out.print( _s );
+ }
+}
+
+void rw_java_buf_stmt( BufStmt: indep::buf_stmt )
+{
+ switch BufStmt
+ case [`buf_clear `( `) `;] {
+ send Out
+ " blen = 0;
+ }
+ case [`buf_append `( `) `;] {
+ send Out
+ " buffer\[blen\] = fc;
+ " blen += 1;
+ }
+}
+
+
+int rw_java_ragel_stmt( Stmt: indep::ragel_stmt )
+{
+ send Out
+ [$Stmt]
+}
+
+int rw_java_stmt( Stmt: indep::stmt )
+{
+ if match Stmt [var_decl]
+ rw_java_var_decl( Stmt.var_decl )
+ else if match Stmt [expr_stmt]
+ rw_java_expr_stmt( Stmt.expr_stmt )
+ else if match Stmt [if_stmt]
+ rw_java_if_stmt( Stmt.if_stmt )
+ else if match Stmt [print_stmt]
+ rw_java_print_stmt( Stmt.print_stmt )
+ else if match Stmt [buf_stmt]
+ rw_java_buf_stmt( Stmt.buf_stmt )
+ else if match Stmt [ragel_stmt]
+ rw_java_ragel_stmt( Stmt.ragel_stmt )
+}
+
+void rw_java_stmt_list( StmtList: indep::stmt* )
+{
+ for Stmt: indep::stmt in repeat( StmtList )
+ rw_java_stmt( Stmt )
+}
+
+int rw_java_action_block( ActionBlock: indep::action_block )
+{
+ Out = new parser<out_code::lines>()
+ if match ActionBlock [`{ stmt* `}] {
+ send Out
+ "{[rw_java_stmt_list( ActionBlock._repeat_stmt )]}
+ }
+ else if match ActionBlock [`{ expr `}] {
+ send Out
+ "{[rw_java_expr( ActionBlock.expr )]}
+ }
+ send Out [] eos
+}
+
+void rw_java( 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)
+ }
+
+ rw_java_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: java
+ " * @GENERATED: true
+
+ if ProhibitGenflags {
+ send Output
+ " * @PROHIBIT_GENFLAGS:[ProhibitGenflags]
+ }
+
+ send Output
+ " */
+ "
+ "
+ "class [ClassName]
+ "{
+
+ Init: indep::stmt* = RagelTree.Init
+ for Stmt: indep::stmt in Init {
+ if match Stmt [Decl: var_decl] {
+ Out = new parser<out_code::lines>()
+ rw_java_var_decl( Decl )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ "
+ "[@Section]
+ "
+ "%% write data;
+ "int cs;
+ "
+ "void init()
+ "{
+
+ for Stmt: indep::stmt in Init {
+ if match Stmt [ExprStmt: expr_stmt] {
+ Out = new parser<out_code::lines>()
+ rw_java_expr_stmt( ExprStmt )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ " %% write init;
+ "}
+ "
+ "void exec( char data\[\], int len )
+ "{
+ " char buffer \[\] = new char\[1024\];
+ " int blen = 0;
+ " int p = 0;
+ " int pe = len;
+ "
+
+ if NeedsEof {
+ send Output
+ " int eof = len;
+ }
+
+ send Output
+ " String _s;
+ " %% write exec;
+ "}
+ "
+ "void finish( )
+ "{
+ " if ( cs >= [MachineName.word]_first_final )
+ " System.out.println( \"ACCEPT\" );
+ " else
+ " System.out.println( \"FAIL\" );
+ "}
+ "
+
+ send Output
+ "static final String inp\[\] = {
+
+ NR: int = 0
+ for InputString: indep::input_string in RagelTree {
+ send Output
+ [^InputString ",\n"]
+ NR = NR + 1
+ }
+
+ send Output
+ "};
+ "
+
+ send Output
+ "static final int inplen = [NR];
+ "
+
+ send Output
+ "public static void main (String\[\] args)
+ "{
+ " [ClassName] machine = new [ClassName]();
+ " for ( int i = 0; i < inplen; i++ ) {
+ " machine.init();
+ " machine.exec( inp\[i\].toCharArray(), inp\[i\].length() );
+ " machine.finish();
+ " }
+ "}
+ "}
+}
diff --git a/test/trans.d/trans-julia.lm b/test/trans.d/trans-julia.lm
new file mode 100644
index 00000000..ed918dbb
--- /dev/null
+++ b/test/trans.d/trans-julia.lm
@@ -0,0 +1,332 @@
+namespace trans_julia
+
+int factor( Factor: indep::factor )
+{
+ if match Factor [`first_token_char]
+ {
+ send Out "data\[ts+1\]"
+ }
+ 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
+ "convert( [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
+ "length(buffer)"
+ }
+ else
+ {
+ send Out [$Factor]
+ }
+}
+
+void type( Type: indep::type )
+{
+ switch Type
+ case [`int]
+ {
+ send Out "Int"
+ }
+ case [`bool]
+ {
+ send Out "Int8"
+ }
+ case [`char]
+ {
+ send Out "Uint8"
+ }
+ 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
+ "[VarDecl.tk_ident] = [type( VarDecl.type )] "
+ "\[ [array_init( atoi($VarDecl.opt_arr.expr) )] \];
+ }
+ else {
+ send Out
+ "[VarDecl.tk_ident] = 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 )]
+ }
+
+ send Out
+ "end
+}
+
+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
+ "print( data\[(ts+1) : (te)\] )
+ }
+}
+
+void buf_stmt( BufStmt: indep::buf_stmt )
+{
+ switch BufStmt
+ case [`buf_clear `( `) `;] {
+ send Out
+ " buffer = \"\";
+ }
+ case [`buf_append `( `) `;] {
+ send Out
+ " buffer = buffer * AbstractString(Char\[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<out_code::lines>()
+ 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 julia( 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: julia
+ "// @GENERATED: true
+
+ if ProhibitGenflags {
+ send Output
+ "// @PROHIBIT_GENFLAGS:[ProhibitGenflags]
+ }
+
+ send Output
+ "//
+ "
+
+
+ send Output
+ "
+ "[@Section]
+ "
+ "%% write data;
+ "
+ "function m( data::AbstractString )
+ " p = 0
+ " pe = length(data)
+ " eof = length(data)
+ " cs = 0
+ " buffer = \"\"
+
+ Init: indep::stmt* = RagelTree.Init
+ for Stmt: indep::stmt in Init {
+ if match Stmt [Decl: var_decl] {
+ Out = new parser<out_code::lines>()
+ var_decl( Decl )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ for Stmt: indep::stmt in Init {
+ if match Stmt [ExprStmt: expr_stmt] {
+ Out = new parser<out_code::lines>()
+ 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\" );
+ " end
+ "end
+
+
+
+ send Output
+ ~
+
+ for InputString: indep::input_string in RagelTree {
+ send Output
+ " m( [^InputString] );
+ }
+
+}
+
+end
diff --git a/test/trans.d/trans-ocaml.lm b/test/trans.d/trans-ocaml.lm
new file mode 100644
index 00000000..4298637f
--- /dev/null
+++ b/test/trans.d/trans-ocaml.lm
@@ -0,0 +1,362 @@
+int rw_ocaml_factor( Factor: indep::factor )
+{
+ switch Factor
+ case [`first_token_char] {
+ send Out
+ "( Char.code data.\[ts.contents\] )"
+ }
+ case [tk_ident `[ expr `]] {
+ send Out
+ "[$Factor.tk_ident]\[ [rw_ocaml_expr(Factor.expr)] \]
+ }
+ case [ `fentry `( E: expr `)] {
+ send Out
+ "fentry( [E] )"
+ }
+ case [tk_ident `( expr `)] {
+ send Out
+ "[$Factor.tk_ident]( [rw_ocaml_expr(Factor.expr)] )
+ }
+ case [`< type `> `( expr `)] {
+ send Out
+ "( [rw_ocaml_expr(Factor.expr)] )
+ }
+ case [`( expr `)] {
+ send Out
+ "( [rw_ocaml_expr(Factor.expr)] )
+ }
+ case ['true'] {
+ send Out '1'
+ }
+ case ['false'] {
+ send Out '0'
+ }
+ case "'0'" {
+ send Out
+ "( Char.code '0' )"
+ }
+ case "'a'" {
+ send Out
+ "( Char.code 'a' )"
+ }
+ case [`fc] {
+ send Out
+ "fc"
+ }
+ case [tk_ident] {
+ send Out
+ "[Factor.tk_ident].contents"
+ }
+ case [`buffer]
+ {
+ send Out
+ "String.sub buffer 0 blen.contents"
+ }
+ case [`blen]
+ {
+ send Out
+ "blen.contents"
+ }
+ default {
+ send Out
+ [Factor]
+ }
+}
+
+void rw_ocaml_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_ocaml_abs_expr( Expr: indep::abs_expr )
+{
+ if ( Expr.Op ) {
+ send Out
+ "[rw_ocaml_abs_expr(Expr.E1)] [$Expr.Op] [rw_ocaml_abs_expr( Expr.E2 )]"
+ }
+ else {
+ rw_ocaml_factor( Expr.factor )
+ }
+}
+
+void rw_ocaml_expr( Expr: indep::expr )
+{
+ AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative )
+ rw_ocaml_abs_expr( AbsExpr )
+}
+
+void rw_ocaml_opt_array( OptArr: indep::opt_arr )
+{
+ if OptArr.expr {
+ send Out "\[[rw_ocaml_expr( OptArr.expr )]\]"
+ }
+}
+
+int rw_ocaml_var_decl( VarDecl: indep::var_decl )
+{
+ if match VarDecl.opt_arr [] {
+ send Out
+ "let [$VarDecl.tk_ident] = ref 0
+ }
+ else {
+ send Out
+ "let [$VarDecl.tk_ident] = Array.make 32 0
+ }
+}
+
+void rw_ocaml_opt_sub( OptSub: indep::opt_sub )
+{
+ if ( OptSub.expr )
+ send Out "\[[rw_ocaml_expr(OptSub.expr)]\]"
+}
+
+int rw_ocaml_expr_stmt( ExprStmt: indep::expr_stmt )
+{
+ if match ExprStmt [tk_ident opt_sub `= expr `;]
+ {
+ if match ExprStmt.opt_sub [] {
+ send Out
+ "[$ExprStmt.tk_ident rw_ocaml_opt_sub(ExprStmt.opt_sub)] := [rw_ocaml_expr(ExprStmt.expr)];
+ }
+ else {
+ send Out
+ "Array.set [$ExprStmt.tk_ident] [rw_ocaml_expr(ExprStmt.opt_sub.expr)] [rw_ocaml_expr(ExprStmt.expr)];
+
+ }
+ }
+ else if match ExprStmt [expr `;]
+ {
+ send Out
+ "[rw_ocaml_expr(ExprStmt.expr)];
+ }
+}
+
+int rw_ocaml_if_stmt( IfStmt: indep::if_stmt )
+{
+ send Out
+ "if [rw_ocaml_expr( IfStmt.expr )] then
+ "begin
+ " [rw_ocaml_stmt_list( IfStmt._repeat_stmt )]
+ "end
+
+ if ( IfStmt.opt_else._repeat_stmt ) {
+ send Out
+ "else
+ "begin
+ " [rw_ocaml_stmt_list( IfStmt.opt_else._repeat_stmt )]
+ "end
+ }
+ send Out
+ ";
+}
+
+int rw_ocaml_print_stmt( Stmt: indep::print_stmt )
+{
+ if match Stmt [`print_int expr `;] {
+ send Out
+ "print_int( [rw_ocaml_expr(Stmt.expr)] );
+ }
+ else if match Stmt [`print_buf E1: expr `, E2: expr `;]
+ {
+ send Out
+ "for i = 0 to [rw_ocaml_expr(E2)] - 1 do print_char (Char.chr [E1].(i)) done; "
+ }
+ else if match Stmt [`print_str expr `;]
+ {
+ send Out
+ "print_string( [rw_ocaml_expr( Stmt.expr )] );
+ }
+ else if match Stmt [`print_token `;]
+ {
+ send Out
+ "for i = ts.contents to te.contents - 1 do print_char data.\[i\] done; "
+ }
+}
+
+void rw_ocaml_buf_stmt( BufStmt: indep::buf_stmt )
+{
+ switch BufStmt
+ case [`buf_clear `( `) `;] {
+ send Out
+ "begin
+ " blen := 0;
+ "end
+ }
+ case [`buf_append `( `) `;] {
+ send Out
+ " begin
+ " String.set buffer blen.contents data.\[p.contents\];
+ " blen := blen.contents + 1;
+ " end
+ }
+}
+
+int rw_ocaml_ragel_stmt( Stmt: indep::ragel_stmt )
+{
+ switch Stmt
+ case [`fnext `* E: expr `;] {
+ send Out
+ "fnext *[rw_ocaml_expr(E)];
+ }
+ case [`fncall `* E: expr `;] {
+ send Out
+ "fncall *[rw_ocaml_expr(E)];
+ }
+ default {
+ send Out
+ [Stmt]
+ }
+}
+
+int rw_ocaml_stmt( Stmt: indep::stmt )
+{
+ if match Stmt [var_decl]
+ rw_ocaml_var_decl( Stmt.var_decl )
+ else if match Stmt [expr_stmt]
+ rw_ocaml_expr_stmt( Stmt.expr_stmt )
+ else if match Stmt [if_stmt]
+ rw_ocaml_if_stmt( Stmt.if_stmt )
+ else if match Stmt [print_stmt]
+ rw_ocaml_print_stmt( Stmt.print_stmt )
+ else if match Stmt [buf_stmt]
+ rw_ocaml_buf_stmt( Stmt.buf_stmt )
+ else if match Stmt [ragel_stmt]
+ rw_ocaml_ragel_stmt( Stmt.ragel_stmt )
+}
+
+void rw_ocaml_stmt_list( StmtList: indep::stmt* )
+{
+ for Stmt: indep::stmt in repeat( StmtList )
+ rw_ocaml_stmt( Stmt )
+}
+
+int rw_ocaml_action_block( ActionBlock: indep::action_block )
+{
+ Out = new parser<out_code::lines>()
+ if match ActionBlock [`{ stmt* `}] {
+ send Out
+ "{[rw_ocaml_stmt_list( ActionBlock._repeat_stmt )]}
+ }
+ else if match ActionBlock [`{ expr `}] {
+ send Out
+ "{[rw_ocaml_expr( ActionBlock.expr )]}
+ }
+ send Out [] eos
+}
+
+void rw_ocaml( Output: stream )
+{
+ send Output
+ "(*
+ " * @LANG: ocaml
+ " * @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<out_code::lines>()
+ rw_ocaml_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 parsing indep action block: ", error, '\n', Action )
+ exit(1)
+ }
+
+ rw_ocaml_action_block( IndepActionBlock )
+
+ # Reparse back to ragel action block.
+ Action = parse ragel::action_block[$Out->tree]
+ if ( !Action ) {
+ print( "error parsing ragel action block: ", error, '\n', $Out->tree )
+ exit(1)
+ }
+ }
+
+ send Output
+ "
+ "[@Section]
+ "
+ "
+ "%% write data;
+ "
+ "let exec data =
+ " let buffer = String.create(1024) in
+ " let blen :int ref = ref 0 in
+ " let cs = ref 0 in
+ " let p = ref 0 in
+ " let pe = ref (String.length data) in
+
+ if NeedsEof {
+ send Output
+ " let eof = pe in
+ }
+
+
+ for Stmt: indep::stmt in Init {
+ if match Stmt [ExprStmt: expr_stmt] {
+ Out = new parser<out_code::lines>()
+ rw_ocaml_expr_stmt( ExprStmt )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ " %% write init;
+ " %% write exec;
+ " if !cs >= [MachineName.word]_first_final then
+ " print_string \"ACCEPT\\n\"
+ " else
+ " print_string \"FAIL\\n\"
+ ";;
+ "
+
+ send Output
+ "let () =
+
+ for InputString: indep::input_string in RagelTree {
+ send Output
+ " exec [^InputString];
+ }
+
+ send Output
+ " ()
+ ";;
+ "
+}
diff --git a/test/trans.d/trans-ruby.lm b/test/trans.d/trans-ruby.lm
new file mode 100644
index 00000000..df0f346c
--- /dev/null
+++ b/test/trans.d/trans-ruby.lm
@@ -0,0 +1,336 @@
+int rw_ruby_factor( Factor: indep::factor )
+{
+ switch Factor
+ case [`first_token_char] {
+ send Out "data\[ts\].ord"
+ }
+ case [tk_ident `[ expr `]] {
+ send Out
+ "[$Factor.tk_ident]\[ [rw_ruby_expr(Factor.expr)] \]
+ }
+ case [tk_ident `( expr `)] {
+ send Out
+ "[$Factor.tk_ident]( [rw_ruby_expr(Factor.expr)] )
+ }
+ case [`< type `> `( expr `)] {
+ send Out
+ "( [rw_ruby_expr(Factor.expr)] )
+ }
+ case [`( expr `)] {
+ send Out
+ "( [rw_ruby_expr(Factor.expr)] )
+ }
+ case ['true'] {
+ send Out '1'
+ }
+ case ['false'] {
+ send Out '0'
+ }
+ case "'0'" {
+ send Out '"0"[0].ord'
+ }
+ case "'a'" {
+ send Out '"a"[0].ord'
+ }
+ case [`buffer] {
+ send Out
+ "buffer\[0..blen-1\].pack( \"c*\" )"
+ }
+ default {
+ send Out [$Factor]
+ }
+}
+
+void rw_ruby_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_ruby_abs_expr( Expr: indep::abs_expr )
+{
+ if ( Expr.Op ) {
+ send Out
+ "[rw_ruby_abs_expr(Expr.E1)] [$Expr.Op] [rw_ruby_abs_expr( Expr.E2 )]"
+ }
+ else {
+ rw_ruby_factor( Expr.factor )
+ }
+}
+
+void rw_ruby_expr( Expr: indep::expr )
+{
+ AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative )
+ rw_ruby_abs_expr( AbsExpr )
+}
+
+void rw_ruby_opt_array( OptArr: indep::opt_arr )
+{
+ if OptArr.expr {
+ send Out "\[[rw_ruby_expr( OptArr.expr )]\]"
+ }
+}
+
+int rw_ruby_var_decl( VarDecl: indep::var_decl )
+{
+ OptArr: indep::opt_arr = VarDecl.opt_arr
+ if OptArr.expr {
+ send Out
+ "[$VarDecl.tk_ident] = Array.new
+ }
+ else {
+ send Out
+ "[$VarDecl.tk_ident] = 1
+ }
+}
+
+void rw_ruby_opt_sub( OptSub: indep::opt_sub )
+{
+ if ( OptSub.expr )
+ send Out "\[[rw_ruby_expr(OptSub.expr)]\]"
+}
+
+int rw_ruby_expr_stmt( ExprStmt: indep::expr_stmt )
+{
+ if match ExprStmt [tk_ident opt_sub `= expr `;]
+ {
+ send Out
+ "[$ExprStmt.tk_ident rw_ruby_opt_sub(ExprStmt.opt_sub)] = [rw_ruby_expr(ExprStmt.expr)];
+ }
+ else if match ExprStmt [expr `;]
+ {
+ send Out
+ "[rw_ruby_expr(ExprStmt.expr)];
+ }
+}
+
+int rw_ruby_if_stmt( IfStmt: indep::if_stmt )
+{
+ send Out
+ "if ( [rw_ruby_expr( IfStmt.expr )] )
+ " [rw_ruby_stmt_list( IfStmt._repeat_stmt )]
+
+ if ( IfStmt.opt_else._repeat_stmt ) {
+ send Out
+ "else
+ " [rw_ruby_stmt_list( IfStmt.opt_else._repeat_stmt )]
+ }
+ send Out
+ "end
+}
+
+int rw_ruby_print_stmt( Stmt: indep::print_stmt )
+{
+ if match Stmt [`print_int expr `;] {
+ send Out
+ "print( [rw_ruby_expr(Stmt.expr)] );
+ }
+ else if match Stmt [`print_buf E1: expr `, E2: expr `;]
+ {
+ send Out
+ "_a = [rw_ruby_expr(E1)] \[0..pos-1\] ;
+ "print( _a.pack( \"c*\" ) );
+ }
+ else if match Stmt [`print_str expr `;]
+ {
+ send Out
+ "print( [rw_ruby_expr( Stmt.expr )] );
+ }
+ else if match Stmt [`print_token `;]
+ {
+ send Out
+ "_m = data\[ts..te-1\];
+ "print( _m );
+ }
+}
+
+int rw_ruby_ragel_stmt( Stmt: indep::ragel_stmt )
+{
+ send Out
+ [$Stmt]
+}
+
+void rw_ruby_buf_stmt( BufStmt: indep::buf_stmt )
+{
+ switch BufStmt
+ case [`buf_clear `( `) `;] {
+ send Out
+ " blen = 0;
+ }
+ case [`buf_append `( `) `;] {
+ send Out
+ " buffer\[blen\] = fc;
+ " blen += 1;
+ }
+}
+
+int rw_ruby_stmt( Stmt: indep::stmt )
+{
+ switch Stmt
+ case [var_decl]
+ rw_ruby_var_decl( Stmt.var_decl )
+ case [expr_stmt]
+ rw_ruby_expr_stmt( Stmt.expr_stmt )
+ case [if_stmt]
+ rw_ruby_if_stmt( Stmt.if_stmt )
+ case [print_stmt]
+ rw_ruby_print_stmt( Stmt.print_stmt )
+ case [buf_stmt]
+ rw_ruby_buf_stmt( Stmt.buf_stmt )
+ case [ragel_stmt]
+ rw_ruby_ragel_stmt( Stmt.ragel_stmt )
+}
+
+void rw_ruby_stmt_list( StmtList: indep::stmt* )
+{
+ for Stmt: indep::stmt in repeat( StmtList )
+ rw_ruby_stmt( Stmt )
+}
+
+int rw_ruby_action_block( ActionBlock: indep::action_block )
+{
+ Out = new parser<out_code::lines>()
+ if match ActionBlock [`{ stmt* `}] {
+ send Out
+ "{[rw_ruby_stmt_list( ActionBlock._repeat_stmt )]}
+ }
+ else if match ActionBlock [`{ expr `}] {
+ send Out
+ "{[rw_ruby_expr( ActionBlock.expr )]}
+ }
+ send Out [] eos
+}
+
+void rw_ruby( Output: stream )
+{
+ Section: indep::section = RagelTree.section
+
+ # Lowercase the machine name
+ for MachineName: ragel::machine_name in Section {
+ for Word: ragel::word in MachineName {
+ Word.data = tolower( Word.data )
+ }
+ }
+
+ MachineName = ragel::machine_name in Section
+
+ # Rewrite the action blocks.
+ 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)
+ }
+
+ rw_ruby_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: ruby
+ "# @GENERATED: true
+
+ if ProhibitGenflags {
+ send Output
+ "# @PROHIBIT_GENFLAGS:[ProhibitGenflags]
+ }
+
+ send Output
+ "#
+ "
+
+ send Output
+ "
+ "[@Section]
+ "
+ "%% write data;
+ "
+ "def run_machine( data )
+ " p = 0
+ " pe = data.length
+ " eof = data.length
+ " cs = 0;
+ " _m = ""
+ " _a = ""
+ " buffer = Array.new
+ " blen = 0
+
+ Init: indep::stmt* = RagelTree.Init
+ for Stmt: indep::stmt in Init {
+ if match Stmt [Decl: var_decl] {
+ Out = new parser<out_code::lines>()
+ rw_ruby_var_decl( Decl )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ for Stmt: indep::stmt in Init {
+ if match Stmt [ExprStmt: expr_stmt] {
+ Out = new parser<out_code::lines>()
+ rw_ruby_expr_stmt( ExprStmt )
+ send Out [] eos
+ send Output [Out->tree]
+ }
+ }
+
+ send Output
+ " %% write init;
+ " %% write exec;
+ " if cs >= [MachineName.word]_first_final
+ " puts \"ACCEPT\"
+ " else
+ " puts \"FAIL\"
+ " end
+ "end
+ "
+
+ send Output
+ "inp = \[
+
+ NR: int = 0
+ for InputString: indep::input_string in RagelTree {
+ send Output
+ [^InputString ",\n"]
+ NR = NR + 1
+ }
+
+ send Output
+ "\]
+ "
+
+ send Output
+ "inplen = [NR]
+ "
+
+ send Output
+ "inp.each { |str| run_machine(str) }
+ "
+}
diff --git a/test/trans.d/trans-rust.lm b/test/trans.d/trans-rust.lm
new file mode 100644
index 00000000..b75f672b
--- /dev/null
+++ b/test/trans.d/trans-rust.lm
@@ -0,0 +1,344 @@
+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<out_code::lines>()
+ 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<out_code::lines>()
+ 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<out_code::lines>()
+ 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
diff --git a/test/trans.d/trans.lm b/test/trans.d/trans.lm
new file mode 100644
index 00000000..b9fa5870
--- /dev/null
+++ b/test/trans.d/trans.lm
@@ -0,0 +1,366 @@
+include 'ragel.lm'
+include 'ragel-c.lm'
+include 'ragel-ocaml.lm'
+include 'ragel-ruby.lm'
+include 'ragel-crack.lm'
+
+namespace indep
+ # Opening the test case header.
+ lex
+ ignore / ( [ \t] | NL )+ /
+
+ token c_comm_open
+ / '/*' /
+ end
+
+ # Contents of test case heaer.
+ lex
+ token comm_name /'@' [A-Za-z0-9_]+ ':' /
+ token comm_term /'*/'/
+ token comm_any / any /
+ end
+
+ token comm_val /[^\n]* '\n' /
+
+ lex
+ literal `%%{ `}%%
+
+ literal `int `bool `char `ptr `byte `if `else
+ `print_int `print_buf `print_str `print_token
+ `first_token_char `buffer `blen `buf_append `buf_clear
+
+ literal `fpc `fc `fcurs `ftargs `fentry
+ `fhold `fexec `fgoto `fnext `fcall
+ `fret `fbreak `fncall `fnret `fnbreak
+
+ literal `; `< `> `( `) `[ `] `=
+ `* `! `{ `} `+ `- `== `!=
+ `>= `<= `,
+
+ ignore / ( [ \t] | NL )+ /
+
+ token tk_ident /ident/
+ token tk_number /digit+/
+ token tk_hex_number /'0x' [0-9a-fA-F]+/
+
+ rl INPUT /'INPUT'/
+ rl OUTPUT /'OUTPUT'/
+
+ token sect_INPUT
+ / '#'+ ' '* INPUT ' '* '#'+ '\n' /
+
+ token sect_OUTPUT
+ / '#'+ ' '* OUTPUT ' '* '#'+ '\n' / -ni
+
+ token string
+ / s_literal | d_literal /
+
+ ignore / cpp_comment /
+ ignore / c_comment /
+ end
+
+ lex
+ token output_line /[^\n]* '\n'/
+ end
+
+ def comm_def
+ [comm_name comm_val]
+
+ def comm_item
+ [comm_def]
+ | [comm_any]
+
+ def test_header
+ [c_comm_open comm_item* comm_term]
+
+ def input_string
+ [string]
+
+ def input_list
+ [input_list input_string]
+ | [input_string]
+
+ def input
+ [input_list]
+
+ def output
+ [output_line*]
+
+ def factor
+ [`first_token_char]
+ | [`buffer]
+ | [`blen]
+ | [tk_ident]
+ | [tk_ident `[ expr `]]
+ | [tk_ident `( expr `)]
+ | [tk_number]
+ | [`- tk_number]
+ | [tk_hex_number]
+ | [string]
+ | [`< type `> `( expr `)]
+ | [`( expr `)]
+ | [ragel_factor]
+
+ def ragel_factor
+ [`fentry `( expr `)]
+ | [`fc]
+ | [`fcurs]
+ | [`ftargs]
+
+ def mult_op
+ [`*]
+
+ def add_op
+ [`+]
+ | [`-]
+
+ def cmp_op
+ [`<]
+ | [`>]
+ | [`!=]
+ | [`==]
+ | [`<=]
+ | [`>=]
+
+ def abs_op
+ [mult_op]
+ | [add_op]
+ | [cmp_op]
+
+ abs_expr abs_multiplicative( Expr: indep::multiplicative )
+ {
+ if ( !Expr.Op ) {
+ return cons abs_expr [Expr.factor]
+ }
+ else {
+ return cons abs_expr [
+ abs_multiplicative( Expr._multiplicative )
+ @Expr.Op
+ Expr.factor
+ ]
+ }
+ }
+
+ abs_expr abs_additive( Expr: indep::additive )
+ {
+ if ( !Expr.Op ) {
+ return cons abs_expr [
+ abs_multiplicative( Expr.multiplicative )
+ ]
+ }
+ else {
+ return cons abs_expr [
+ abs_additive( Expr._additive )
+ @Expr.Op
+ abs_multiplicative( Expr.multiplicative )
+ ]
+ }
+ }
+
+ abs_expr abs_comparative( Expr: indep::comparative )
+ {
+ if ( !Expr.Op ) {
+ return cons abs_expr [
+ abs_additive( Expr.additive )
+ ]
+ }
+ else {
+ return cons abs_expr [
+ abs_comparative( Expr._comparative )
+ @Expr.Op
+ abs_additive( Expr.additive )
+ ]
+ }
+ }
+
+ def multiplicative
+ [multiplicative Op: mult_op factor]
+ | [factor]
+
+ def additive
+ [additive Op: add_op multiplicative]
+ | [multiplicative]
+
+ def comparative
+ [comparative Op: cmp_op additive]
+ | [additive]
+
+ def abs_expr
+ [E1: abs_expr Op: abs_op E2: abs_expr]
+ | [factor]
+
+ def expr
+ [comparative]
+
+ def type
+ [`int]
+ | [`bool]
+ | [`char]
+ | [`ptr]
+ | [`byte]
+
+ def opt_arr
+ [`[ expr `]]
+ | []
+
+ def var_decl
+ [type tk_ident opt_arr `;]
+
+ def opt_sub
+ [ `[ expr `] ]
+ | []
+
+ def expr_stmt
+ [tk_ident opt_sub `= expr `;]
+ | [expr `;]
+
+ def if_stmt
+ [`if `( expr `) `{ stmt* `} opt_else]
+
+ def opt_else
+ [`else `{ stmt* `}]
+ | []
+
+ def print_stmt
+ [`print_int expr `;]
+ | [`print_buf expr `, expr `;]
+ | [`print_str expr `;]
+ | [`print_token `;]
+
+ def ragel_stmt
+ [`fgoto tk_ident `;]
+ | [`fcall tk_ident `;]
+ | [`fncall tk_ident `;]
+ | [`fnext tk_ident `;]
+ | [`fgoto `* expr `;]
+ | [`fcall `* expr `;]
+ | [`fncall `* expr `;]
+ | [`fnext `* expr `;]
+ | [`fexec expr `;]
+ | [`fhold `;]
+ | [`fbreak `;]
+ | [`fnbreak `;]
+ | [`fret `;]
+ | [`fnret `;]
+
+ def buf_stmt
+ [`buf_append `( `) `;]
+ | [`buf_clear `( `) `;]
+
+ def stmt
+ [var_decl]
+ | [expr_stmt]
+ | [if_stmt]
+ | [print_stmt]
+ | [buf_stmt]
+ | [ragel_stmt]
+
+ def action_block
+ [`{ stmt* `}]
+ | [`{ expr `}]
+
+ def section
+ [`%%{ ragel::ragel_start `}%%]
+
+ def start
+ [
+ test_header
+ Init: stmt*
+ section
+ sect_INPUT
+ input
+ sect_OUTPUT
+ output
+ ]
+end
+
+namespace out_code
+ lex
+ token line
+ /[^\n]* '\n'/
+ end
+
+ def lines
+ [line*]
+
+ alias line_parser
+ parser<lines>
+end
+
+global Out: parser<out_code::lines>
+
+include 'trans-c.lm'
+include 'trans-asm.lm'
+include 'trans-d.lm'
+include 'trans-csharp.lm'
+include 'trans-go.lm'
+include 'trans-java.lm'
+include 'trans-ruby.lm'
+include 'trans-ocaml.lm'
+include 'trans-rust.lm'
+include 'trans-julia.lm'
+include 'trans-crack.lm'
+
+str argvPop()
+{
+ AE: list_el<str> = argv->pop_el()
+ return AE->value
+}
+
+Lang: str = argvPop()
+OutputFile: str = argvPop()
+InputFile: str = argvPop()
+global ClassName: str = argvPop()
+
+Input: stream = open( InputFile, "r" )
+Output: stream = open( OutputFile, "w" )
+
+global RagelTree: indep::start = parse indep::start[ Input ]
+
+if ( !RagelTree ) {
+ print( error, '\n' )
+ exit(1)
+}
+
+# Find the machine name.
+global MachineName: ragel::machine_name = ragel::machine_name in RagelTree
+
+global NeedsEof: bool = false
+global ProhibitGenflags: str
+for CommDef: indep::comm_def in RagelTree {
+ switch CommDef
+ case "@NEEDS_EOF: yes\n"
+ {
+ NeedsEof = true
+ }
+ case "@PROHIBIT_GENFLAGS:[CV: comm_val]"
+ {
+ ProhibitGenflags = $CV
+ }
+}
+
+if ( Lang == 'c' )
+ rw_c( Output )
+elsif ( Lang == 'asm' )
+ rw_asm( Output )
+elsif ( Lang == 'd' )
+ rw_d( Output )
+elsif ( Lang == 'cs' )
+ rw_csharp( Output )
+elsif ( Lang == 'go' )
+ rw_go( Output )
+elsif ( Lang == 'java' )
+ rw_java( Output )
+elsif ( Lang == 'ruby' )
+ rw_ruby( Output )
+elsif ( Lang == 'ocaml' )
+ rw_ocaml( Output )
+elsif ( Lang == 'rust' )
+ trans_rust::rust( Output )
+elsif ( Lang == 'julia' )
+ trans_julia::julia( Output )
+elsif ( Lang == 'crack' )
+ trans_crack::crack( Output )
+else {
+ print( 'trans: unrecognized language: ', Lang, '\n' )
+}