diff options
author | Adrian Thurston <thurston@colm.net> | 2017-02-22 15:36:54 +0800 |
---|---|---|
committer | Adrian Thurston <thurston@colm.net> | 2017-02-22 15:36:54 +0800 |
commit | bf4c32ff73537111b7c381f8764cca6fc246b4ba (patch) | |
tree | 9bf2c335c51fe9f717330abd9fe173f50448fa5d /test/rlhc.d/rlhc-go.lm | |
parent | 389a3c8235858395e9885bddafe1fe7da41f898a (diff) | |
download | colm-bf4c32ff73537111b7c381f8764cca6fc246b4ba.tar.gz |
flatteneed test directory
Diffstat (limited to 'test/rlhc.d/rlhc-go.lm')
-rw-r--r-- | test/rlhc.d/rlhc-go.lm | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/test/rlhc.d/rlhc-go.lm b/test/rlhc.d/rlhc-go.lm new file mode 100644 index 00000000..809dd2fd --- /dev/null +++ b/test/rlhc.d/rlhc-go.lm @@ -0,0 +1,491 @@ + +namespace go_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 go_out + [_IN_ _EX_ item*] +end + +namespace go_gen + + global Parser: parser<go_out::go_out> + + void tok_list( TL: host::tok* ) + { + for Tok: host::tok in repeat(TL) { + switch Tok + case [host::`${ StmtList: stmt* host::`}$] + send Parser "{[stmt_list( StmtList )]}" + 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 + [O:`( TL: expr C: `)] + { + send Parser [O] + expr( TL ) + send Parser [C] + } + case + [ident O: `[ TL: expr C: `]] + { + send Parser [ExprFactor.ident O] + expr( TL ) + send Parser [C] + } + case + [`offset `( ident `, expr `)] + { + send Parser ['int('] + expr( ExprFactor.expr ) + send Parser [')'] + } + case + ['deref' '(' ident ',' expr ')'] + { + send Parser [ ExprFactor.ident '['] + expr( ExprFactor.expr ) + send Parser [']'] + } + case + [T: `TRUE] + { + T.data = 'true' + send Parser [T] + } + case + [F: `FALSE] + { + F.data = '0' + send Parser [F] + } + case + [N: `nil] + { + N.data = '0' + send Parser [N] + } + case [E1: embedded_host `-> E2: expr_factor] + { + embedded_host( E1 ) + expr_factor( E2 ) + } + case [`cast '(' Type: type ')' expr_factor] + { + type( Type ) + send Parser ['('] + expr_factor( ExprFactor._expr_factor ) + send Parser [')'] + } + 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 ) + send Parser [C] + } + case [E1: embedded_host `-> E2: lvalue] + { + embedded_host( E1 ) + lvalue( E2 ) + } + 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 ['^'] + 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 "s16" + send Parser ['int16 '] + case "s32" + send Parser ['int32 '] + case "s64" + send Parser ['int64 '] + case "s128" + send Parser ['long long '] + default + send Parser [Type] + } + + void number( Number: number ) + { + switch Number + case [`u `( uint `) ] + send Parser [Number.uint] + default + send Parser [Number] + } + + void num_list( NumList: num_list ) + { + number( NumList.number ) + for CommaNum: comma_num in NumList { + send Parser [', '] + number( CommaNum.number ) + } + } + + void stmt( Stmt: stmt ) + { + switch Stmt + case [EH: embedded_host] + { + send Parser + [embedded_host(EH)] + } + case [A: static_array] { + send Parser + "var [A.ident] \[\] [type(A.type)] = \[\] " + "[type(A.type)] { [num_list(A.num_list)] } + } + case [V: static_value] { + send Parser + "var [V.ident] [type(V.type)] = [V.number] + } + case [ + 'if' O: `( IfExpr: expr C: `) IfStmt: stmt + ] { + # if-statements with only the if clause can go out as an if. + send Parser + "if [expr(IfExpr)] { + " [stmt(IfStmt)] + "} + } + case [ + 'if' O: `( IfExpr: expr C: `) IfStmt: stmt + ElseIfClauseList: else_if_clause* ElseClauseOpt: else_clause? + ] { + # If the if-statement has more than just an if clause it goes out as a switch. + send Parser + "switch { + " case [expr( IfExpr )]: + " [stmt( IfStmt )] + + for ElseIfClause: else_if_clause in repeat( ElseIfClauseList ) { + match ElseIfClause + ['else if (' ElseIfExpr: expr ')' ElseIfStmt: stmt] + + send Parser + "case [expr(ElseIfExpr)]: + " [stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "default: + " [stmt(ElseStmt)] + } + send Parser + "} + } + case ["while ( TRUE )" WhileStmt: stmt] { + send Parser + "for { + " [stmt(WhileStmt)] + "} + } + case ['while' '(' WhileExpr: expr ')' WhileStmt: stmt] { + send Parser + "for [expr(WhileExpr)] { + " [stmt(WhileStmt)] + "} + } + case ['switch' '(' SwitchExpr: expr ')' '{' StmtList: stmt* '}'] { + send Parser + "switch [expr(SwitchExpr)] { + " [stmt_list(StmtList)] + "} + } + case [ExprExpr: expr Semi: `;] { + send Parser + [expr(ExprExpr) Semi] + } + case [L: `{ TL: stmt* R: `}] { + send Parser + [L stmt_list(TL) R] + } + case [D: declaration] + { + send Parser + "var [D.ident] [type(D.type)]" + + if match D.opt_init ['=' Expr: expr] { + send Parser + " = [expr(Expr)]" + } + send Parser ['\n'] + } + case [export_stmt] + { + send Parser + "#define [Stmt.export_stmt.ident] [number(Stmt.export_stmt.number)] + } + case ['fallthrough' ';'] + { + send Parser + "fallthrough + } + case [index_stmt] + { + send Parser + "var [Stmt.index_stmt.ident] int + } + case [case_block] + { + send Parser + "case [expr( Stmt.case_block.expr )]: + "[stmt_list( Stmt.case_block._repeat_stmt )] + "break; + } + 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 [label_stmt] + { + send Parser + "[Stmt.label_stmt.ident]: + "[stmt_list( Stmt.label_stmt._repeat_stmt )] + } + case [entry_loop] + { + send Parser + [stmt_list( Stmt.entry_loop._repeat_stmt )] + } + 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<go_out::go_out>() + + stmt_list( Start._repeat_stmt ) + + GO: go_out::go_out = Parser->finish() + + if GO { + send Output + [GO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } +end |