include 'ril.lm' namespace c_out token _IN_ /''/ token _EX_ /''/ lex token comment / '//' any* :> '\n' | '/*' any* :>> '*/' / 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 item [comment] | [id] | [number] | [symbol] | [string] | [`{ _IN_ item* _EX_ `} ] def c_out [_IN_ _EX_ item*] end namespace c_gen global _: parser void tok_list( TL: host::tok* ) { for Tok: host::tok in repeat(TL) { switch Tok case Stmt { << "{ " [stmt_list( StmtList )] "} } case Expr { << "([expr( Expr )])" } case Escape { Str: str = $escape << "[Str.suffix( 1 )]" } default { << [Tok] } } } void embedded_host( EmbeddedHost: embedded_host ) { switch EmbeddedHost case Expr { << "([tok_list( TL )])" } case Stmt { << "{ " [tok_list( TL )] "} } case Bare { << [tok_list( TL )] } } void expr_factor( ExprFactor: expr_factor ) { switch ExprFactor case [EH: embedded_host] { << [embedded_host( EH )] } case Paren { << "([expr( expr )])" } case ArraySub { << "[ident]\[[expr( expr )]\]" } case ArraySubField { << "[ident]\[[expr( expr )]\].[Field]" } case Offset { << "[base] + [expr( expr )]" } case Deref { << "(*( [expr(expr)] )) } case True { << "1" } case False { << "1" } case Nil { << "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] { << "( [type( T )] ) [expr_factor( F )]" } default { # Catches cases not specified << [ExprFactor] } } void lvalue( ExprFactor: lvalue ) { switch ExprFactor case [EH: embedded_host] { << [embedded_host( EH )] } case [ident O: `[ TL: expr C: `]] { << [ident O expr( TL ) C] } case [I: ident `[ E: expr `] `. F: ident] { << "[I]\[[ expr( E )]\].[F] } case [E1: embedded_host `-> E2: lvalue] { # The accessor operator is contained wihtin the lhs. embedded_host( E1 ) lvalue( E2 ) } default { # Catches cases not specified << [ExprFactor] } } void expr_factor_op( ExprFactorOp: expr_factor_op ) { switch ExprFactorOp case [B: `! expr_factor_op] { << ['!' expr_factor_op( _expr_factor_op )] } case [T: `~ expr_factor_op] { << ['~' expr_factor_op( _expr_factor_op )] } case [expr_factor] { << [expr_factor( expr_factor )] } } void expr_bitwise( ExprBitwise: expr_bitwise ) { switch ExprBitwise case [expr_bitwise A: `& expr_factor_op] { << [expr_bitwise( _expr_bitwise ) A expr_factor_op( expr_factor_op )] } case [expr_factor_op] { << [expr_factor_op( expr_factor_op )] } } void expr_mult( ExprMult: expr_mult ) { switch ExprMult case [expr_mult T: `* expr_bitwise] { << [expr_mult( _expr_mult ) T expr_bitwise( expr_bitwise )] } case [expr_bitwise] { << [expr_bitwise( expr_bitwise )] } } void expr_add( ExprAdd: expr_add ) { switch ExprAdd case [expr_add Op: add_op expr_mult] { << [expr_add( _expr_add ) Op expr_mult( expr_mult )] } case [expr_mult] { << [expr_mult( expr_mult )] } } void expr_shift( ExprShift: expr_shift ) { switch ExprShift case [expr_shift Op: shift_op expr_add] { << [expr_shift( _expr_shift ) Op expr_add( expr_add )] } case [expr_add] { << [expr_add( expr_add )] } } void expr_test( ExprTest: expr_test ) { switch ExprTest case [expr_test Op: test_op expr_shift] { << [expr_test( _expr_test ) Op expr_shift( expr_shift )] } case [expr_shift] { << [expr_shift( expr_shift )] } } void expr( Expr: expr ) { expr_test( Expr.expr_test ) } void type( Type: type ) { switch Type case S8 << ['signed char '] case S16 << ['short '] case S32 << ['int '] case S64 << ['long '] case S128 << ['long long '] case "uint" << ['unsigned int '] default << [Type] } void number( Number: number ) { switch Number case Unsigned << "[uint]u" default << [Number] } void num_list( NumList: num_list ) { for Number: number in NumList << "[number( Number )], " } void stmt( Stmt: stmt ) { switch Stmt case [EH: embedded_host] { << [embedded_host( EH )] } case [A: static_array] { << "static const [type(A.type)] " "[A.ident] \[\] = { [num_list(A.num_list)] }; } case [V: static_value] { << "static const [V.type] [V.ident] = [V.number]; } case [ `if `( IfExpr: expr `) IfStmt: stmt ElseIfClauseList: else_if_clause* ElseClauseOpt: else_clause? ] { << "if ( [expr(IfExpr)] ) << " [stmt(IfStmt)] for ElseIfClause: else_if_clause in repeat( ElseIfClauseList ) { match ElseIfClause [`else `if `( ElseIfExpr: expr `) ElseIfStmt: stmt] << "else if ( [expr(ElseIfExpr)] ) " [stmt(ElseIfStmt)] } if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { << "else << " [stmt(ElseStmt)] } } case [`while `( WhileExpr: expr `) WhileStmt: stmt] { << "while ( [expr(WhileExpr)] ) " [stmt(WhileStmt)] } case [M: match_stmt] { << "switch ( [expr(M.E)] ) { for PB: pat_block in repeat( M.P ) { << "case [expr( PB.expr )]: "[stmt_list( PB._repeat_stmt )] "break; } if match M.D [D: default_block] { << "default: "[stmt_list( D._repeat_stmt )] "break; } << "} } case [`switch `( SwitchExpr: expr `) `{ StmtList: stmt* `}] { << "switch ( [expr(SwitchExpr)] ) { " [stmt_list(StmtList)] "} } case [ES: expr_stmt] { << "[expr(ES.expr)]; } case [B: block] { << "{ " [stmt_list(B.StmtList)] "} } case [ OptConst: opt_const Type: type Ident: ident OptInit: opt_init Semi: `; ] { << "[OptConst] [type(Type)] [Ident]" if match OptInit [`= Init: expr] { << " = [expr(Init)] } << "; } case [Export: export_stmt] { << "#define [Export.ident] [number(Export.number)] } case [fallthrough] { # Nothing needed here. # C falls through by default. } case [Index: index_stmt] { << "const [type(Index.type)] *[Index.ident] if match Index.opt_init [E: `= expr] { << [E expr(Index.opt_init.expr)] } << "; } case [CB: case_block] { << "case [expr( CB.expr )]: "[stmt_list( CB._repeat_stmt )] "break; } case [DB: default_block] { << "default: "[stmt_list( DB._repeat_stmt )] "break; } case [CL: case_label] { << "case [expr( CL.expr )]: } case [AS: assign_stmt] { << "[lvalue(AS.LValue) AS.assign_op expr(AS.expr)]; } default { # catches unspecified cases << [Stmt] } } void stmt_list( StmtList: stmt* ) { for Stmt: stmt in repeat( StmtList ) stmt( Stmt ) } void trans( Output: stream, Start: start ) { _ = new parser() if ( Start.opt_bom.bom ) send Output [Start.opt_bom.bom] stmt_list( Start._repeat_stmt ) CO: c_out::c_out = _->finish() if CO { send Output [CO] } else { send stderr "failed to parse output: [_->error] } } end void trans( Output: stream, Start: start ) { c_gen::trans( Output, Start ) } include 'rlhc-main.lm'