diff options
author | Adrian Thurston <thurston@colm.net> | 2020-10-18 11:44:43 -0700 |
---|---|---|
committer | Adrian Thurston <thurston@colm.net> | 2020-10-18 11:44:43 -0700 |
commit | 85b76476de71f43d3eb25d6bef4ee6d84cb71f6c (patch) | |
tree | 65c127fbcf70e62d8a4848be2c9c4ff7d74d86a1 /src/cgil | |
parent | 86bb5882a70224a29650ccfa1e46c9b023c2a3ef (diff) | |
download | colm-85b76476de71f43d3eb25d6bef4ee6d84cb71f6c.tar.gz |
lift all source code into src/ dirinto-src
Diffstat (limited to 'src/cgil')
-rw-r--r-- | src/cgil/.gitignore | 2 | ||||
-rw-r--r-- | src/cgil/Makefile.am | 9 | ||||
-rw-r--r-- | src/cgil/ragel.lm | 1027 | ||||
-rw-r--r-- | src/cgil/ril.lm | 284 | ||||
-rw-r--r-- | src/cgil/rlhc-c.lm | 462 | ||||
-rw-r--r-- | src/cgil/rlhc-crack.lm | 536 | ||||
-rw-r--r-- | src/cgil/rlhc-csharp.lm | 480 | ||||
-rw-r--r-- | src/cgil/rlhc-d.lm | 511 | ||||
-rw-r--r-- | src/cgil/rlhc-go.lm | 454 | ||||
-rw-r--r-- | src/cgil/rlhc-java.lm | 504 | ||||
-rw-r--r-- | src/cgil/rlhc-js.lm | 504 | ||||
-rw-r--r-- | src/cgil/rlhc-julia.lm | 561 | ||||
-rw-r--r-- | src/cgil/rlhc-main.lm | 19 | ||||
-rw-r--r-- | src/cgil/rlhc-ocaml.lm | 609 | ||||
-rw-r--r-- | src/cgil/rlhc-ruby.lm | 527 | ||||
-rw-r--r-- | src/cgil/rlhc-rust.lm | 534 |
16 files changed, 7023 insertions, 0 deletions
diff --git a/src/cgil/.gitignore b/src/cgil/.gitignore new file mode 100644 index 00000000..9ee64540 --- /dev/null +++ b/src/cgil/.gitignore @@ -0,0 +1,2 @@ +/Makefile.in +/Makefile diff --git a/src/cgil/Makefile.am b/src/cgil/Makefile.am new file mode 100644 index 00000000..57d12e80 --- /dev/null +++ b/src/cgil/Makefile.am @@ -0,0 +1,9 @@ + +data_DATA = $(CGIL_FILES) + +CGIL_FILES = ril.lm rlhc-main.lm \ + rlhc-c.lm rlhc-csharp.lm rlhc-go.lm rlhc-js.lm rlhc-ruby.lm \ + rlhc-crack.lm rlhc-d.lm rlhc-java.lm rlhc-julia.lm rlhc-ocaml.lm rlhc-rust.lm + +EXTRA_DIST = $(CGIL_FILES) + diff --git a/src/cgil/ragel.lm b/src/cgil/ragel.lm new file mode 100644 index 00000000..1325bbb3 --- /dev/null +++ b/src/cgil/ragel.lm @@ -0,0 +1,1027 @@ + +global GblActionParams: bool = false +global GblMachineMap: map<str, machine> = new map<str, machine>() +global GblCurMachine: machine +global GblTargetMachine: str = "" +global GblSearchMachine: str = "" +global GblWantSection: bool = false +global GblIncludeDepth: int = 0 +global GblImport: bool = false +global GblFileName: str = "" +global GblIncludePaths: list<str> = new list<str>() + +struct saved_globals + FileName: str + TargetMachine: str + SearchMachine: str + WantSection: bool + IncludeDepth: int + Import: bool +end + +global GblSavedGlobals: list<saved_globals> = new list<saved_globals>() + +void saveGlobals() +{ + new SG: saved_globals() + + SG->FileName = GblFileName + SG->TargetMachine = GblTargetMachine + SG->SearchMachine = GblSearchMachine + SG->WantSection = GblWantSection + SG->Import = GblImport + SG->IncludeDepth = GblIncludeDepth + + GblSavedGlobals->push_tail( SG ) +} + +void restoreGlobals() +{ + SG: saved_globals = GblSavedGlobals->pop_tail() + + GblFileName = SG->FileName + GblTargetMachine = SG->TargetMachine + GblSearchMachine = SG->SearchMachine + GblWantSection = SG->WantSection + GblImport = SG->Import + GblIncludeDepth = SG->IncludeDepth +} + +struct include_history_item + FileName: str + SectionName: str +end + +bool isDuplicateInclude( From: machine, FileName: str, SectionName: str ) +{ + for Item: include_history_item in From->IncludeHistory { + if Item->FileName == FileName && Item->SectionName == SectionName { + return true + } + } + return false +} + +void addIncludeItem( From: machine, FileName: str, SectionName: str ) +{ + new Item: include_history_item() + Item->FileName = FileName + Item->SectionName = SectionName + From->IncludeHistory->push_tail( Item ) +} + +struct machine + Name: str + ActionParams: map<str, str> + IncludeHistory: list<include_history_item> +end + + +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} / + +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))* '/' / + +# +# Consuming ragel defintions without parsing. Used for included sections we +# don't want and for import (TODO). +# +namespace consume + lex + token h_word / [a-zA-Z_][a-zA-Z0-9_]* / + + token h_open /'{'/ + token h_close /'}'/ + + token h_number /digit+/ + token h_hex_number /'0x' [0-9a-fA-F]+/ + + token h_comment + / c_comment | cpp_comment / + + token h_string + / s_literal | d_literal / + + token h_whitespace + / ( [ \t] | NL )+ / + + token h_any / any / + end + + def host_tok + [h_word] + | [h_number] + | [h_hex_number] + | [h_comment] + | [h_string] + | [h_whitespace] + | [h_open host_tok* h_close] + | [h_any] + + lex + ignore /[\t\n ]+/ + ignore /'#' any* :> '\n'/ + + literal `}%% + + token word / [a-zA-Z_][a-zA-Z0-9_]* / + token uint / number / + token hex / hex_number / + + token string / + '"' ( [^"\\] | '\\' any )* '"' 'i'? | + "'" ( [^'\\] | '\\' any )* "'" 'i'? | + "[" ( [^\]\\] | '\\' any )* "]" 'i'? #| + #"/" ( [^\/\\] | '\\' any )* "/" 'i'? + / + + + token open /'{'/ -ni + token close ni- /'}'/ + token c_any / any / + end + + + # Garbling up a machine, no interpretation + def tok + [word] + | [uint] + | [hex] + | [string] + | [open host_tok* h_close] + | [c_any] +end + +# State reference. +namespace state_ref + lex + ignore /[\t\n ]+/ + literal `:: `; `) + token word /[a-zA-Z_][a-zA-Z0-9_]*/ + end + + def state_ref + [opt_name_sep state_ref_names] :Ref + + def opt_name_sep + [`::] :ColonColon + | [] :Empty + + # List of names separated by :: + def state_ref_names + [state_ref_names `:: word] :Rec + | [word] :Base +end + +namespace inline + + 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::state_ref state_ref::`)] :Fentry + | [var_ref] :VarRef + + 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::state_ref state_ref::`;] :FgotoSr + | [`fnext state_ref::state_ref state_ref::`;] :FnextSr + | [`fcall state_ref::state_ref state_ref::`;] :FcallSr + | [`fncall state_ref::state_ref state_ref::`;] :FncallSr + | [`fret `;] :Fret + | [`fnret `;] :Fnret + | [`fbreak `;] :Fbreak + | [`fnbreak `;] :Fnbreak +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 `%%--{ -ni `%%++{ -ni + + token include_tok + /'include'/ + { + # Take off the include token. + input->pull( match_length ) + + # Parse the include details, up to the the ';' and stop there. + parse_stop Spec: include_spec(input)[] + + Fn: str + Machine: str + if Spec.string + Fn = $Spec.string + if Spec.word + Machine = $Spec.word + + Stream: stream = ragelInclude( Fn, Machine ) + + if Stream { + input->push( "}--%%" ) + input->push_stream( Stream ) + input->push( "%%--{" ) + } + } + + token import_tok + /'import'/ + { + # Take off the include token. + input->pull( match_length ) + + # Parse the import details, up to the the ';' and stop there. + parse_stop Spec: import_spec(input)[] + + Fn: str + if Spec.string + Fn = $Spec.string + + Stream: stream = ragelImport( Fn ) + + if Stream { + input->push( "}++%%" ) + input->push_stream( Stream ) + input->push( "%%++{" ) + } + } + + + literal `machine `action `variable `alphtype + `access `write `getkey `export `prepush + `postpop `nfaprepush `nfapostpop + + literal `:nfa `:nfa_greedy `:nfa_lazy `:nfa_wrap + `:nfa_wrap_greedy `:nfa_wrap_lazy + `:cond `:condplus `:condstar `): + + token string / + '"' ( [^"\\] | '\\' any )* '"' 'i'? | + "'" ( [^'\\] | '\\' any )* "'" 'i'? + / + + 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 + + def include_spec + [word `;] + | [string `;] + | [word string `;] + + def import_spec + [string `;] + + 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/ + + # This region is for deciding if we want to parse a ragel section, or if we + # want to consume it without interpreting. Consuming is for included + # sections we don't want and all sections in an imported file. + lex + token ign_select /''/ + { + if GblWantSection + input->push( make_token( typeid<ign_want>, '' ) ) + else + input->push( make_token( typeid<ign_ignore>, '' ) ) + } + + token ign_want // + token ign_ignore // + end + + # + # Machine name word. We inspect it to determine if we are interested in the + # section. + # + lex + token mn_word / [a-zA-Z_][a-zA-Z0-9_]* / + { + S: str = input->pull(match_length) + IgnWord: mn_word = make_token( typeid<mn_word>, S ) + input->push( IgnWord ) + + if ( GblImport ) + GblWantSection = false + else if ( GblSearchMachine != "" ) { + if ( S != GblSearchMachine ) + GblWantSection = false + else + GblWantSection = true + } + else { + GblWantSection = true + } + + Name: str = S #$lhs.mn_word + if GblTargetMachine != "" + Name = GblTargetMachine + + Machine: machine = GblMachineMap->find( Name ) + + if !Machine + { + Machine = new machine() + Machine->Name = Name + Machine->ActionParams = new map<str, str>() + Machine->IncludeHistory = new list<include_history_item>() + GblMachineMap->insert( Machine->Name, Machine ) + } + + GblCurMachine = Machine + + # print "want section: [GblWantSection] + } + end + + + 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 + [`{ CInlineExpr: inline::inline_expr inline::`}] :ActionExpr + + def action_block + [`{ CInlineBlock: inline::inline_block inline::`}] :ActionBlock + + 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 ( GblCurMachine->ActionParams->find( $lhs.word ) ) + reject + } + | [word `( opt_action_arg_list `)] :Args + { + if ( ! GblCurMachine->ActionParams->find( $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] :Default + | [`:nfa_lazy] :Lazy + | [`:nfa_greedy] :Greedy + + def nfawrap + [`:nfa_wrap] :Default + | [`:nfa_wrap_lazy] :Lazy + | [`:nfa_wrap_greedy] :Greedy + + def colon_cond + [`:cond] :Cond + | [`:condstar] :CondStar + | [`:condplus] :CondPlus + + def factor + [alphabet_num] :AlphabetNum + | [word] :Word + | [string] :String + | [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 + | [nfawrap `( expression `, + Push: action_ref `, Pop: action_ref `, Init: action_ref `, Stay: action_ref `, + Exit: action_ref `):] :NfaWrap + | [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 + | [`:nfa `|* lm_stmt_list `*|] :LmNfa + + # + # 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 + { + # Track that this action has params so we can parse appropriately + # when reducing. + GblCurMachine->ActionParams->insert( $lhs.word, $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 opt_export + [`export] :Export + | [] :Base + + def write_arg + [word] :Word + + def machine_name + [`machine mn_word `;] :MachineName + + def open_inc + [`%%--{] :OpenInc + + def close_inc + [host::close_inc] :CloseInc + + def include_statement + [open_inc host::section* close_inc] :IncPost commit + + def open_imp + [`%%++{] :OpenImp + + def close_imp + [host::close_imp] :CloseImp + + def import_statement + [open_imp host::section* close_imp] :ImpPost commit + + 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_statement] :Import commit + | [include_statement] :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 ign_want statement*] + | [opt_machine_name ign_ignore consume::tok*] +end + +str prepareLitString( Str: str ) +{ + # TODO: escape sequences + return suffix( prefix( Str, Str.length - 1 ), 1 ) +} + +bool isAbsolutePath( Path: str ) +{ + # TODO: implement this + return false +} + +namespace path + lex + token slash /'/'/ + token chars /[^\/]+/ + end + + def path + [Abs: slash? DirList: dir* File: chars] + + def dir + [chars slash] + + dir *concat_dir( Dir1: dir*, Dir2: dir* ) + { + for D: dir* in Dir1 { + if match D [] { + D = Dir2 + break + } + } + return Dir1 + } +end + +namespace host + token bom / 0xEF 0xBB 0xBF / + + def opt_bom + [bom] :Bom + | [] + + def section + [`%%{ ragel::opt_machine_name ragel::ign_want ragel::statement* ragel::`}%%] :MultiLine + | [`%%{ ragel::opt_machine_name ragel::ign_ignore consume::tok* consume::`}%%] :Consume + | [tok] :Token +end + +def start + [host::opt_bom SectionList: host::section*] + +list<str> makeIncludePathChecks( CurFileName: str, IncFileName: str ) +{ + new L: list<str>() + + parse CurPath: path::path[ CurFileName ] + parse IncPath: path::path[ IncFileName ] + + if match IncPath.Abs [slash] { + # Included file is absolute + L->push_tail( IncFileName ) + } + else { + # First add the location of current file + if match CurPath.DirList [] + L->push_tail( IncFileName ) + else { + # Current file path + Include Path + Include File + cons NewPath: path::path [ + CurPath.Abs + path::concat_dir( CurPath.DirList, IncPath.DirList ) + IncPath.File + ] + + L->push_tail( $NewPath ) + } + + # Next add include file locations. + for Path: str in GblIncludePaths { + parse IncPath: path::path[ CurFileName ] + L->push_tail( "[Path]/[IncFileName]" ) + } + } + return L +} + +stream ragelInclude( IncFileName: str, Machine: str ) +{ + if IncFileName + IncFileName = prepareLitString( IncFileName ) + + Checks: list<str> + if IncFileName + Checks = makeIncludePathChecks( GblFileName, IncFileName ) + else { + Checks = new list<str>() + Checks->push_tail( GblFileName ) + + } + + Stream: stream + OpenedName: str + for P: str in Checks { + Stream = open( P, "r" ) + if Stream { + OpenedName = P + break + } + } + + if !Stream { + print "error: could not open [IncFileName] + return nil + } + + # Default to the current machine if none is specified. + if !Machine + Machine = GblCurMachine->Name + + if isDuplicateInclude( GblCurMachine, IncFileName, Machine ) + return nil + + addIncludeItem( GblCurMachine, IncFileName, Machine ) + + saveGlobals() + + GblIncludeDepth = GblIncludeDepth + 1 + GblFileName = OpenedName + + # Set up the search and target machine names. Search is the machine we want + # to include and target is the machine we include to. + GblSearchMachine = Machine + GblTargetMachine = GblCurMachine->Name + + return Stream +} + +stream ragelImport( IncFileName: str ) +{ + if IncFileName + IncFileName = prepareLitString( IncFileName ) + + Checks: list<str> + if IncFileName + Checks = makeIncludePathChecks( GblFileName, IncFileName ) + else { + Checks = new list<str>() + Checks->push_tail( GblFileName ) + } + + Stream: stream + OpenedName: str + for P: str in Checks { + Stream = open( P, "r" ) + if Stream { + OpenedName = P + break + } + } + + if !Stream { + print "error: could not open [IncFileName] + return nil + } + + saveGlobals() + + GblFileName = OpenedName + GblImport = true + + return Stream +} diff --git a/src/cgil/ril.lm b/src/cgil/ril.lm new file mode 100644 index 00000000..cde6ce93 --- /dev/null +++ b/src/cgil/ril.lm @@ -0,0 +1,284 @@ +namespace host + lex + rl NL / '\n' / + + token escape + / '@' any / + + literal `={ `}= `${ `}$ `@{ `}@ + + token host_any / any / + end + + def tok + [`${ StmtList: stmt* `}$] :Stmt + | [`={ Expr: expr `}=] :Expr + | [escape] :Escape + | [host_any] :Any +end + +lex + rl NL / '\n' / + + rl s_literal + / "'" ([^'\\\n] | '\\' (any | NL))* "'" / + + rl d_literal + / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / + + rl c_comment + / '/*' ( any | NL )* :>> '*/' / + + rl cpp_comment + / '//' [^\n]* NL / + + literal `array `value `TRUE `FALSE + `while `switch `case + `if `else `offset `index + `goto `deref `entry `label `default + `host `cast `match `pat + + literal `uint `const + `s8 `s16 `s32 `s64 + `s128 `nil `export + `fallthrough `u `c `break `continue + + token ident + /( alpha | '_' ) ( alpha | digit | '_' )*/ + + token uint + / digit+ / + + token hex_number + / '0x' [0-9a-fA-F]+ / + + ignore + / c_comment | cpp_comment / + + token string + / s_literal | d_literal / + + ignore / ( [ \t] | NL )+ / + + literal `$ `{ `} `= `[ `] + `- `, `. `; `( `) `: + `? `* `+ `> `< `& + `~ `! `!= `== `<< `>> + `+= `&& `|| `<= `>= + `@ `-= `-> `={ `${ `@{ +end + +def embedded_host + [`host `( string `, uint `) `={ TL: host::tok* host::`}=] :Expr +| [`host `( string `, uint `) `${ TL: host::tok* host::`}$] :Stmt +| [`host `( string `, uint `) `@{ TL: host::tok* host::`}@] :Bare + +def type + [ident] :Ident +| [ident ident] :Ident2 +| [`uint] :Uint +| [`s8] :S8 +| [`s16] :S16 +| [`s32] :S32 +| [`s64] :S64 +| [`s128] :S128 + +def expr_factor + [embedded_host] :EmbeddedHost +| [ident] :Ident +| [ident `[ expr `]] :ArraySub +| [ident `[ expr `] `. Field: ident] :ArraySubField +| [`offset `( ident `, expr `)] :Offset +| [`deref `( ident `, expr `)] :Deref +| [number] :Number +| [`TRUE] :True +| [`FALSE] :False +| [`nil] :Nil +| [hex_number] :HexNumber +| [string] :String +| [embedded_host `-> expr_factor] :Access +| [`( expr `)] :Paren +| [`cast `( type `) expr_factor] :Cast + +def lvalue + [embedded_host] +| [ident] +| [ident `[ expr `]] +| [ident `[ expr `] `. ident] +| [embedded_host `-> lvalue] + +def expr_factor_op + [`! expr_factor_op] +| [`~ expr_factor_op] +| [expr_factor] + +def expr_bitwise + [expr_bitwise `& expr_factor_op] +| [expr_factor_op] + +def expr_mult + [expr_mult `* expr_bitwise] +| [expr_bitwise] + +def add_op + [`+] | [`-] + +def expr_add + [expr_add add_op expr_mult] +| [expr_mult] + +def shift_op + [`<<] | [`>>] + +def expr_shift + [expr_shift shift_op expr_add] +| [expr_add] + +def test_op + [`<] | [`>] | [`<=] | [`>=] | + [`==] | [`!=] | [`&&] | [`||] + +def expr_test + [expr_test test_op expr_shift] +| [expr_shift] + +def expr + [expr_test] + +def sint + [uint] +| [`- uint] + +def number + [`u `( uint `)] :Unsigned +| [`c `( uint `)] :Char +| [sint] :Number + +def comma_num + [`, number] + +def num_list + [number comma_num*] +| [] + +def static_array + [`array type ident `( number `, number `) `= `{ num_list `} `;] + +def static_value + [`value type ident `= number `;] + +def break_label + [ident `: `:] + +def while_stmt + [break_label? `while `( expr `) stmt] + +def else_if_clause + [`else `if `( expr `) stmt] + +def else_clause + [`else stmt] + +def if_stmt [ + `if `( expr `) stmt + else_if_clause* else_clause? +] + +def match_stmt + [`match `( E: expr `) `{ P: pat_block* D: default_block? `}] + +def pat_block + [`pat expr `{ stmt* `}] + +def switch_stmt + [`switch `( expr `) `{ stmt* `}] + +def case_block + [`case expr `{ stmt* `}] + +def default_block + [`default `{ stmt* `}] + +def case_label + [`case expr `:] + +def goto_label + [ident `:] + +def opt_init + [`= expr] +| [] + +def opt_ptr + [`*] +| [] + +def opt_const + [`const] +| [] + +def declaration + [opt_const type ident opt_init `;] + +def index_stmt + [`index type ident opt_init`;] + +def export_stmt + [`export type ident number `;] + +def goto_stmt + Id: int + [`goto ident `;] + +def fallthrough + [`fallthrough `;] + +def break_stmt + [`break ident? `;] + +def continue_stmt + [`continue ident? `;] + +def block + [`{ StmtList: stmt* `}] + +def expr_stmt + [expr `;] + +def assign_op + [`=] | [`+=] | [`-=] + +def assign_stmt + [LValue: lvalue assign_op expr `;] + +def stmt + [embedded_host] +| [static_array] +| [static_value] +| [declaration] +| [index_stmt] +| [export_stmt] +| [assign_stmt] +| [expr_stmt] +| [while_stmt] +| [if_stmt] +| [match_stmt] +| [switch_stmt] +| [case_block] +| [default_block] +| [case_label] +| [goto_label] +| [goto_stmt] +| [fallthrough] +| [break_stmt] +| [continue_stmt] +| [block] + +token bom / 0xEF 0xBB 0xBF / + +def opt_bom + [bom] :Bom +| [] + +def start + [opt_bom stmt*] diff --git a/src/cgil/rlhc-c.lm b/src/cgil/rlhc-c.lm new file mode 100644 index 00000000..dfc24d1d --- /dev/null +++ b/src/cgil/rlhc-c.lm @@ -0,0 +1,462 @@ +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<c_out::c_out> + + 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 + { + << "[ident] + [expr( expr )]" + } + case Deref + { + << "(*( [expr(expr)] )) + } + case [`TRUE] + { + << "1" + } + case [`FALSE] + { + << "1" + } + case [N: `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<c_out::c_out>() + + 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' diff --git a/src/cgil/rlhc-crack.lm b/src/cgil/rlhc-crack.lm new file mode 100644 index 00000000..bebe7cd5 --- /dev/null +++ b/src/cgil/rlhc-crack.lm @@ -0,0 +1,536 @@ +include 'ril.lm' + +namespace crack_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 ) * "'" | + "`" ( [^`\\] | '\\' any ) * "`" + / + + ignore + /[ \t\v\r\n]+/ + end + + def item + [comment] + | [id] + | [number] + | [symbol] + | [string] + | [`{ _IN_ item* _EX_ `} ] + + def crack_out + [_IN_ _EX_ item*] +end + +namespace crack_gen + + global Parser: parser<crack_out::crack_out> + + void tok_list( TL: host::tok* ) + { + for Tok: host::tok in repeat(TL) { + switch Tok + case [host::`${ StmtList: stmt* host::`}$] { + send Parser + "if ( 1 ) { + " [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 + "if ( 1 ) { + " [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]\[[expr( E )]\]" + } + case [`offset `( ident `, expr `)] + { + send Parser + [expr( ExprFactor.expr )] + } + case [`deref `( ident `, expr `)] + { + send Parser + [ ExprFactor.ident '[' expr( ExprFactor.expr ) ']'] + } + case [`TRUE] + { + send Parser "1" + } + case [`FALSE] + { + send Parser "1" + } + 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 + "[type( T )] ( [expr_factor( F )] )" + } + 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] + { + # The accessor operator is contained wihtin the lhs. + 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 ['int16 '] + case "s16" + send Parser ['int16 '] + case "s32" + send Parser ['int32 '] + case "s64" + send Parser ['int64 '] + case "s128" + send Parser ['long long '] + case "uint" + send Parser ['uint32 '] + default + send Parser [Type] + } + + void number( Number: number ) + { + switch Number + case [`u `( uint `) ] + send Parser "[Number.uint]u" + case [`c `( uint `) ] + send Parser "[Number.uint]" + 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 [Array: static_array] { + send Parser + "const array\[[type(Array.type)]\] " + "[Array.ident] = \[ [num_list(Array.num_list)] \]; + } + case [Value: static_value] { + send Parser + "const [Value.type] [Value.ident] = [Value.number]; + } + case [ + `if `( IfExpr: expr `) IfStmt: stmt + ElseIfClauseList: else_if_clause* ElseClauseOpt: else_clause? + ] { + send Parser + "if ( [expr(IfExpr)] ) + " [flow_stmt(IfStmt)] + + for ElseIfClause: else_if_clause in repeat( ElseIfClauseList ) { + match ElseIfClause + ['else if (' ElseIfExpr: expr ')' ElseIfStmt: stmt] + + send Parser + "else if ( [expr(ElseIfExpr)] ) + " [flow_stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else + " [flow_stmt(ElseStmt)] + } + } + case [`while `( WhileExpr: expr `) WhileStmt: stmt] { + send Parser + "while ( [expr(WhileExpr)] ) + " [flow_stmt(WhileStmt)] + } + 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 + "else if ( [expr(SwitchExpr)] == [expr(E1)] ) { + " [stmt_list(Inner)] + "} + } + case + [`default `{ Inner: stmt* `}] + { + send Parser + "else { + " [stmt_list(Inner)] + "} + } + } + + send Parser + "; + } + case [ExprExpr: expr Semi: `;] { + send Parser + [expr(ExprExpr) Semi] + } + case [`{ TL: stmt* `}] { + send Parser + "if ( 1 ) { + " [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 + [Semi] + } + case [Export: export_stmt] + { + send Parser + "#define [Export.ident] [number(Export.number)] + } + case ['fallthrough' ';'] + { + # Nothing needed here. + } + case [Index: index_stmt] + { + send Parser + "int [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 )]: + "[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 [AS: assign_stmt] + { + send Parser + "[lvalue(AS.LValue) AS.assign_op expr(AS.expr)]; + } + default { + # catches unspecified cases + send Parser [Stmt] + } + } + + void flow_stmt( Stmt: stmt ) + { + switch Stmt + case [`{ TL: stmt* `}] { + send Parser + "{ + " [stmt_list(TL)] + "} + } + default { + stmt( Stmt ) + } + } + + void stmt_list( StmtList: stmt* ) + { + for Stmt: stmt in repeat( StmtList ) + stmt( Stmt ) + } + + void trans( Output: stream, Start: start ) + { + Parser = new parser<crack_out::crack_out>() + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + CO: crack_out::crack_out = Parser->finish() + + if CO { + send Output + [CO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } +end + +void trans( Output: stream, Start: start ) +{ + crack_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' diff --git a/src/cgil/rlhc-csharp.lm b/src/cgil/rlhc-csharp.lm new file mode 100644 index 00000000..078157c5 --- /dev/null +++ b/src/cgil/rlhc-csharp.lm @@ -0,0 +1,480 @@ +include 'ril.lm' + +namespace csharp_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 csharp_out + [_IN_ _EX_ item*] +end + +namespace csharp_gen + + global Parser: parser<csharp_out::csharp_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( 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 + "{[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) 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 ) ']'] + } + 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] + { + 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 ) + } + 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 ) + } + 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 ['sbyte '] + 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 ['uint '] + default + send Parser [Type] + } + + void number( Number: number ) + { + switch Number + case [`c `( uint `) ] { + Str: str = $Number.uint + send Parser "'\\u[sprintf( "%04x", Str.atoi() )]'" + } + case [`u `( uint `) ] { + send Parser [$Number.uint] + } + default { + send Parser [$Number.sint] + } + } + + 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 + "static readonly [type(A.type)] \[\]" + "[A.ident] = { [num_list( A.num_list )] }; + } + case [V: static_value] { + send Parser + "static readonly [V.type] [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 + "else if ( [expr(ElseIfExpr)] ) + " [stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else + " [stmt(ElseStmt)] + } + } + case ['while' '(' WhileExpr: expr ')' WhileStmt: stmt] { + send Parser + "while ( [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 [ + 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 + [Semi] + } + case [Export: export_stmt] + { + send Parser + "#define [Export.ident] [Export.number] + } + case ['fallthrough' ';'] + { + # Nothing needed here. + } + case [Index: index_stmt] + { + send Parser + "int [Index.ident]" + + if match Index.opt_init [E: `= expr] { + send Parser + [E expr(Index.opt_init.expr)] + } + + send Parser ";" + } + 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 [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<csharp_out::csharp_out>() + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + CSO: csharp_out::csharp_out = Parser->finish() + + if CSO { + send Output + [CSO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } +end + +void trans( Output: stream, Start: start ) +{ + csharp_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' diff --git a/src/cgil/rlhc-d.lm b/src/cgil/rlhc-d.lm new file mode 100644 index 00000000..2a047e68 --- /dev/null +++ b/src/cgil/rlhc-d.lm @@ -0,0 +1,511 @@ +include 'ril.lm' + +namespace d_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 d_out + [_IN_ _EX_ item*] +end + +namespace d_gen + + global Parser: parser<d_out::d_out> + + global HasDefault: list<int> = new list<int>() + + void pushHasDef( H: int ) + { + HasDefault->push( H ) + } + + int popHasDef() + { + return HasDefault->pop() + } + + 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 ) C] + } + case + [ident O: `[ TL: expr C: `]] + { + send Parser + [ExprFactor.ident O expr(TL) C] + } + case + [`offset `( ident `, expr `)] + { + send Parser + "& [ExprFactor.ident] \[ [expr(ExprFactor.expr)] \] + } + case + [`deref `( ident `, expr `)] + { + send Parser + "(*( [expr(ExprFactor.expr)] )) + } + case + [T: `TRUE] + { + T.data = '1' + send Parser [T] + } + case + [F: `FALSE] + { + F.data = '0' + send Parser [F] + } + case + [N: `nil] + { + N.data = 'null' + send Parser [N] + } + case + [Number: number] + { + 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 ['cast' Open] + type( Type ) + send Parser [Close] + expr_factor( ExprFactor._expr_factor ) + } + 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 ) + } + 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 '] + 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 + "static const [type(A.type)]\[\] " + "[A.ident] = \[ [num_list( A.num_list )] \]; + } + case [V: static_value] { + send Parser + "static const [V.type] [V.ident] = [V.number]; + } + 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 + "else if ( [expr(ElseIfExpr)] ) + " [stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else + " [stmt(ElseStmt)] + } + } + case [`while `( WhileExpr: expr `) WhileStmt: stmt] { + send Parser + "while ( [expr(WhileExpr)] ) + " [stmt(WhileStmt)] + } + case [`switch `( SwitchExpr: expr `) `{ StmtList: stmt* `}] { + pushHasDef( 0 ) + + send Parser + "switch ( [expr(SwitchExpr)] ) { + " [stmt_list(StmtList)] + + if ( popHasDef() == 0 ) { + send Parser + " default: break; + } + + send Parser + "} + } + case [ExprExpr: expr Semi: `;] { + send Parser + [expr( ExprExpr ) Semi] + } + case [L: `{ TL: stmt* R: `}] { + send Parser + [L stmt_list( TL ) R] + } + case [ + OptConst: opt_const Type: type + Ident: ident OptInit: opt_init Semi: `; + ] + { + if match OptConst ['const'] { + send Parser + "const( [type( Type )] ) + } + else { + type( Type ) + } + + send Parser [Ident] + + if match OptInit [E: `= expr] { + send Parser + [E expr(OptInit.expr)] + } + + send Parser [Semi] + } + 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; + + popHasDef() + pushHasDef( 1 ) + } + case [case_label] + { + send Parser + "case [expr( Stmt.case_label.expr )]: + } + case [export_stmt] + { + send Parser + "static const [type(Stmt.export_stmt.type)] " + "[Stmt.export_stmt.ident] = [number(Stmt.export_stmt.number)]; + } + case ['fallthrough' ';'] + { + send Parser "goto case;" + } + case [Index: index_stmt] + { + send Parser + "const([type(Index.type)]) *[Index.ident]" + + if match Index.opt_init [E: `= expr] { + send Parser + [E expr(Index.opt_init.expr)] + } + + send Parser "; + } + 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<d_out::d_out>() + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + DO: d_out::d_out = Parser->finish() + + if DO { + send Output + [DO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } +end + +void trans( Output: stream, Start: start ) +{ + d_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' diff --git a/src/cgil/rlhc-go.lm b/src/cgil/rlhc-go.lm new file mode 100644 index 00000000..b8353d10 --- /dev/null +++ b/src/cgil/rlhc-go.lm @@ -0,0 +1,454 @@ +include 'ril.lm' + +namespace out_go + 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 out_go + [_IN_ _EX_ item*] +end + + + +namespace go_gen + + global _: parser<out_go::out_go> + + 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 = $Tok + << "[Str.suffix( 1 )]" + } + default { + << [Tok] + } + } + } + + void embedded_host( EmbeddedHost: embedded_host ) + { + switch EmbeddedHost + case Expr + { + << ['(' tok_list( TL ) ')'] + } + case Stmt + { + << ['{' tok_list( TL ) '}\n'] + } + case Bare + { + << [tok_list( TL )] + } + } + + void expr_factor( ExprFactor: expr_factor ) + { + switch ExprFactor + case EmbeddedHost + { + << [embedded_host(embedded_host)] + } + case Paren + { + << ['( ' expr(expr) ' )'] + } + case ArraySub + { + << [ident '[ ' expr( expr ) ' ]'] + } + case Offset + { + << "int([expr(expr )]) + } + case Deref + { + << [ident '[ ' expr( expr ) ' ]' ] + } + case True + { + << "true" + } + case False + { + << "false" + } + case Nil + { + << "0" + } + case Access + { + embedded_host(embedded_host) + expr_factor(_expr_factor) + } + case Cast + { + << [type(type) '( ' expr_factor(_expr_factor) ' )' ] + } + default { + # Catches cases not specified + << [ExprFactor] + } + } + + void lvalue( ExprFactor: lvalue ) + { + switch ExprFactor + case [EH: embedded_host] + { + << [embedded_host(EH)] + } + case [ident `[ TL: expr `]] + { + << [ident '[' expr( TL ) ']'] + } + case [E1: embedded_host `-> E2: lvalue] + { + 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( ExprFactorOp.expr_factor )] + } + } + + void expr_bitwise( ExprBitwise: expr_bitwise ) + { + switch ExprBitwise + case [expr_bitwise A: `& expr_factor_op] + { + << [expr_bitwise( _expr_bitwise ) ' & ' expr_factor_op( 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( _expr_mult ) ' * ' 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( ExprAdd.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( ExprTest.expr_shift )] + } + } + + void expr( Expr: expr ) + { + expr_test( Expr.expr_test ) + } + + void type( Type: type ) + { + switch Type + case S8 + << ['int8'] + case S16 + << ['int16'] + case S32 + << ['int32'] + case S64 + << ['int64'] + case S128 + << ['long long'] + default + << [Type] + } + + void number( Number: number ) + { + switch Number + case Unsigned + << [uint] + default + << [Number] + } + + void num_list( NumList: num_list ) + { + number( NumList.number ) + for CommaNum: comma_num in NumList { + << [', ' number( CommaNum.number )] + } + } + + # Go must have {} around if and for statements. We strip any blocks from + # these statments and force our own. + void strip_block_stmt( Stmt: stmt ) + { + if match Stmt [`{ StmtList: stmt* `}] + stmt_list(StmtList) + else + stmt( Stmt ) + } + + void stmt( Stmt: stmt ) + { + switch Stmt + case [EH: embedded_host] + { + << [embedded_host(EH)] + } + case [A: static_array] { + << "var [A.ident] = \[\] " + "[type(A.type)] { [num_list(A.num_list)] } + } + case [V: static_value] { + << "var [V.ident] [type(V.type)] = [V.number] + "var _ = [V.ident] + } + case [ + 'if' O: `( IfExpr: expr C: `) IfStmt: stmt + ] { + # if-statements with only the if clause can go out as an if. + << "if [expr(IfExpr)] { + " [strip_block_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. + << "if [expr( IfExpr )] { + " [strip_block_stmt( IfStmt )] + + for ElseIfClause: else_if_clause in repeat( ElseIfClauseList ) { + match ElseIfClause + ['else if (' ElseIfExpr: expr ')' ElseIfStmt: stmt] + + << "} else if [expr(ElseIfExpr)] { + " [strip_block_stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + << "} else { + " [strip_block_stmt(ElseStmt)] + } + + << "} + } + case ["while ( TRUE )" WhileStmt: stmt] { + << "for { + " [strip_block_stmt(WhileStmt)] + "} + } + case ['while' '(' WhileExpr: expr ')' WhileStmt: stmt] { + << "for [expr(WhileExpr)] { + " [strip_block_stmt(WhileStmt)] + "} + } + case ['switch' '(' SwitchExpr: expr ')' '{' StmtList: stmt* '}'] { + << "switch [expr(SwitchExpr)] { + " [stmt_list(StmtList)] + "} + } + case [ExprExpr: expr `;] { + << [expr(ExprExpr) ';'] + } + case [B: block] { + << "{ + " [stmt_list(B.StmtList)] + "} + } + case [D: declaration] + { + << "var [D.ident] [type(D.type)]" + + if match D.opt_init ['=' Expr: expr] { + << " = [expr(Expr)]" + } + + << ['\n'] + } + case [ES: export_stmt] + { + << "#define [ES.ident] [number(ES.number)] + } + case [fallthrough] + { + << "fallthrough + } + case [Index: index_stmt] + { + << "var [Index.ident] int" + + if match Index.opt_init ['=' Expr: expr] { + << " = [expr(Expr)]" + } + + << ['\n'] + } + case [CB: case_block] + { + << "case [expr( CB.expr )]: + " [stmt_list( CB._repeat_stmt )] + } + case [DB: default_block] + { + << "default: + " [stmt_list( DB._repeat_stmt )] + } + 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<out_go::out_go>() + Input: _input = _->gets() + Input->auto_trim(true) + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + GO: out_go::out_go = _->finish() + + if GO { + send Output + [GO] + } + else { + send stderr + "failed to parse output: [_->error] + } + + } +end + +void trans( Output: stream, Start: start ) +{ + go_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' diff --git a/src/cgil/rlhc-java.lm b/src/cgil/rlhc-java.lm new file mode 100644 index 00000000..a458369f --- /dev/null +++ b/src/cgil/rlhc-java.lm @@ -0,0 +1,504 @@ +include 'ril.lm' + +namespace java_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 java_out + [_IN_ _EX_ item*] +end + +namespace java_gen + + global Parser: parser<java_out::java_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( 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 + "{ + " [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) 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 ) ']'] + } + 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] + { + 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 number( Number: number ) + { + switch Number + case [`u `( uint `) ] + send Parser "[Number.uint]" + default + send Parser [Number] + } + + void java_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 + "private static [type(A.type)] " + "[A.ident] \[\] = { [java_num_list(A.num_list)] }; + } + case [V: static_value] { + send Parser + "private static [V.type] [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 + "else if ( [expr(ElseIfExpr)] ) + " [stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else + " [stmt(ElseStmt)] + } + } + case ['while' '(' WhileExpr: expr ')' WhileStmt: stmt] { + send Parser + "while ( [expr(WhileExpr)] ) + " [stmt(WhileStmt)] + } + case [BL: break_label? 'while' '(' WhileExpr: expr ')' '{' StmtList: stmt* '}' ] { + if match BL [bl: break_label] + send Parser "[bl.ident]: " + + send Parser + "while ( [expr(WhileExpr)] ) { + " [stmt_list(StmtList)] + "} + } + 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 + "{ + " [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 + [Semi] + } + case [Export: export_stmt] + { + send Parser + "static final char [Export.ident] = [number(Export.number)]; + } + case ['fallthrough' ';'] + { + # Nothing needed here. + } + case [Index: index_stmt] + { + send Parser + "int [Index.ident]" + + if match Index.opt_init [E: `= expr] { + send Parser + [E expr(Index.opt_init.expr)] + } + send Parser "; + + } + 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 [goto_label] { } + case [G: goto_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<java_out::java_out>() + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + JO: java_out::java_out = Parser->finish() + + if JO { + send Output + [JO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } +end + +void trans( Output: stream, Start: start ) +{ + java_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' diff --git a/src/cgil/rlhc-js.lm b/src/cgil/rlhc-js.lm new file mode 100644 index 00000000..29a61346 --- /dev/null +++ b/src/cgil/rlhc-js.lm @@ -0,0 +1,504 @@ +include 'ril.lm' + +namespace js_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 js_out + [_IN_ _EX_ item*] +end + +namespace js_gen + + global Parser: parser<js_out::js_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) 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] + if $ExprFactor.ident == 'data' + send Parser ['.charCodeAt(' expr( ExprFactor.expr ) ')'] + else + send Parser ['[' expr( ExprFactor.expr ) ']'] + } + case [T: `TRUE] + { + T.data = 'true' + send Parser [T] + } + case [F: `FALSE] + { + F.data = 'false' + send Parser [F] + } + case [N: `nil] + { + N.data = '-1' + send Parser [N] + } + case [Number: number] + { + number( Number ) + } + case [E1: embedded_host `-> E2: expr_factor] + { + embedded_host( E1 ) + expr_factor( E2 ) + } + case [`cast Open: `( type Close: `) expr_factor] + { + expr_factor( ExprFactor._expr_factor ) + } + 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 [I: ident `[ E: expr `] `. F: ident] + { + send Parser + "[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 + 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_op( Op: test_op ) + { + switch Op + case [ `== ] + send Parser '===' + case [ `!= ] + send Parser '!==' + default + send Parser [Op] + } + + void expr_test( ExprTest: expr_test ) + { + switch ExprTest + case [expr_test test_op expr_shift] + { + expr_test( ExprTest._expr_test ) + expr_test_op( ExprTest.test_op ) + expr_shift( ExprTest.expr_shift ) + } + case [expr_shift] + { + expr_shift( ExprTest.expr_shift ) + } + } + + void expr( Expr: expr ) + { + expr_test( Expr.expr_test ) + } + + void number( Number: number ) + { + switch Number + case [`u `( uint `) ] + send Parser [Number.uint] + default + send Parser [Number] + } + + void type( Type: type ) + { + switch Type + case 'u8' + send Parser 'Uint8' + case 'u16' + send Parser 'Uint16' + case 'u32' + send Parser 'Uint32' + case 's8' + send Parser 'Int8' + case 's16' + send Parser 'Int16' + case 's32' + send Parser 'Int32' + default + send Parser 'Float64' + } + + 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] = new [type(A.type)]Array(\[ [num_list(A.num_list)]\]); + } + case [V: static_value] { + send Parser + "var [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 + "else if ( [expr(ElseIfExpr)] ) + " [stmt(ElseIfStmt)] + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else + " [stmt(ElseStmt)] + } + } + case ['while' '(' WhileExpr: expr ')' WhileStmt: stmt] { + send Parser + "while ( [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 + "{ + " [stmt_list(TL)] + "} + } + case [ + TypeList: opt_const Type: type + Ident: ident OptInit: opt_init Semi: `; + ] + { + send Parser + "var [Ident] + + if match OptInit [E: `= expr] { + send Parser + [E expr(OptInit.expr)] + } + + send Parser + [Semi] + } + case [Export: export_stmt] + { + send Parser + "var [Export.ident] = [number(Export.number)]; + } + case ['fallthrough' ';'] + { + # Nothing needed here. + } + case [Index: index_stmt] + { + send Parser + "var [Index.ident]" + + if match Index.opt_init [E: `= expr] { + send Parser + [E expr(Index.opt_init.expr)] + } + + send Parser + "; + } + 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 [goto_label] { } + case [G: goto_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<js_out::js_out>() + + send Parser + "'use strict'; + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + CO: js_out::js_out = Parser->finish() + + if CO { + send Output + [CO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } +end + +void trans( Output: stream, Start: start ) +{ + js_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' diff --git a/src/cgil/rlhc-julia.lm b/src/cgil/rlhc-julia.lm new file mode 100644 index 00000000..72108994 --- /dev/null +++ b/src/cgil/rlhc-julia.lm @@ -0,0 +1,561 @@ +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<julia_out::julia_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::`}=] { + 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 `( ident `, expr `)] + { + send Parser + [expr( ExprFactor.expr )] + } + case [`deref `( I: ident `, E: expr `)] + { + send Parser + "[I]\[1+([ expr( E ) ])\]" + } + 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<julia_out::julia_out>() + + 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' diff --git a/src/cgil/rlhc-main.lm b/src/cgil/rlhc-main.lm new file mode 100644 index 00000000..f9abea7e --- /dev/null +++ b/src/cgil/rlhc-main.lm @@ -0,0 +1,19 @@ +InputFile: str = argv->pop() +OutputFile: str = argv->pop() + +# +# Open input and parse +# +Input: stream = open( InputFile, "r" ) +parse Start: start[ Input ] +if ( !Start ) { + print( error, '\n' ) + exit(1) +} + +# +# Translate +# +Output: stream = open( OutputFile, "w" ) +trans( Output, Start ) + diff --git a/src/cgil/rlhc-ocaml.lm b/src/cgil/rlhc-ocaml.lm new file mode 100644 index 00000000..f68b61be --- /dev/null +++ b/src/cgil/rlhc-ocaml.lm @@ -0,0 +1,609 @@ +include 'ril.lm' + +namespace ocaml_out + token _IN_ /''/ + token _EX_ /''/ + + lex + token comment / + '(*' any* :>> '*)' + / + + literal `begin `end `{ `} + + token id + /[a-zA-Z_][a-zA-Z_0-9]* "'"? / + + token number / + [0-9]+ + / + + token symbol / + '!' | '#' | '$' | '%' | '&' | '(' | ')' | '*' | + '+' | ',' | '-' | '.' | '/' | ':' | ';' | '<' | + '=' | '>' | '?' | '@' | '[' | ']' | '^' | '|' | + '~' | '`' / + + token string / + '"' ( [^"\\\n] | '\\' any ) * '"' | + "'" ( [^'\\\n] | '\\' any ) * "'" + / + + ignore + /[ \t\v\r\n]+/ + end + + def item + [comment] + | [id] + | [number] + | [symbol] + | [string] + | [`begin _IN_ item* _EX_ `end ] + | [`{ _IN_ item* _EX_ `} ] + + def ocaml_out + [_IN_ _EX_ item*] +end + +namespace ml_gen + + global StaticVarMap: map<str, str> = new map<str, str>() + global Parser: parser<ocaml_out::ocaml_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::`}=] + send Parser "([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 [`( TL: expr `)] + { + send Parser + "( [ expr(TL) ] )" + } + case [I: ident `[ TL: expr `]] + { + if ( StaticVarMap->find( $I ) || $I == 'stack' ) { + send Parser + "[ ExprFactor.ident ].([ expr( TL ) ])" + } + else { + send Parser + "[ ExprFactor.ident ].\[[ expr( TL ) ]\]" + } + } + case [I: ident `[ E: expr `] `. F: ident] { + send Parser + [^I '_' ^F '.(' expr(E) ')'] + } + case ['offset' '(' ident ',' expr ')'] + { + send Parser + [expr( ExprFactor.expr )] + } + case ['deref' '(' I: ident ',' Expr: expr ')'] + { + if ( $I == 'data' ) + send Parser 'Char.code ' + + if ( StaticVarMap->find( $I ) ) { + send Parser + "[I].( [ expr( Expr ) ] )" + } + else { + send Parser + "[I].\[[ expr( Expr ) ]\]" + } + } + 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] + { + number( Number ) + } + case [I: ident] { + if ( StaticVarMap->find( $I ) ) { + send Parser + [^I] + } + else { + send Parser + "[^I].contents" + } + } + case [E1: embedded_host `-> E2: expr_factor] + { + # The accessor operator is contained wihtin the lhs. + embedded_host( E1 ) + expr_factor( E2 ) + } + case [`cast `( type `) expr_factor] + { + send Parser + [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] + { + # The accessor operator is contained wihtin the lhs. + 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 " lnot " + expr_factor_op( ExprFactorOp._expr_factor_op ) + } + case [expr_factor] + { + expr_factor( ExprFactorOp.expr_factor ) + } + } + + void expr_bitwise( ExprBitwise: expr_bitwise ) + { + switch ExprBitwise + case [L: expr_bitwise `& R: expr_factor_op] + { + send Parser + "[expr_bitwise( L )] land [expr_factor_op( R )]" + } + 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 ) + switch Op + case [`<<] + send Parser " lsl " + default + send Parser " asr " + 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 ) + switch Op + case [`==] + send Parser "= " + default + 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 ['char '] + 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 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] { + StaticVarMap->insert( $A.ident, ' ' ) + send Parser + "let [A.ident] : int array = \[| + " [num_list(A.num_list)] + "|\] + } + case [V: static_value] { + StaticVarMap->insert( $V.ident, ' ' ) + send Parser + "let [V.ident] : [V.type] = [V.number] + } + case [ + 'if' O: `( IfExpr: expr C: `) IfStmt: stmt + ElseIfClauseList: else_if_clause* ElseClauseOpt: else_clause? + ] { + send Parser + "if [expr(IfExpr)] then + "begin + " [stmt(IfStmt)] + "end + + for ElseIfClause: else_if_clause in repeat( ElseIfClauseList ) { + match ElseIfClause + ['else if (' ElseIfExpr: expr ')' ElseIfStmt: stmt] + + send Parser + "else if [expr(ElseIfExpr)] then + "begin + " [stmt(ElseIfStmt)] + "end + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else + "begin + " [stmt(ElseStmt)] + "end + } + + send Parser + ";" + } + case ['while' '(' WhileExpr: expr ')' WhileStmt: stmt] { + send Parser + "while [expr(WhileExpr)] do + " [stmt(WhileStmt)] + "done; + } + case ['switch' '(' SwitchExpr: expr ')' '{' StmtList: stmt* '}'] { + require StmtList + [`case E1: expr `{ Inner: stmt* `} Rest: stmt*] + + send Parser + "if [expr(SwitchExpr)] = [expr(E1)] then + "begin + " [stmt_list(Inner)] + "end + + for S: stmt in repeat(Rest) { + switch S + case [`case E1: expr `{ Inner: stmt* `}] + { + send Parser + "else if [expr(SwitchExpr)] = [expr(E1)] then + "begin + " [stmt_list(Inner)] + "end + } + case + [`default `{ Inner: stmt* `}] + { + send Parser + "else + "begin + " [stmt_list(Inner)] + "end + } + } + + send Parser + "; + } + case [ExprExpr: expr Semi: `;] { + send Parser + [expr(ExprExpr) Semi] + } + case [L: `{ TL: stmt* R: `}] { + send Parser + "begin + "[stmt_list(TL)] + "end; + } + case [D: declaration] { + send Parser + "let [D.ident] : [type(D.type)] ref " + + switch D.opt_init + case [E: `= expr] { + send Parser + "= ref ( [expr(D.opt_init.expr)] )" + } + default { + send Parser + "= ref 0" + } + + send Parser + " in + } + case [Export: export_stmt] + { + send Parser + "#define [Export.ident] [number(Export.number)] + } + case ['fallthrough' ';'] + { + # Nothing needed here. + } + case [Index: index_stmt] + { + send Parser + "let [Index.ident] : int ref " + + switch Index.opt_init + case [E: `= expr] { + send Parser + "= ref ( [expr(Index.opt_init.expr)] )" + } + default { + send Parser + "= ref 0" + } + + send Parser + " in + } + case [case_block] + { + send Parser + "| [expr( Stmt.case_block.expr )] -> + "begin + "[stmt_list( Stmt.case_block._repeat_stmt )] + "end; + } + case [default_block] + { + send Parser + "| _ -> + "[stmt_list( Stmt.default_block._repeat_stmt )] + } + case [case_label] + { + send Parser + "case [expr( Stmt.case_label.expr )]: + } + case [AS: assign_stmt] + { + switch AS.assign_op + case [`=] + { + switch AS.LValue + case "stack\[[expr]\]" { + send Parser + "Array.set stack top.contents [expr(AS.expr)]; + } + case "nfa_bp\[[expr]\].state" { + send Parser + "Array.set nfa_bp_state nfa_len.contents [expr(AS.expr)]; + } + case "nfa_bp\[[expr]\].p" { + send Parser + "Array.set nfa_bp_p nfa_len.contents [expr(AS.expr)]; + } + default { + send Parser + "[lvalue(AS.LValue)] := [expr(AS.expr)]; + } + } + case [`+=] + { + parse RhsAsFactor: expr_factor [$AS.LValue] + send Parser + "[lvalue(AS.LValue)] := [expr_factor(RhsAsFactor)] + [expr(AS.expr)]; + } + case [`-=] + { + parse RhsAsFactor: expr_factor [$AS.LValue] + send Parser + "[lvalue(AS.LValue)] := [expr_factor(RhsAsFactor)] - [expr(AS.expr)]; + } + default { + 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<ocaml_out::ocaml_out>() + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + MO: ocaml_out::ocaml_out = Parser->finish() + + if MO { + send Output + [MO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } + +end + +void trans( Output: stream, Start: start ) +{ + ml_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' diff --git a/src/cgil/rlhc-ruby.lm b/src/cgil/rlhc-ruby.lm new file mode 100644 index 00000000..87119465 --- /dev/null +++ b/src/cgil/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' diff --git a/src/cgil/rlhc-rust.lm b/src/cgil/rlhc-rust.lm new file mode 100644 index 00000000..03f8b688 --- /dev/null +++ b/src/cgil/rlhc-rust.lm @@ -0,0 +1,534 @@ +include 'ril.lm' + +namespace rust_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 lifetime / "'" id / + + token string / + '"' ( [^"\\] | '\\' any ) * '"' | + "'" ( [^'\\] | '\\' any ) "'" + / + + ignore + /[ \t\v\r\n]+/ + end + + def item + [comment] + | [id] + | [number] + | [symbol] + | [string] + | [lifetime] + | [`{ _IN_ item* _EX_ `} ] + + def rust_out + [_IN_ _EX_ item*] +end + +namespace rust_gen + + global Parser: parser<rust_out::rust_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) C] + } + case [I: ident `[ E: expr `]] + { + send Parser + "[I]\[([expr( E )]) as usize\]" + } + case ['offset' '(' ident ',' expr ')'] + { + send Parser + "( [expr( ExprFactor.expr )] ) as i32" + } + case ['deref' '(' I: ident ',' E: expr ')'] + { + send Parser + "[I]\[([expr( E )]) as usize\] + } + 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] + { + 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 `) E: expr_factor] + { + send Parser + "( [expr_factor( E )] ) as [type(T)]" + } + case [I: ident `[ E: expr `] `. F: ident] { + send Parser + [^I '_' ^F '[' expr(E) ' as usize]'] + } + 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 O: `[ E: expr C: `]] + { + send Parser + "[I]\[([expr( E )]) as usize\] + } + 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 '[' expr(E) ' as usize]'] + } + 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 [`~ EFO: expr_factor_op] + { + send Parser + "![expr_factor_op( EFO )] + } + 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 ['i8 '] + case "s16" + send Parser ['i16 '] + case "s32" + send Parser ['i32 '] + case "s64" + send Parser ['i64 '] + case "s128" + send Parser ['i128'] + case "int" + send Parser ['i32'] + case "uint" + send Parser ['u32'] + 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 ) + { + for Number: number in NumList + send Parser "[number( Number )], " + send Parser "0" + } + + void stmt( Stmt: stmt ) + { + switch Stmt + case [EH: embedded_host] + { + send Parser + [embedded_host( EH )] + } + case [A: static_array] { + Length: int = 1 + for Number: number in A.num_list + Length = Length + 1 + + send Parser + "static [A.ident]: \[[type(A.type)]; [Length]\] = \[ [num_list(A.num_list)] \]; + } + case [V: static_value] { + send Parser + "static [V.ident]: i32 = [V.number]; + } + case [D: declaration] { + send Parser + "let mut [D.ident] " + + switch D.opt_init + case [E: `= expr] { + send Parser + "= [expr(D.opt_init.expr)]; + } + default { + send Parser + "= 0; + } + } + case [Index: index_stmt] + { + send Parser + "let mut [Index.ident] :i32" + + switch Index.opt_init + case [E: `= expr] { + send Parser + "= [expr(Index.opt_init.expr)]; + } + default { + send Parser + "= 0; + } + } + 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 + "else if ( [expr(ElseIfExpr)] ) { + " [stmt(ElseIfStmt)] + "} + } + + if ( match ElseClauseOpt ['else' ElseStmt: stmt] ) { + send Parser + "else { + " [stmt(ElseStmt)] + "} + } + } + case [`continue CL: ident `;] { + send Parser + "continue '[CL]; + } + case [`break BL: ident `;] { + send Parser + "break '[BL]; + } + case [BL: break_label? 'while' '(' WhileExpr: expr ')' '{' StmtList: stmt* '}' ] { + if match BL [bl: break_label] + send Parser "'[bl.ident]: " + + send Parser + "while ( [expr(WhileExpr)] ) { + " [stmt_list(StmtList)] + "} + } + case [`switch `( SwitchExpr: expr `) `{ StmtList: stmt* `}] { + send Parser + "match ( [expr(SwitchExpr)] ) { + " [stmt_list(StmtList)] + + NeedDef: bool = true + for Stmt: stmt in repeat(StmtList) { + if match Stmt [default_block] + NeedDef = false + } + + if NeedDef { + send Parser + " _ => {} + } + + send Parser + "} + } + case [ExprExpr: expr Semi: `;] { + send Parser + [expr(ExprExpr) Semi] + } + case [L: `{ TL: stmt* R: `}] { + send Parser + [L stmt_list(TL) R] + } + 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 + [Semi] + } + case [Export: export_stmt] + { + send Parser + "#define [Export.ident] [number(Export.number)] + } + case ['fallthrough' ';'] + { + # Nothing needed here. + } + case [case_block] + { + send Parser + "[expr( Stmt.case_block.expr )] => { + "[stmt_list( Stmt.case_block._repeat_stmt )] + "} + } + case [default_block] + { + send Parser + "_ => { + "[stmt_list( Stmt.default_block._repeat_stmt )] + "} + } + case [case_label] + { + send Parser + "case [expr( Stmt.case_label.expr )]: + } + 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<rust_out::rust_out>() + + if ( Start.opt_bom.bom ) + send Output [Start.opt_bom.bom] + + stmt_list( Start._repeat_stmt ) + + CO: rust_out::rust_out = Parser->finish() + + if CO { + send Output + [CO] + } + else { + send stderr + "failed to parse output: [Parser->error] + } + } +end + +void trans( Output: stream, Start: start ) +{ + rust_gen::trans( Output, Start ) +} + +include 'rlhc-main.lm' |