diff options
Diffstat (limited to 'ragel/rlhc-ruby.lm')
-rw-r--r-- | ragel/rlhc-ruby.lm | 527 |
1 files changed, 527 insertions, 0 deletions
diff --git a/ragel/rlhc-ruby.lm b/ragel/rlhc-ruby.lm new file mode 100644 index 00000000..87119465 --- /dev/null +++ b/ragel/rlhc-ruby.lm @@ -0,0 +1,527 @@ +include 'ril.lm' + +namespace ruby_out + token _IN_ /''/ + token _EX_ /''/ + + lex + token comment / + '#' any* :> '\n' + / + + literal `def `class `begin `end `while `if + + token id + /[a-zA-Z_][a-zA-Z_0-9]*/ + + token number / + [0-9]+ + / + + token string / + '"' ( [^"\\] | '\\' any ) * '"' | + "'" ( [^'\\] | '\\' any ) * "'" | + "/" ( [^/\\] | '\\' any ) * "/" + / + + token symbol / + '!' | '#' | '$' | '%' | '&' | '(' | ')' | '*' | + '+' | ',' | '-' | '.' | '/' | ':' | ';' | '<' | + '=' | '>' | '?' | '@' | '[' | ']' | '^' | '|' | + '~' | '{' | '}' | '\\' / + + ignore + /[ \t\v\r\n]+/ + end + + def item + [comment] + | [id] + | [number] + | [symbol] + | [string] + | [`begin _IN_] + | [`class _IN_] + | [`while _IN_] + | [`if _IN_] + | [`def _IN_] + | [_EX_ `end] + + def ruby_out + [_IN_ _EX_ item*] +end + +global Parser: parser<ruby_out::ruby_out> + +void tok_list( TL: host::tok* ) +{ + for Tok: host::tok in repeat(TL) { + switch Tok + case [host::`${ StmtList: stmt* host::`}$] + { + send Parser + "begin + "[stmt_list( StmtList )] + "end + } + case [host::`={ Expr: expr host::`}=] + expr( Expr ) + case [E: escape] { + Str: str = $E + send Parser + "[Str.suffix( 1 )]" + } + default { + send Parser [Tok] + } + } +} + +void embedded_host( EH: embedded_host ) +{ + switch EH + case [`host `( string `, uint `) `={ TL: host::tok* host::`}=] + { + send Parser + "([tok_list( TL )])" + } + case [`host `( string `, uint `) `${ TL: host::tok* host::`}$] + { + send Parser + "begin + " [tok_list( TL )] + "end + } + case [`host `( string `, uint `) `@{ TL: host::tok* host::`}@] + { + send Parser + [tok_list( TL )] + } +} + +void expr_factor( ExprFactor: expr_factor ) +{ + switch ExprFactor + case [EH: embedded_host] + { + send Parser + [embedded_host( EH )] + } + case [O:`( TL: expr C: `)] + { + send Parser + [O expr(TL) C] + } + case [ident O: `[ TL: expr C: `]] + { + send Parser + [ExprFactor.ident O expr( TL ) C] + } + case ['offset' '(' ident ',' expr ')'] + { + send Parser + [expr( ExprFactor.expr )] + } + case ['deref' '(' ident ',' expr ')'] + { + send Parser + [ ExprFactor.ident '[' expr( ExprFactor.expr ) ']'] + if $ExprFactor.ident == 'data' + send Parser '.ord' + } + case [T: `TRUE] + { + T.data = 'true' + send Parser [T] + } + case [F: `FALSE] + { + F.data = 'false' + send Parser [F] + } + case [N: `nil] + { + N.data = '0' + send Parser [N] + } + case [Number: number] + { + ruby_number( Number ) + } + case [E1: embedded_host `-> E2: expr_factor] + { + embedded_host( E1 ) + expr_factor( E2 ) + } + case [`cast Open: `( Type: type Close: `) expr_factor] + { + #send Parser [Open] + #type( Type ) + #send Parser [Close] + expr_factor( ExprFactor._expr_factor ) + } + case [I: ident `[ E: expr `] `. F: ident] { + send Parser + [^I '_' ^F '[' E ']'] + } + default { + # Catches cases not specified + send Parser [ExprFactor] + } +} + +void lvalue( ExprFactor: lvalue ) +{ + switch ExprFactor + case [EH: embedded_host] + { + send Parser + [embedded_host( EH )] + } + case [ident O: `[ TL: expr C: `]] + { + send Parser + [ExprFactor.ident O expr( TL ) C] + } + case [E1: embedded_host `-> E2: lvalue] + { + embedded_host( E1 ) + lvalue( E2 ) + } + case [I: ident `[ E: expr `] `. F: ident] { + send Parser + [^I '_' ^F '[' E ']'] + } + default { + # Catches cases not specified + send Parser [ExprFactor] + } +} + +void expr_factor_op( ExprFactorOp: expr_factor_op ) +{ + switch ExprFactorOp + case [B: `! expr_factor_op] + { + send Parser [B] + expr_factor_op( ExprFactorOp._expr_factor_op ) + } + case [T: `~ expr_factor_op] + { + send Parser [T] + expr_factor_op( ExprFactorOp._expr_factor_op ) + } + case [expr_factor] + { + expr_factor( ExprFactorOp.expr_factor ) + } +} + +void expr_bitwise( ExprBitwise: expr_bitwise ) +{ + switch ExprBitwise + case [expr_bitwise A: `& expr_factor_op] + { + expr_bitwise( ExprBitwise._expr_bitwise ) + send Parser [A] + expr_factor_op( ExprBitwise.expr_factor_op ) + } + case [expr_factor_op] + { + expr_factor_op( ExprBitwise.expr_factor_op ) + } +} + +void expr_mult( ExprMult: expr_mult ) +{ + switch ExprMult + case [expr_mult T: `* expr_bitwise] + { + expr_mult( ExprMult._expr_mult ) + send Parser [T] + expr_bitwise( ExprMult.expr_bitwise ) + } + case [expr_bitwise] + { + expr_bitwise( ExprMult.expr_bitwise ) + } +} + +void expr_add( ExprAdd: expr_add ) +{ + switch ExprAdd + case [expr_add Op: add_op expr_mult] + { + expr_add( ExprAdd._expr_add ) + send Parser [Op] + expr_mult( ExprAdd.expr_mult ) + } + case [expr_mult] + { + expr_mult( ExprAdd.expr_mult ) + } +} + +void expr_shift( ExprShift: expr_shift ) +{ + switch ExprShift + case [expr_shift Op: shift_op expr_add] + { + expr_shift( ExprShift._expr_shift ) + send Parser [Op] + expr_add( ExprShift.expr_add ) + } + case [expr_add] + { + expr_add( ExprShift.expr_add ) + } +} + +void expr_test( ExprTest: expr_test ) +{ + switch ExprTest + case [expr_test Op: test_op expr_shift] + { + expr_test( ExprTest._expr_test ) + send Parser [Op] + expr_shift( ExprTest.expr_shift ) + } + case [expr_shift] + { + expr_shift( ExprTest.expr_shift ) + } +} + +void expr( Expr: expr ) +{ + expr_test( Expr.expr_test ) +} + +void type( Type: type ) +{ + switch Type + case "s8" + send Parser ['byte '] + case "s16" + send Parser ['short '] + case "s32" + send Parser ['int '] + case "s64" + send Parser ['long '] + case "s128" + send Parser ['long long '] + case "uint" + send Parser ['int '] + default + send Parser [Type] +} + +void ruby_number( Number: number ) +{ + switch Number + case [`u `( uint `) ] + send Parser "[Number.uint]" + default + send Parser [Number] +} + +void ruby_num_list( NumList: num_list ) +{ + for Number: number in NumList + send Parser "[ruby_number( Number )], " +} + +void stmt( Stmt: stmt ) +{ + switch Stmt + case [EH: embedded_host] + { + send Parser + [embedded_host( EH )] + } + case [A: static_array] { + send Parser + "class << self + " attr_accessor :[ A.ident ] + " private :[ A.ident ], :[ A.ident ]= + "end + "self.[ A.ident ] = \[ + " [ruby_num_list( A.num_list )] + "\] + " + } + case [V: static_value] { + send Parser + "class << self + " attr_accessor :[ V.ident ] + "end + "self.[ V.ident ] = [ V.number ]; + " + } + case [ + 'if' O: `( IfExpr: expr C: `) IfStmt: stmt + ElseIfClauseList: else_if_clause* ElseClauseOpt: else_clause? + ] { + send Parser + "if ( [expr(IfExpr)] ) + " [stmt(IfStmt)] + + for ElseIfClause: else_if_clause in repeat( ElseIfClauseList ) { + match ElseIfClause + ['else if (' ElseIfExpr: expr ')' ElseIfStmt: stmt] + + send Parser + "elsif ( [expr(ElseIfExpr)] ) + " [stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else + " [stmt(ElseStmt)] + } + send Parser + "end + } + case ['while' '(' WhileExpr: expr ')' WhileStmt: stmt] { + send Parser + "while ( [expr(WhileExpr)] ) + " [stmt(WhileStmt)] + "end + } + case ['switch' '(' SwitchExpr: expr ')' '{' StmtList: stmt* '}'] { + send Parser + "case [expr(SwitchExpr)] + "when -2 then + "begin + " [stmt_list(StmtList)] + "end + "end + } + case [ExprExpr: expr Semi: `;] { + send Parser + [expr(ExprExpr) Semi] + } + case [L: `{ TL: stmt* R: `}] { + send Parser + "begin + "[stmt_list(TL)] + "end + } + # [declaration] + case [ + TypeList: opt_const Type: type + Ident: ident OptInit: opt_init Semi: `; + ] + { + send Parser + [Ident] + + if match OptInit [E: `= expr] { + send Parser + [E expr(OptInit.expr)] + } + else { + send Parser + "= 0 + } + + send Parser + [Semi] + } + case [Export: export_stmt] + { + send Parser + "class << self + " attr_accessor :[ Export.ident ] + "end + "self.[ Export.ident ] = [ ruby_number(Export.number) ]; + " + } + case ['fallthrough' ';'] + { + # Nothing needed here. + } + case [Index: index_stmt] + { + send Parser + "[Index.ident]" + + if match Index.opt_init [E: `= expr] { + send Parser + [E expr(Index.opt_init.expr)] + } + else { + send Parser + "= 0 + } + + send Parser "; + } + case [case_block] + { + send Parser + "end + "when [expr( Stmt.case_block.expr )] then + "begin + "[stmt_list( Stmt.case_block._repeat_stmt )] + } + case [default_block] + { + send Parser + "end + "else + "begin + "[stmt_list( Stmt.default_block._repeat_stmt )] + } + case [goto_label] {} + case [goto_stmt] {} + case [AS: assign_stmt] + { + send Parser + "[lvalue(AS.LValue) AS.assign_op expr(AS.expr)]; + } + case [continue_stmt] + { + send Parser + "next; + } + default { + # catches unspecified cases + send Parser [Stmt] + } +} + +void stmt_list( StmtList: stmt* ) +{ + for Stmt: stmt in repeat( StmtList ) + stmt( Stmt ) +} + +void ruby_trans( Output: stream, Start: start ) +{ + Parser = new parser<ruby_out::ruby_out>() + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + RO: ruby_out::ruby_out = Parser->finish() + + if RO { + send Output + [RO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } +} + +void trans( Output: stream, Start: start ) +{ + ruby_trans( Output, Start ) +} + +include 'rlhc-main.lm' |