include 'ril.lm' namespace julia_out token _IN_ /''/ token _EX_ /''/ lex token comment / '//' any* :> '\n' | '/*' any* :>> '*/' / literal `function `end `while `if `else `elseif token id /[a-zA-Z_][a-zA-Z_0-9]*/ token number / [0-9]+ / token symbol / '!' | '#' | '$' | '%' | '&' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | '[' | ']' | '^' | '|' | '~' / literal `{ `} token string / '"' ( [^"\\] | '\\' any ) * '"' | "'" ( [^'\\] | '\\' any ) * "'" / ignore /[ \t\v\r\n]+/ end def kw [`function _IN_] | [`while _IN_] | [`if _IN_] | [_EX_ `elseif _IN_] | [_EX_ `else _IN_] | [_EX_ `end] def item [comment] | [kw] | [id] | [number] | [symbol] | [string] | [`{ _IN_ item* _EX_ `} ] def julia_out [_IN_ _EX_ item*] end namespace julia_gen global Parser: parser 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::`}=] { send Parser "([expr( Expr )])" } case [E: escape] { Str: str = $E send Parser "[Str.suffix( 1 )]" } default { send Parser [Tok] } } } void embedded_host( EmbeddedHost: embedded_host ) { switch EmbeddedHost case [`host `( string `, uint `) `={ TL: host::tok* host::`}=] { send Parser "([tok_list( TL )])" } case [`host `( string `, uint `) `${ TL: host::tok* host::`}$] { send Parser [tok_list( TL )] } 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 [`( E: expr `)] { send Parser "([expr(E)])" } case [I: ident `[ E: expr `]] { send Parser "[I]\[1+([expr( E )])\]" } case [`offset `( Base: ident `, Offset: expr `)] { send Parser [expr( Offset )] } case [`deref `( Base: expr `, Offset: expr `)] { send Parser "[expr( Base )]\[1+([ expr( Offset ) ])\]" } case [`TRUE] { send Parser "true" } case [`FALSE] { send Parser "false" } case [N: `nil] { send Parser "0" } case [Number: number] { number( Number ) } case [E1: embedded_host `-> E2: expr_factor] { # The accessor operator is contained wihtin the lhs. embedded_host( E1 ) expr_factor( E2 ) } case [`cast `( T: type `) F: expr_factor] { send Parser "convert([type( T )], [expr_factor( F )] )" } case [I: ident `[ E: expr `] `. F: ident] { send Parser [^I '_' ^F '[1+(' expr(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 [I: ident `[ E: expr `]] { send Parser "[I]\[1+([expr( E )])\]" } case [E1: embedded_host `-> E2: lvalue] { # The accessor operator is contained wihtin the lhs. embedded_host( E1 ) lvalue( E2 ) } case [I: ident `[ E: expr `] `. F: ident] { send Parser [^I '_' ^F '[1+(' expr(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 ['Int8'] case "u8" send Parser ['UInt8'] case "s16" send Parser ['Int16'] case "s32" send Parser ['Int32'] case "s64" send Parser ['Int64'] case "s128" send Parser ['Int128'] case "uint" send Parser ['UInt'] case "int" send Parser ['Int'] default send Parser [Type] } void number( Number: number ) { switch Number case [`u `( uint `) ] send Parser "[Number.uint]u" default send Parser [Number] } void num_list( NumList: num_list ) { for Number: number in NumList send Parser "[number( Number )], " } void stmt( Stmt: stmt ) { switch Stmt case [EH: embedded_host] { send Parser [embedded_host( EH )] } case [A: static_array] { send Parser "const [A.ident] = [type(A.type)]\[[num_list(A.num_list)]\] } case [V: static_value] { send Parser "const [V.ident] = [V.number] } # case [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 [ `if `( IfExpr: expr `) 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 "elseif [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* `}] { require StmtList [`case E1: expr `{ Inner: stmt* `} Rest: stmt*] send Parser "if [expr(SwitchExpr)] == [expr(E1)] " [stmt_list(Inner)] for S: stmt in repeat(Rest) { switch S case [`case E1: expr `{ Inner: stmt* `}] { send Parser "elseif [expr(SwitchExpr)] == [expr(E1)] " [stmt_list(Inner)] } case [`default `{ Inner: stmt* `}] { send Parser "else " [stmt_list(Inner)] } } send Parser "end } case [ExprExpr: expr Semi: `;] { send Parser [expr(ExprExpr)] } case [L: `{ TL: stmt* R: `}] { send Parser [stmt_list(TL)] } case [ TypeList: opt_const Type: type Ident: ident OptInit: opt_init Semi: `; ] { send Parser [TypeList type(Type) Ident] if match OptInit [E: `= expr] { send Parser [E expr(OptInit.expr)] } send Parser "; } case [Export: export_stmt] { send Parser "#define [Export.ident] [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 "@case [expr( Stmt.case_block.expr )] begin "[stmt_list( Stmt.case_block._repeat_stmt )] "end } case [default_block] { send Parser "default: "[stmt_list( Stmt.default_block._repeat_stmt )] "break; } case [case_label] { send Parser "@case [expr( Stmt.case_label.expr )] } case [L: goto_label] { send Parser "@label [L.ident] } case [G: goto_stmt] { send Parser "@goto [G.ident] } case [AS: assign_stmt] { send Parser "[lvalue(AS.LValue) AS.assign_op expr(AS.expr)] } default { # catches unspecified cases send Parser "[Stmt] } } void stmt_list( StmtList: stmt* ) { for Stmt: stmt in repeat( StmtList ) stmt( Stmt ) } void trans( Output: stream, Start: start ) { Parser = new parser() if ( Start.opt_bom.bom ) send Output [Start.opt_bom.bom] stmt_list( Start._repeat_stmt ) CO: julia_out::julia_out = Parser->finish() if CO { send Output [CO] } else { send stderr "failed to parse output: [Parser->error] } } end void trans( Output: stream, Start: start ) { julia_gen::trans( Output, Start ) } include 'rlhc-main.lm'