├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── examples ├── Failing │ ├── Basics │ │ ├── no_brace.c │ │ ├── no_bracket.c │ │ ├── no_func_name.c │ │ ├── no_ret.c │ │ ├── no_semi.c │ │ └── no_semi_bitwise.c │ ├── Binary │ │ ├── fail_add.c │ │ ├── fail_add.c, │ │ ├── fail_divide.c │ │ ├── fail_divide2.c │ │ ├── fail_multi.c │ │ ├── fail_multi.c, │ │ ├── fail_sub.c, │ │ └── fail_sub2.c │ ├── Binary2 │ │ ├── fail_and.c │ │ ├── fail_equals.c │ │ ├── fail_gt.c │ │ ├── fail_gte.c │ │ ├── fail_lt.c │ │ ├── fail_lte.c │ │ ├── fail_not_equals.c │ │ └── fail_or.c │ ├── Compound │ │ ├── double.c │ │ ├── extra.c │ │ ├── fail_access.c │ │ └── missing_brace.c │ ├── Functions │ │ ├── identical_dec.c │ │ └── wrong_arg.c │ ├── If │ │ ├── bad_if_assignment.c │ │ ├── bad_ternary.c │ │ ├── incomplete_tern.c │ │ └── ternary.c │ ├── Loops │ │ ├── fail_break.c │ │ ├── fail_continue.c │ │ ├── fail_for_scope.c │ │ └── fail_for_scope_2.c │ ├── Unary │ │ ├── fail_comp.c │ │ ├── fail_comp2.c │ │ ├── fail_log_neg.c │ │ ├── fail_log_neg2.c │ │ ├── fail_multi.c │ │ ├── fail_neg.c │ │ └── fail_neg2.c │ └── Variables │ │ ├── bad_type.c │ │ ├── bad_var_name.c │ │ ├── fail_add.c │ │ ├── fail_add2.c │ │ ├── fail_add3.c │ │ ├── fail_add4.c │ │ ├── fail_increment.c │ │ ├── fail_increment10.c │ │ ├── fail_increment2.c │ │ ├── fail_increment3.c │ │ ├── fail_increment4.c │ │ ├── fail_increment5.c │ │ ├── fail_increment6.c │ │ ├── fail_increment7.c │ │ ├── fail_increment9.c │ │ ├── incorrect_inc_bracketx1.c │ │ ├── incorrect_inc_bracketx2.c │ │ ├── incorrect_inc_bracketx3.c │ │ ├── late_declaration.c │ │ ├── lvalue_fail.c │ │ ├── lvalue_fail2.c │ │ ├── lvalue_fail3.c │ │ ├── multi_declare.c │ │ └── undeclared.c └── Passing │ ├── Basics │ ├── bad_styling.c │ ├── ret100.c │ └── ret42.c │ ├── Binary │ ├── add_edge.c │ ├── adding.c │ ├── bracket_add_edge.c │ ├── dividing.c │ ├── multi.c │ ├── multi2.c │ ├── multi3.c │ ├── multiplying.c │ ├── sub_edge.c │ └── subtracting.c │ ├── Binary2 │ ├── bit_left_shift2.c │ ├── bit_right_shift2.c │ ├── bitwise_and.c │ ├── bitwise_left_shift.c │ ├── bitwise_or.c │ ├── bitwise_right_shift.c │ ├── bitwise_xor.c │ ├── equal.c │ ├── greater.c │ ├── greater2.c │ ├── greater_equal.c │ ├── less.c │ ├── less_equal.c │ ├── logic_and.c │ ├── logic_or.c │ ├── logic_or2.c │ ├── modulo.c │ └── not_equal.c │ ├── Compound │ ├── dealloc.c │ ├── multi.c │ ├── multi_3.c │ ├── other_foo.c │ ├── return.c │ ├── return2.c │ ├── simple.c │ ├── simple2.c │ ├── simple3.c │ ├── simple4.c │ └── simple5.c │ ├── Functions │ ├── fib.c │ ├── multi_declare.c │ ├── multi_var.c │ ├── nested.c │ ├── no_func_call.c │ ├── predeclare.c │ ├── put_char.c │ └── simple_func.c │ ├── If │ ├── hard_0.c │ ├── hard_1.c │ ├── hard_2.c │ ├── missing_return.c │ ├── missing_return2.c │ ├── simple.c │ ├── simple2.c │ ├── simple3.c │ ├── simple4.c │ ├── simple5.c │ ├── simple6.c │ ├── simple7.c │ ├── simple8.c │ ├── ternary_chain.c │ ├── ternary_multi.c │ ├── ternary_simple.c │ └── ternary_simple2.c │ ├── Loops │ ├── bracket_for.c │ ├── break_test.c │ ├── compound_for.c │ ├── compound_for_2.c │ ├── do_continue.c │ ├── multi_cmpd.c │ ├── nested_do.c │ ├── nested_for_1.c │ ├── nested_for_2.c │ ├── nested_for_3.c │ ├── nested_for_while.c │ ├── nested_while.c │ ├── null_statement.c │ ├── simple_break.c │ ├── simple_continue.c │ ├── simple_do.c │ ├── simple_for.c │ ├── simple_for_2.c │ ├── simple_for_3.c │ ├── simple_for_4.c │ ├── simple_for_5.c │ ├── simple_for_6.c │ ├── simple_for_7.c │ ├── simple_while.c │ └── simple_while_2.c │ ├── Unary │ ├── bitwise_non_zero.c │ ├── bitwise_zero.c │ ├── bracket_negate.c │ ├── logical_negate_non_zero.c │ ├── logical_negate_zero.c │ ├── negate_zero.c │ ├── negation.c │ ├── nested_unary.c │ ├── not_forty_two.c │ └── not_zero.c │ └── Variables │ ├── add_return.c │ ├── and_assign.c │ ├── assign_div.c │ ├── assign_mul.c │ ├── assign_sub.c │ ├── assign_sum.c │ ├── assign_val_double.c │ ├── assign_val_double2.c │ ├── chain.c │ ├── correct_dec.c │ ├── correct_dec2.c │ ├── correct_inc.c │ ├── correct_inc2.c │ ├── correct_inc_bracket.c │ ├── correct_inc_bracketx3.c │ ├── correct_inc_mixed.c │ ├── decrement.c │ ├── dumb_standalone_exp.c │ ├── inc_chain.c │ ├── increment.c │ ├── large.c │ ├── long_no_ret.c │ ├── lshift.c │ ├── massive.c │ ├── missing_ret.c │ ├── mixed2.c │ ├── multi_assign.c │ ├── multi_assign2.c │ ├── no_assign.c │ ├── no_statement.c │ ├── or_assign.c │ ├── prefix_add.c │ ├── reuse.c │ ├── rshift.c │ ├── simple.c │ ├── thicc.c │ ├── unused_statement.c │ ├── unused_statement2.c │ ├── wtf.c │ └── xor_assign.c ├── failed_test_script.sh ├── rustcc.sh ├── src ├── main.rs ├── parser.rs └── parser │ └── lexer.rs └── test_script.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | # C stuff 13 | # Prerequisites 14 | *.d 15 | *.s 16 | 17 | # Object files 18 | *.o 19 | *.ko 20 | *.obj 21 | *.elf 22 | 23 | # Linker output 24 | *.ilk 25 | *.map 26 | *.exp 27 | 28 | # Precompiled Headers 29 | *.gch 30 | *.pch 31 | 32 | # Libraries 33 | *.lib 34 | *.a 35 | *.la 36 | *.lo 37 | 38 | # Shared objects (inc. Windows DLLs) 39 | *.dll 40 | *.so 41 | *.so.* 42 | *.dylib 43 | 44 | # Executables 45 | *.exe 46 | *.out 47 | *.app 48 | *.i*86 49 | *.x86_64 50 | *.hex 51 | 52 | # Debug files 53 | *.dSYM/ 54 | *.su 55 | *.idb 56 | *.pdb 57 | 58 | # Kernel Module Compile Results 59 | *.mod* 60 | *.cmd 61 | .tmp_versions/ 62 | modules.order 63 | Module.symvers 64 | Mkfile.old 65 | dkms.conf 66 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustcc" 3 | version = "0.1.0" 4 | authors = ["ClementTsang "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Clement Tsang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rustcc - a Rust C compiler 2 | A basic C compiler written in Rust that compiles C code into x86 assembly, following GAS/AT&T syntax, with no external Rust dependencies. Inspired by [this post by Nora Sandler](https://norasandler.com/2017/11/29/Write-a-Compiler.html). 3 | 4 | Note this was done for learning purposes as my intro to Rust, and isn't intended to be used too seriously. 5 | 6 | ## Features 7 | Currently, rustcc supports the following features: 8 | * Unary operators (logical negation, bitwise complements, negation) 9 | * Binary operators (basic arithmetic, bitwise operations, comparisons) 10 | * Local variables (assignment, declaration, variable calling, postfix and prefix incrementing) 11 | * If-else branching 12 | * Ternary operator 13 | * While loops, do-while loops, for loops, break, continue 14 | * Function calling and creation 15 | 16 | As of now, rustcc only supports variables of type int. 17 | 18 | 19 | ## Installation 20 | To install, ensure beforehand that you have [Rust and Cargo installed.](https://www.rust-lang.org/tools/install) After that, clone the repository. Then, run ``cargo build --release``. 21 | 22 | ## Usage 23 | To use the compiler, run the `rustcc` script as follows: 24 | ``` 25 | ./rustcc /path/to/source.c 26 | ``` 27 | Upon running, the compiled executable file will be in the same directory and name as the input source file. The created assembly ``source.s`` file will be deleted upon running the script. 28 | 29 | Alternatively, you can directly run ``./target/release/rustcc /path/to/source.c`` (or ``target/release/rustcc.exe /path/to/source.c`` on Windows) to retain the assembly file. 30 | 31 | ## Disclaimer 32 | rustcc is a project done purely out of personal interest. The compiled x86 code is most likely not optimized and the possibility of something not working or being supported is quite probable. I am not responsible for anything going wrong with the use of this. 33 | 34 | 35 | -------------------------------------------------------------------------------- /examples/Failing/Basics/no_brace.c: -------------------------------------------------------------------------------- 1 | int main() 2 | return 100; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Basics/no_bracket.c: -------------------------------------------------------------------------------- 1 | int main { 2 | return 100; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Basics/no_func_name.c: -------------------------------------------------------------------------------- 1 | int () { 2 | return 100; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Basics/no_ret.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Basics/no_semi.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 100 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Basics/no_semi_bitwise.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return ~0 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_add.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 +; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_add.c,: -------------------------------------------------------------------------------- 1 | int main () { 2 | return (5 + 1; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_divide.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 / 0; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_divide2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return / 2; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_multi.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return *5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_multi.c,: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 * 7 *; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_sub.c,: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 -; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary/fail_sub2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 -; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_and.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 && ; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_equals.c: -------------------------------------------------------------------------------- 1 | int main { 2 | return 5 == 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_gt.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 > 6; 3 | 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_gte.c: -------------------------------------------------------------------------------- 1 | int main () 2 | { return 5 >= 6; 3 | 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_lt.c: -------------------------------------------------------------------------------- 1 | int main () 2 | return 5 < 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_lte.c: -------------------------------------------------------------------------------- 1 | int main () 2 | {return 5<=2} 3 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_not_equals.c: -------------------------------------------------------------------------------- 1 | int main ( { 2 | return 5 != 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Binary2/fail_or.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return || 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Compound/double.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | { 3 | int a; 4 | int a; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/Failing/Compound/extra.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if(0 == 0){ 3 | return 5; 4 | }} 5 | return 5; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Failing/Compound/fail_access.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | { 3 | int foo = 2; 4 | } 5 | 6 | return foo; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Failing/Compound/missing_brace.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | { 4 | a = 10; 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Failing/Functions/identical_dec.c: -------------------------------------------------------------------------------- 1 | int foo(int a, int b); 2 | 3 | int foo(int a) { 4 | return a; 5 | } 6 | 7 | int main() { 8 | return foo(5); 9 | } 10 | -------------------------------------------------------------------------------- /examples/Failing/Functions/wrong_arg.c: -------------------------------------------------------------------------------- 1 | int foo (int a) { 2 | return a; 3 | } 4 | 5 | int main() { 6 | return foo(5, 6); 7 | } 8 | -------------------------------------------------------------------------------- /examples/Failing/If/bad_if_assignment.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a= if (1 > 5) 3 | 2; 4 | else 5 | 3; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Failing/If/bad_ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | (5 > 6) ? return 1 : return 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/If/incomplete_tern.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 ? 2; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/If/ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 ? 2 ? 3 : 4; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Loops/fail_break.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | break; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Loops/fail_continue.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a= 5; 3 | continue; 4 | return 5; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Loops/fail_for_scope.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 0; i < 5; ++i) { 3 | } 4 | 5 | return i; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Failing/Loops/fail_for_scope_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 0; i < 5; ++i) { 3 | int a = 5; 4 | ++a; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Failing/Unary/fail_comp.c: -------------------------------------------------------------------------------- 1 | int main { 2 | return ~1 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Unary/fail_comp2.c: -------------------------------------------------------------------------------- 1 | int main ((( { 2 | return ~153; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Unary/fail_log_neg.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !1 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Unary/fail_log_neg2.c: -------------------------------------------------------------------------------- 1 | int main { 2 | return !2; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Unary/fail_multi.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !~-!~-5; 3 | 4 | -------------------------------------------------------------------------------- /examples/Failing/Unary/fail_neg.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -5 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Unary/fail_neg2.c: -------------------------------------------------------------------------------- 1 | int main( { 2 | return -5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Failing/Variables/bad_type.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | inasvadfvqasd a = 5; 3 | return a; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Failing/Variables/bad_var_name.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a b = 5; 3 | return b; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_add.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | (a + 5) += 6; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_add2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 6; 3 | 5 += 6; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_add3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | a += 5; 3 | int a = 5; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_add4.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 6; 3 | 6 += a; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | ++5; 3 | return 10; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment10.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b = 10; 4 | (a + b)++; 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | ++(++a); 4 | } 5 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | ++a; 3 | int a = 5; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment4.c: -------------------------------------------------------------------------------- 1 | int main () { int a = 5; ++a++; return a; 2 | } 3 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment5.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 100; 3 | a++; 4 | return (a++)++; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment6.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return (((((++(((a))))))); 4 | } 5 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment7.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 10; 3 | ++((((((1+1)))))); 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/fail_increment9.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b = 6; 4 | ++(a + b); 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/incorrect_inc_bracketx1.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 100; 3 | ++(a)); 4 | ++((a); 5 | (a))++; 6 | ((a)++; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Failing/Variables/incorrect_inc_bracketx2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | ((a)++; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/incorrect_inc_bracketx3.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 5; 3 | ++((a); 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/late_declaration.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | a = 5; 3 | int a; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/lvalue_fail.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 5; 3 | !a = 6; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/lvalue_fail2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int al = 5; 3 | ~al = 5; 4 | return al; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/lvalue_fail3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int vs = 5; 3 | /vs = 6; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Failing/Variables/multi_declare.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 6; 3 | int a = 5; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Failing/Variables/undeclared.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return a; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Basics/bad_styling.c: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | return 42 ; } 4 | -------------------------------------------------------------------------------- /examples/Passing/Basics/ret100.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 100; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Basics/ret42.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 42; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary/add_edge.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return + 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary/adding.c: -------------------------------------------------------------------------------- 1 | int main () { return 4 + 5; } 2 | -------------------------------------------------------------------------------- /examples/Passing/Binary/bracket_add_edge.c: -------------------------------------------------------------------------------- 1 | int main(){return(+6);} 2 | -------------------------------------------------------------------------------- /examples/Passing/Binary/dividing.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return (11 / 5); 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary/multi.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -(5 * 6 + 8 / 4 * 5 - 2) * 3; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary/multi2.c: -------------------------------------------------------------------------------- 1 | int main(){return !-!-(~!-4+-6*!0/5-!!!9);} 2 | -------------------------------------------------------------------------------- /examples/Passing/Binary/multi3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return (5 + -!0) / -~(5 * 7 * -!0) + -~5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary/multiplying.c: -------------------------------------------------------------------------------- 1 | int main () 2 | { 3 | return (5 * 6); 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Binary/sub_edge.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return - 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary/subtracting.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 - -6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/bit_left_shift2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return a << 1; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/bit_right_shift2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return a >> 1; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/bitwise_and.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 & 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/bitwise_left_shift.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 << 1; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/bitwise_or.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 | 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/bitwise_right_shift.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 592474 >> 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/bitwise_xor.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 ^ 3; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/equal.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 == 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/greater.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 > 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/greater2.c: -------------------------------------------------------------------------------- 1 | int main() 2 | {return 5>2; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/greater_equal.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 >= 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/less.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 < 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/less_equal.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 <= 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/logic_and.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return (5 && 0); 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/logic_or.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 || 0; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/logic_or2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return (0 ||0); 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/modulo.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 5 % 2; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Binary2/not_equal.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | return 5 != 6; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Compound/dealloc.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | { 3 | int i = 0; 4 | } 5 | int j = 1; 6 | return j; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Compound/multi.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | { 4 | int a = 6; 5 | { 6 | a = 100; 7 | { 8 | int a = 1000; 9 | } 10 | } 11 | a = 123; 12 | } 13 | return a; 14 | } 15 | -------------------------------------------------------------------------------- /examples/Passing/Compound/multi_3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 100; 3 | { 4 | int a = 5; 5 | { 6 | int j = a + i; 7 | return a; 8 | } 9 | } 10 | return 100; 11 | } 12 | -------------------------------------------------------------------------------- /examples/Passing/Compound/other_foo.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int foo = 100; 3 | { 4 | int foo; 5 | foo = 15; 6 | } 7 | return foo; 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/Compound/return.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | { 3 | return 2; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Compound/return2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (0) { 3 | return 5; 4 | } 5 | 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Compound/simple.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 5; 3 | int b = 10; 4 | int cintd = 11; 5 | int intent10 = 100; 6 | 7 | if (a == b) { 8 | if (cintd) { 9 | return intent10; 10 | } 11 | else { 12 | b = 100; 13 | return b; 14 | } 15 | }else{ 16 | if (intent10 == 100) { 17 | cintd += 501; 18 | } 19 | else { 20 | cintd += 1000; 21 | } 22 | 23 | cintd += b; 24 | } 25 | return cintd; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /examples/Passing/Compound/simple2.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | if (0) { 3 | return 10; 4 | } 5 | else { 6 | return 5; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/Compound/simple3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | { 4 | a = 4; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Compound/simple4.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | { 4 | a = 2; 5 | { 6 | a = 3; 7 | { 8 | if (a) { 9 | a = 15; 10 | } 11 | } 12 | } 13 | } 14 | 15 | return a; 16 | } 17 | -------------------------------------------------------------------------------- /examples/Passing/Compound/simple5.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 5; 3 | {} 4 | {} 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Functions/fib.c: -------------------------------------------------------------------------------- 1 | int fib (int n) { 2 | if (n == 0 || n == 1) { 3 | return n; 4 | } 5 | return fib(n-1) + fib(n-2); 6 | } 7 | 8 | int main() { 9 | return fib(5) + fib(6) + fib (7); 10 | } 11 | -------------------------------------------------------------------------------- /examples/Passing/Functions/multi_declare.c: -------------------------------------------------------------------------------- 1 | int foo (); 2 | 3 | int foo (); 4 | 5 | int foo() { 6 | return 5; 7 | } 8 | 9 | int main() { 10 | return foo(); 11 | } 12 | -------------------------------------------------------------------------------- /examples/Passing/Functions/multi_var.c: -------------------------------------------------------------------------------- 1 | int foo (int a, int b) { 2 | return a + b; 3 | } 4 | 5 | int main() { 6 | return foo(5, 6); 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Functions/nested.c: -------------------------------------------------------------------------------- 1 | int a () { 2 | return 5; 3 | } 4 | 5 | int b () { 6 | return 6; 7 | } 8 | 9 | int c (int one, int two) { 10 | return one + two; 11 | } 12 | 13 | int main() { 14 | return c(a(), b()); 15 | } 16 | -------------------------------------------------------------------------------- /examples/Passing/Functions/no_func_call.c: -------------------------------------------------------------------------------- 1 | int foo (int a, int b, int c) { 2 | return a + b + c; 3 | } 4 | 5 | int main() { 6 | return 5; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Functions/predeclare.c: -------------------------------------------------------------------------------- 1 | int foo(int a); 2 | 3 | int main() { 4 | return foo(15); 5 | } 6 | 7 | int foo (int a) { 8 | return a + 1000; 9 | } 10 | -------------------------------------------------------------------------------- /examples/Passing/Functions/put_char.c: -------------------------------------------------------------------------------- 1 | int putchar(int c); 2 | 3 | int main() { 4 | putchar(72); 5 | putchar(101); 6 | putchar(108); 7 | putchar(108); 8 | putchar(111); 9 | putchar(44); 10 | putchar(32); 11 | putchar(87); 12 | putchar(111); 13 | putchar(114); 14 | putchar(108); 15 | putchar(100); 16 | putchar(33); 17 | putchar(10); 18 | } 19 | -------------------------------------------------------------------------------- /examples/Passing/Functions/simple_func.c: -------------------------------------------------------------------------------- 1 | int foo (int a, int b) { 2 | return a + 100 + b; 3 | } 4 | 5 | int main() { 6 | int a = 5; 7 | return (foo(a, 10)); 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/If/hard_0.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b = 404; 4 | 5 | if (b == a) b = 15; 6 | else if (b < a) return a; 7 | return b; 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/If/hard_1.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b = 10; 4 | if (a == b) b = 15; 5 | else if (a > b) b = 5; 6 | else if (a < b - 9) b = 100; 7 | else b = (1 < 2) ? 404 : 505; 8 | 9 | if (b == a) b = 15; 10 | else if (b < a) return a; 11 | return b; 12 | } 13 | -------------------------------------------------------------------------------- /examples/Passing/If/hard_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int b = 5; 3 | if (b == 5) b = (b == 6) ? 7 : 8; 4 | else b = b == 7 ? 9 : 10; 5 | 6 | b = 505; 7 | return b; 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/If/missing_return.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | if (a == 5) 4 | return 5; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/If/missing_return2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (5 > 6) 3 | return 5; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/If/simple.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | if (a == 5) 4 | return a; 5 | else if (a == 6) 6 | return a + 1; 7 | else 8 | return 101; 9 | } 10 | -------------------------------------------------------------------------------- /examples/Passing/If/simple2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 6; 3 | if (a == 5) 4 | return a; 5 | else if (a == 6) 6 | return a + 1; 7 | else 8 | return 101; 9 | } 10 | -------------------------------------------------------------------------------- /examples/Passing/If/simple3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 7; 3 | if (a == 5) 4 | return a; 5 | else if (a == 6) 6 | return a + 1; 7 | else 8 | return 101; 9 | } 10 | -------------------------------------------------------------------------------- /examples/Passing/If/simple4.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | if (a == 5) return 5; 4 | else return 10; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/If/simple5.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (15 == 5) 3 | return 5; 4 | return 100; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/If/simple6.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (1) return 5; 3 | else return 6; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/If/simple7.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (0) return 5; 3 | return 100; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/If/simple8.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | if (0) return 5; 3 | else if (0) return 6; 4 | return 7; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/If/ternary_chain.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return (5 > 6) ? 5 : (6 < 7) ? 100 : (5 > 5) ? 1001 : 4; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/If/ternary_multi.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = (1 == 1) ? 1 : 2; 3 | int b = (a == 1) ? 5 : 3; 4 | return (a == b) ? 5 : 101; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/If/ternary_simple.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | a = (5 > 6) ? a : 8; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/If/ternary_simple2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | a = (5 < 6) ? a : 8; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Loops/bracket_for.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | for (int i = (1 + 2 + 3); i < (5 * 6); i = i + (1 * 2 + 3)) { 4 | a += i; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/break_test.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | while (1) { 3 | while (2) { 4 | break; 5 | } 6 | break; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/Loops/compound_for.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 5; 3 | int a = 5; 4 | for (int i = 0; i < 5; ++i) { 5 | { 6 | int i = 100; 7 | a += i; 8 | } 9 | a += i; 10 | } 11 | a += i; 12 | return a; 13 | } 14 | -------------------------------------------------------------------------------- /examples/Passing/Loops/compound_for_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 4; 3 | int a = 5; 4 | for (int i = 0; i < 5; ++i) { 5 | { 6 | int i = 100; 7 | a += i; 8 | } 9 | a += i; 10 | } 11 | a += i; 12 | return a; 13 | } 14 | -------------------------------------------------------------------------------- /examples/Passing/Loops/do_continue.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | 4 | do { 5 | if (a % 2 == 0) { 6 | ++a; 7 | continue; 8 | } 9 | ++a; 10 | } while (a < 10); 11 | 12 | return a; 13 | } 14 | -------------------------------------------------------------------------------- /examples/Passing/Loops/multi_cmpd.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 5; 3 | { 4 | int i = 100; 5 | { 6 | { 7 | for (int i = 0; i < 150; ++i) { 8 | ++i; 9 | } 10 | } 11 | } 12 | } 13 | return i; 14 | } 15 | -------------------------------------------------------------------------------- /examples/Passing/Loops/nested_do.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | do { 4 | int i = 5; 5 | do { 6 | ++i; 7 | ++a; 8 | } while(i < 100); 9 | } while(a < 500); 10 | 11 | return a; 12 | } -------------------------------------------------------------------------------- /examples/Passing/Loops/nested_for_1.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | for (int i = 0; i < 5; ++i) { 4 | for (int j = 0 ; j < 10; j++) { 5 | a += j; 6 | } 7 | a -= i; 8 | } 9 | return a; 10 | } 11 | -------------------------------------------------------------------------------- /examples/Passing/Loops/nested_for_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | for (int i = 0; i < 2; ++i) { 4 | for (int j = 0 ; j < 5; j++) { 5 | a += j; 6 | } 7 | } 8 | return a; 9 | } 10 | -------------------------------------------------------------------------------- /examples/Passing/Loops/nested_for_3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | int i = 0; 4 | for (; i < 2; ++i) { 5 | int j = 0; 6 | for (; j < 3; j++) { 7 | a += j; 8 | } 9 | } 10 | return a; 11 | } 12 | -------------------------------------------------------------------------------- /examples/Passing/Loops/nested_for_while.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 10; 3 | int b = 0; 4 | for (int i = 0; i < 5; ++i) { 5 | while (a > 0) { 6 | --a; 7 | b += a; 8 | } 9 | b += i; 10 | } 11 | 12 | return b; 13 | } -------------------------------------------------------------------------------- /examples/Passing/Loops/nested_while.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b = 10; 4 | while (a < 100) { 5 | while (b < 100) { 6 | a += 5; 7 | b += a; 8 | } 9 | a += b; 10 | } 11 | return a + b; 12 | } 13 | -------------------------------------------------------------------------------- /examples/Passing/Loops/null_statement.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | ; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_break.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | while (1) { 4 | ++a; 5 | if (a < 100) { 6 | break; 7 | } 8 | } 9 | return a; 10 | } 11 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_continue.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | for (int i = 0; i < 100; ++i) { 4 | if (i % 2 == 1) { 5 | continue; 6 | } 7 | a += i; 8 | } 9 | return a; 10 | } 11 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_do.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | do { 4 | ++a; 5 | }while (a < 100); 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_for.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | for (int i = 0; i < 5; ++i) { 4 | a += i; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_for_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i; 3 | for (i = 0; i < 10; ++i) { 4 | ; 5 | } 6 | return i; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_for_3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | for (;;) { 4 | break; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_for_4.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 6; 3 | for(;1;) { 4 | break; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_for_5.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | for (int i = 5; i < 5; ++i) { 4 | a++; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_for_6.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 0; i < 5; ++i) { 3 | return i; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_for_7.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | for (int i = 0; i < 5; ++i) { 4 | a += i; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_while.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | while (a < 15) { 4 | ++a; 5 | } 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Loops/simple_while_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | while (1) { 3 | return 1; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Unary/bitwise_non_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return ~4; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/bitwise_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return ~0; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/bracket_negate.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -(-(-5)); 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/logical_negate_non_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/logical_negate_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !0; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/negate_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -0; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/negation.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/nested_unary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !~-!~-1; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/not_forty_two.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !42; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Unary/not_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !0; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Variables/add_return.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b = 6; 4 | b = 6 + 7; 5 | b += 7; 6 | return (a += b); 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Variables/and_assign.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 52; 3 | a &= 6; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/assign_div.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 15; 3 | a /= 3; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/assign_mul.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 6; 3 | a *= 5; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/assign_sub.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | a -= 3; 4 | a -= 1; 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Variables/assign_sum.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | a += 5; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/assign_val_double.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 1; 3 | int b = a = 5; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/assign_val_double2.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 1; 3 | int b = a = 5; 4 | return b; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/chain.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 5; 3 | int b = 6; 4 | int c = 7; 5 | int d = 8; 6 | int e = (a = 5) + (b = 5) + (c = 5) + (d = 5); 7 | return (e + a + b + c + d + e) / 5; 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/Variables/correct_dec.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return a--; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Variables/correct_dec2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return --a; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Variables/correct_inc.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return a++; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Variables/correct_inc2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return ++a; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Variables/correct_inc_bracket.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | ++(a); 4 | (a)++; 5 | --(a); 6 | (a)--; 7 | return a; 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/Variables/correct_inc_bracketx3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 10; 3 | ++((((((((((a)))))))))); 4 | (((((((((a)))))))))++; 5 | return (((((((a)))))))++; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Variables/correct_inc_mixed.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b =100; 4 | b += (a)+++b; 5 | b = (((((b))))) + ++((a)); 6 | b -= (++(((((a)))))); 7 | return b; 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/Variables/decrement.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | --a; 4 | a--; 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Variables/dumb_standalone_exp.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | 2 + 2; 3 | 3 + 3; 4 | 4 + 4; 5 | return 5; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Variables/inc_chain.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5 + 0 / 3 + 5 ^ 7 >> 6; 3 | int b = 6 + a / 5 - 7; 4 | (++a); 5 | (b++); 6 | a += (b + 5); 7 | return (a + b); 8 | } 9 | -------------------------------------------------------------------------------- /examples/Passing/Variables/increment.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int b = 5; 3 | ++b; 4 | b ++; 5 | b++; 6 | return ++b; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Variables/large.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int abc = 123; 3 | int def = 1435; 4 | int vsvd = def; 5 | int asada = vsvd = 5; 6 | return asada + vsvd - abc + def; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Variables/long_no_ret.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | int b; 4 | a = 5; 5 | b = 5; 6 | a = b + a + 5; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Variables/lshift.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | a >>= 6; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/massive.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int abcd = 5; 3 | --abcd; 4 | abcd += 101; 5 | int kgk = 404; 6 | kgk++; 7 | 8 | kgk *= abcd; 9 | abcd /= abcd; 10 | kgk--; 11 | return (kgk + ++abcd); 12 | } 13 | -------------------------------------------------------------------------------- /examples/Passing/Variables/missing_ret.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Variables/mixed2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | int b = a + 6; 4 | int c = a++ * 5 / -(--b + 5); 5 | int d = ++c + --b + a++; 6 | d *= 5; 7 | d *= ++c; 8 | b ^= d; 9 | return ++d + b + c-- * ++a; 10 | } 11 | -------------------------------------------------------------------------------- /examples/Passing/Variables/multi_assign.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | int b = 3; 4 | a = 2 * (b = 2); 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Variables/multi_assign2.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 2 - 1 + 3; 3 | int b = 5 * 6 / 2; 4 | int c = !0 + (6 / 2) + !1 + ~1 - -5; 5 | return -((a + b) * c); 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Variables/no_assign.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | int b; 4 | int c; 5 | return 5; 6 | } 7 | -------------------------------------------------------------------------------- /examples/Passing/Variables/no_statement.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Variables/or_assign.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 52; 3 | a |= 6; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/prefix_add.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 5; 3 | return ++a; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Variables/reuse.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | int b; 4 | a = 5; 5 | b = 5; 6 | a = b + a + 5; 7 | b = a * 2 + b; 8 | return a + b; 9 | } 10 | -------------------------------------------------------------------------------- /examples/Passing/Variables/rshift.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int b = 16; 3 | b <<= 4; 4 | return b; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/simple.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | a = a + 1; 4 | return a * 2; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/thicc.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int test = 5; 3 | int var = 6; 4 | int bazing = (test = 7 + (var = 9)); 5 | bazing = bazing - 5; 6 | return bazing; 7 | } 8 | -------------------------------------------------------------------------------- /examples/Passing/Variables/unused_statement.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | 2 + 5; 3 | } 4 | -------------------------------------------------------------------------------- /examples/Passing/Variables/unused_statement2.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | 2 + 5; 3 | return 54; 4 | } 5 | -------------------------------------------------------------------------------- /examples/Passing/Variables/wtf.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int b = 1; 3 | int a = b = 6; 4 | return b; 5 | } 6 | -------------------------------------------------------------------------------- /examples/Passing/Variables/xor_assign.c: -------------------------------------------------------------------------------- 1 | int main () { 2 | int a = 52; 3 | a ^= 6; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /failed_test_script.sh: -------------------------------------------------------------------------------- 1 | ./test_script.sh | egrep 'FAILED|Saw|Failed' 2 | -------------------------------------------------------------------------------- /rustcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$#" -ne 1 ]]; then 4 | echo "Invalid number of arguments." 5 | fi 6 | 7 | ./target/release/rustcc ${1} &> /dev/null 8 | 9 | if [[ $? != 0 ]]; then 10 | echo "Failed to properly produce a file." 11 | exit 101 12 | fi 13 | 14 | gcc -m32 "${1%.*}.s" -o "${1%.*}" 15 | rm "${1%.*}.s" 16 | 17 | -------------------------------------------------------------------------------- /src/parser.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_parens)] 2 | #![allow(unused_variables)] 3 | #![allow(while_true)] 4 | 5 | pub mod lexer; 6 | use std::fs; 7 | 8 | pub struct Program { 9 | pub list_of_fnc : Vec, 10 | } 11 | 12 | pub struct Function { 13 | pub name : String, 14 | pub return_type : String, 15 | pub list_of_blk : Vec, 16 | pub params : Vec, 17 | pub is_definition : bool, 18 | } 19 | 20 | pub struct Parameter { 21 | pub name : String, 22 | pub param_type : String, 23 | } 24 | 25 | pub struct FnCall { 26 | pub name : String, 27 | pub args : Vec, 28 | } 29 | 30 | pub struct BlockItem { 31 | pub state : Option, 32 | pub decl : Option, 33 | } 34 | 35 | pub struct Compound { 36 | pub list_of_blk : Vec, 37 | } 38 | 39 | pub struct For { 40 | pub optional_exp_1 : Option, 41 | pub exp : Assignment, 42 | pub optional_exp_2 : Option, 43 | pub statement : Box, 44 | } 45 | 46 | pub struct ForDecl { 47 | pub decl : Declaration, 48 | pub exp : Assignment, 49 | pub optional_exp_2 : Option, 50 | pub statement : Box, 51 | } 52 | 53 | pub struct While { 54 | pub exp : Assignment, 55 | pub statement : Box, 56 | } 57 | 58 | pub struct DoWhile { 59 | pub statement : Box, 60 | pub exp : Assignment, 61 | } 62 | 63 | pub struct Break { 64 | // Empty 65 | } 66 | 67 | pub struct Continue { 68 | // Empty 69 | } 70 | 71 | pub struct Statement { 72 | pub name : String, 73 | pub compound : Option, 74 | pub exp : Option, 75 | pub _if : Option, 76 | pub _for : Option, 77 | pub _for_decl : Option, 78 | pub _while : Option, 79 | pub _do : Option, 80 | pub _break : Option, 81 | pub _continue : Option, 82 | } 83 | 84 | pub struct Assignment { 85 | pub var : Option, 86 | pub assign : Option>, 87 | pub exp : Option, 88 | pub op : String, 89 | } 90 | 91 | pub struct ConditionalExp { 92 | pub exp : OrExpression, 93 | pub true_exp : Option>, 94 | pub false_exp : Option>, 95 | } 96 | 97 | pub struct Declaration { 98 | pub var : Variable, 99 | pub exp : Assignment, 100 | pub var_type : String, 101 | } 102 | 103 | pub struct Variable { 104 | pub var_name : String, 105 | } 106 | 107 | pub struct If { 108 | pub cond : Assignment, 109 | pub state : Option>, 110 | pub else_state : Option>, 111 | } 112 | 113 | pub struct OrExpression { 114 | pub op : String, 115 | pub left_exp : Option>, 116 | pub left_and_exp : Option>, 117 | pub right_and_exp : Option>, 118 | } 119 | 120 | pub struct AndExpression { 121 | pub op : String, 122 | pub left_exp : Option>, 123 | pub left_child : Option>, 124 | pub right_child : Option>, 125 | } 126 | 127 | pub struct BitOr { 128 | pub op : String, 129 | pub left_exp : Option>, 130 | pub left_child : Option>, 131 | pub right_child : Option>, 132 | } 133 | 134 | pub struct BitXor { 135 | pub op : String, 136 | pub left_exp : Option>, 137 | pub left_child : Option>, 138 | pub right_child : Option>, 139 | } 140 | 141 | pub struct BitAnd { 142 | pub op : String, 143 | pub left_exp : Option>, 144 | pub left_child : Option>, 145 | pub right_child : Option>, 146 | } 147 | 148 | pub struct EqualityExp { 149 | pub op : String, 150 | pub left_exp : Option>, 151 | pub left_relation_exp : Option>, 152 | pub right_relation_exp : Option>, 153 | } 154 | 155 | pub struct RelationalExp { 156 | pub op : String, 157 | pub left_exp : Option>, 158 | pub left_child : Option>, 159 | pub right_child : Option>, 160 | } 161 | 162 | pub struct BitShift { 163 | pub op : String, 164 | pub left_exp : Option>, 165 | pub left_child : Option>, 166 | pub right_child : Option>, 167 | } 168 | 169 | pub struct AdditiveExp { 170 | pub op : String, 171 | pub left_exp : Option>, 172 | pub left_term : Option>, 173 | pub right_term : Option>, 174 | } 175 | 176 | pub struct Term { 177 | pub op : String, 178 | pub left_term : Option>, 179 | pub left_child : Option>, 180 | pub right_child : Option>, 181 | } 182 | 183 | pub struct Factor { 184 | pub op : String, 185 | pub unary : Option>, 186 | pub postfix_unary : Option>, 187 | pub exp : Option>, 188 | pub val : Option, 189 | pub var : Option, 190 | pub fn_call : Option, 191 | } 192 | 193 | pub struct Unary { 194 | pub op : String, 195 | pub child : Option>, 196 | } 197 | 198 | pub struct PostFixUnary { 199 | pub op : String, 200 | pub child : Option>, 201 | } 202 | 203 | impl Program { 204 | pub fn new () -> Program { 205 | Program { 206 | list_of_fnc : Vec::new(), 207 | } 208 | } 209 | } 210 | 211 | impl Function { 212 | pub fn new () -> Function { 213 | Function { 214 | name : String::new(), 215 | return_type : String::new(), 216 | list_of_blk : Vec::new(), 217 | params : Vec::new(), 218 | is_definition : false, 219 | } 220 | } 221 | } 222 | 223 | impl FnCall { 224 | pub fn new () -> FnCall { 225 | FnCall { 226 | name : String::new(), 227 | args : Vec::new(), 228 | } 229 | } 230 | } 231 | 232 | impl BlockItem { 233 | pub fn new () -> BlockItem { 234 | BlockItem { 235 | state : None, 236 | decl : None, 237 | } 238 | } 239 | } 240 | 241 | impl Parameter { 242 | pub fn new() -> Parameter { 243 | Parameter { 244 | name : String::new(), 245 | param_type : String::new(), 246 | } 247 | } 248 | } 249 | 250 | impl Compound { 251 | pub fn new () -> Compound { 252 | Compound { 253 | list_of_blk : Vec::new(), 254 | } 255 | } 256 | } 257 | 258 | impl For { 259 | pub fn new() -> For { 260 | For { 261 | exp : Assignment::new(), 262 | optional_exp_1 : None, 263 | optional_exp_2 : None, 264 | statement : Box::new(Statement::new()), 265 | } 266 | } 267 | } 268 | 269 | impl ForDecl { 270 | pub fn new() -> ForDecl { 271 | ForDecl { 272 | exp : Assignment::new(), 273 | decl : Declaration::new(), 274 | optional_exp_2 : None, 275 | statement : Box::new(Statement::new()), 276 | } 277 | } 278 | } 279 | 280 | impl DoWhile { 281 | pub fn new() -> DoWhile { 282 | DoWhile { 283 | exp : Assignment::new(), 284 | statement : Box::new(Statement::new()), 285 | } 286 | } 287 | } 288 | 289 | impl Break { 290 | pub fn new() -> Break { 291 | Break { 292 | 293 | } 294 | } 295 | } 296 | 297 | impl Continue { 298 | pub fn new() -> Continue { 299 | Continue { 300 | 301 | } 302 | } 303 | } 304 | 305 | impl While { 306 | pub fn new() -> While { 307 | While { 308 | exp : Assignment::new(), 309 | statement : Box::new(Statement::new()), 310 | } 311 | } 312 | } 313 | 314 | impl Statement { 315 | pub fn new () -> Statement { 316 | Statement { 317 | name : String::new(), 318 | compound : None, 319 | exp : None, 320 | _if : None, 321 | _for : None, 322 | _for_decl : None, 323 | _do : None, 324 | _break : None, 325 | _continue : None, 326 | _while : None, 327 | } 328 | } 329 | } 330 | 331 | impl Assignment { 332 | pub fn new() -> Assignment { 333 | Assignment { 334 | var : None, 335 | assign : None, 336 | exp : None, 337 | op : String::new(), 338 | } 339 | } 340 | 341 | pub fn set_to_zero() -> Assignment { 342 | Assignment { 343 | var : None, 344 | assign : None, 345 | exp : Some(ConditionalExp::set_to_zero()), 346 | op : String::new(), 347 | } 348 | } 349 | 350 | pub fn set_to_one() -> Assignment { 351 | Assignment { 352 | var : None, 353 | assign : None, 354 | exp : Some(ConditionalExp::set_to_one()), 355 | op : String::new(), 356 | } 357 | } 358 | } 359 | 360 | impl Declaration { 361 | pub fn new() -> Declaration { 362 | Declaration { 363 | var : Variable::new(), 364 | exp : Assignment::new(), 365 | var_type : String::new(), 366 | } 367 | } 368 | } 369 | 370 | impl Variable { 371 | pub fn new() -> Variable { 372 | Variable { 373 | var_name : String::new(), 374 | } 375 | } 376 | } 377 | 378 | impl If { 379 | pub fn new() -> If { 380 | If { 381 | cond : Assignment::new(), 382 | state : None, 383 | else_state : None, 384 | } 385 | } 386 | } 387 | 388 | impl ConditionalExp { 389 | pub fn new() -> ConditionalExp { 390 | ConditionalExp { 391 | exp : OrExpression::new(), 392 | true_exp : None, 393 | false_exp : None, 394 | } 395 | } 396 | 397 | pub fn set_to_zero() -> ConditionalExp { 398 | ConditionalExp { 399 | exp : OrExpression::set_to_zero(), 400 | true_exp : None, 401 | false_exp : None, 402 | } 403 | } 404 | 405 | pub fn set_to_one() -> ConditionalExp { 406 | ConditionalExp { 407 | exp : OrExpression::set_to_one(), 408 | true_exp : None, 409 | false_exp : None, 410 | } 411 | } 412 | } 413 | 414 | impl OrExpression { 415 | pub fn new() -> OrExpression { 416 | OrExpression { 417 | op : String::new(), 418 | left_exp : None, 419 | left_and_exp : None, 420 | right_and_exp : None, 421 | } 422 | } 423 | 424 | pub fn set_to_zero() -> OrExpression { 425 | OrExpression { 426 | op : String::new(), 427 | left_exp : None, 428 | left_and_exp : Some(Box::new(AndExpression::set_to_zero())), 429 | right_and_exp : None, 430 | } 431 | } 432 | 433 | pub fn set_to_one() -> OrExpression { 434 | OrExpression { 435 | op : String::new(), 436 | left_exp : None, 437 | left_and_exp : Some(Box::new(AndExpression::set_to_one())), 438 | right_and_exp : None, 439 | } 440 | } 441 | } 442 | 443 | impl AndExpression { 444 | pub fn new() -> AndExpression { 445 | AndExpression { 446 | op : String::new(), 447 | left_exp : None, 448 | left_child : None, 449 | right_child : None, 450 | } 451 | } 452 | 453 | pub fn set_to_zero() -> AndExpression { 454 | AndExpression { 455 | op : String::new(), 456 | left_exp : None, 457 | left_child : Some(Box::new(BitOr::set_to_zero())), 458 | right_child : None, 459 | } 460 | } 461 | 462 | pub fn set_to_one() -> AndExpression { 463 | AndExpression { 464 | op : String::new(), 465 | left_exp : None, 466 | left_child : Some(Box::new(BitOr::set_to_one())), 467 | right_child : None, 468 | } 469 | } 470 | } 471 | 472 | impl BitOr { 473 | pub fn new() -> BitOr { 474 | BitOr { 475 | op : String::new(), 476 | left_exp : None, 477 | left_child : None, 478 | right_child: None, 479 | } 480 | } 481 | 482 | pub fn set_to_zero() -> BitOr { 483 | BitOr { 484 | op : String::new(), 485 | left_exp : None, 486 | left_child : Some(Box::new(BitXor::set_to_zero())), 487 | right_child: None, 488 | } 489 | } 490 | 491 | pub fn set_to_one() -> BitOr { 492 | BitOr { 493 | op : String::new(), 494 | left_exp : None, 495 | left_child : Some(Box::new(BitXor::set_to_one())), 496 | right_child: None, 497 | } 498 | } 499 | } 500 | 501 | impl BitXor { 502 | pub fn new() -> BitXor { 503 | BitXor { 504 | op : String::new(), 505 | left_exp : None, 506 | left_child : None, 507 | right_child: None, 508 | } 509 | } 510 | 511 | pub fn set_to_zero() -> BitXor { 512 | BitXor { 513 | op : String::new(), 514 | left_exp : None, 515 | left_child : Some(Box::new(BitAnd::set_to_zero())), 516 | right_child: None, 517 | } 518 | } 519 | 520 | pub fn set_to_one() -> BitXor { 521 | BitXor { 522 | op : String::new(), 523 | left_exp : None, 524 | left_child : Some(Box::new(BitAnd::set_to_one())), 525 | right_child: None, 526 | } 527 | } 528 | } 529 | 530 | impl BitAnd { 531 | pub fn new() -> BitAnd { 532 | BitAnd { 533 | op : String::new(), 534 | left_exp : None, 535 | left_child : None, 536 | right_child: None, 537 | } 538 | } 539 | 540 | pub fn set_to_zero() -> BitAnd { 541 | BitAnd { 542 | op : String::new(), 543 | left_exp : None, 544 | left_child : Some(Box::new(EqualityExp::set_to_zero())), 545 | right_child: None, 546 | } 547 | } 548 | 549 | pub fn set_to_one() -> BitAnd { 550 | BitAnd { 551 | op : String::new(), 552 | left_exp : None, 553 | left_child : Some(Box::new(EqualityExp::set_to_one())), 554 | right_child: None, 555 | } 556 | } 557 | } 558 | 559 | impl EqualityExp { 560 | pub fn new() -> EqualityExp { 561 | EqualityExp { 562 | op : String::new(), 563 | left_exp : None, 564 | left_relation_exp : None, 565 | right_relation_exp : None, 566 | } 567 | } 568 | 569 | pub fn set_to_zero() -> EqualityExp { 570 | EqualityExp { 571 | op : String::new(), 572 | left_exp : None, 573 | left_relation_exp : Some(Box::new(RelationalExp::set_to_zero())), 574 | right_relation_exp : None, 575 | } 576 | } 577 | 578 | pub fn set_to_one() -> EqualityExp { 579 | EqualityExp { 580 | op : String::new(), 581 | left_exp : None, 582 | left_relation_exp : Some(Box::new(RelationalExp::set_to_one())), 583 | right_relation_exp : None, 584 | } 585 | } 586 | } 587 | 588 | impl RelationalExp { 589 | pub fn new() -> RelationalExp { 590 | RelationalExp { 591 | op : String::new(), 592 | left_exp : None, 593 | left_child : None, 594 | right_child : None, 595 | } 596 | } 597 | 598 | pub fn set_to_zero() -> RelationalExp { 599 | RelationalExp { 600 | op : String::new(), 601 | left_exp : None, 602 | left_child : Some(Box::new(BitShift::set_to_zero())), 603 | right_child : None, 604 | } 605 | } 606 | 607 | pub fn set_to_one() -> RelationalExp { 608 | RelationalExp { 609 | op : String::new(), 610 | left_exp : None, 611 | left_child : Some(Box::new(BitShift::set_to_one())), 612 | right_child : None, 613 | } 614 | } 615 | } 616 | 617 | impl BitShift { 618 | pub fn new() -> BitShift { 619 | BitShift { 620 | op : String::new(), 621 | left_exp : None, 622 | left_child : None, 623 | right_child: None, 624 | } 625 | } 626 | 627 | pub fn set_to_zero() -> BitShift { 628 | BitShift { 629 | op : String::new(), 630 | left_exp : None, 631 | left_child : Some(Box::new(AdditiveExp::set_to_zero())), 632 | right_child: None, 633 | } 634 | } 635 | 636 | pub fn set_to_one() -> BitShift { 637 | BitShift { 638 | op : String::new(), 639 | left_exp : None, 640 | left_child : Some(Box::new(AdditiveExp::set_to_one())), 641 | right_child: None, 642 | } 643 | } 644 | } 645 | 646 | impl AdditiveExp { 647 | pub fn new() -> AdditiveExp { 648 | AdditiveExp { 649 | op : String::new(), 650 | left_exp : None, 651 | left_term : None, 652 | right_term : None, 653 | } 654 | } 655 | 656 | pub fn set_to_zero() -> AdditiveExp { 657 | AdditiveExp { 658 | op : String::new(), 659 | left_exp : None, 660 | left_term : Some(Box::new(Term::set_to_zero())), 661 | right_term : None, 662 | } 663 | } 664 | 665 | pub fn set_to_one() -> AdditiveExp { 666 | AdditiveExp { 667 | op : String::new(), 668 | left_exp : None, 669 | left_term : Some(Box::new(Term::set_to_one())), 670 | right_term : None, 671 | } 672 | } 673 | } 674 | 675 | impl Term { 676 | pub fn new() -> Term { 677 | Term { 678 | op: String::new(), 679 | left_term : None, 680 | left_child : None, 681 | right_child : None, 682 | } 683 | } 684 | 685 | pub fn set_to_zero() -> Term { 686 | Term { 687 | op: String::new(), 688 | left_term : None, 689 | left_child : Some(Box::new(PostFixUnary::set_to_zero())), 690 | right_child : None, 691 | } 692 | } 693 | 694 | pub fn set_to_one() -> Term { 695 | Term { 696 | op: String::new(), 697 | left_term : None, 698 | left_child : Some(Box::new(PostFixUnary::set_to_one())), 699 | right_child : None, 700 | } 701 | } 702 | } 703 | 704 | impl Factor { 705 | pub fn new() -> Factor { 706 | Factor { 707 | op : String::new(), 708 | unary : None, 709 | postfix_unary : None, 710 | exp: None, 711 | val : None, 712 | var : None, 713 | fn_call : None, 714 | } 715 | } 716 | 717 | pub fn set_to_zero() -> Factor { 718 | Factor { 719 | op : String::new(), 720 | unary : None, 721 | postfix_unary : None, 722 | exp: None, 723 | val : Some(0), 724 | var : None, 725 | fn_call : None, 726 | } 727 | } 728 | 729 | pub fn set_to_one() -> Factor { 730 | Factor { 731 | op : String::new(), 732 | unary : None, 733 | postfix_unary : None, 734 | exp: None, 735 | val : Some(1), 736 | var : None, 737 | fn_call : None, 738 | } 739 | } 740 | } 741 | 742 | impl Unary { 743 | pub fn new() -> Unary { 744 | Unary { 745 | op : String::new(), 746 | child : None, 747 | } 748 | } 749 | } 750 | 751 | impl PostFixUnary { 752 | pub fn new() -> PostFixUnary { 753 | PostFixUnary { 754 | op : String::new(), 755 | child : None, 756 | } 757 | } 758 | 759 | pub fn set_to_zero() -> PostFixUnary { 760 | PostFixUnary { 761 | op : String::new(), 762 | child : Some(Box::new(Factor::set_to_zero())), 763 | } 764 | } 765 | 766 | pub fn set_to_one() -> PostFixUnary { 767 | PostFixUnary { 768 | op : String::new(), 769 | child : Some(Box::new(Factor::set_to_one())), 770 | } 771 | } 772 | } 773 | 774 | impl Clone for Compound { 775 | fn clone(&self) -> Self { 776 | Compound { 777 | list_of_blk : self.list_of_blk.clone(), 778 | } 779 | } 780 | } 781 | 782 | impl Clone for For { 783 | fn clone(&self) -> Self { 784 | For { 785 | exp : self.exp.clone(), 786 | optional_exp_1 : self.optional_exp_1.clone(), 787 | optional_exp_2 : self.optional_exp_2.clone(), 788 | statement : self.statement.clone(), 789 | } 790 | } 791 | } 792 | 793 | impl Clone for FnCall { 794 | fn clone(&self) -> Self { 795 | FnCall { 796 | name : self.name.clone(), 797 | args : self.args.clone(), 798 | } 799 | } 800 | } 801 | 802 | impl Clone for Parameter { 803 | fn clone(&self) -> Self { 804 | Parameter { 805 | name : self.name.clone(), 806 | param_type : self.param_type.clone(), 807 | } 808 | } 809 | } 810 | 811 | impl Clone for ForDecl { 812 | fn clone(&self) -> Self { 813 | ForDecl { 814 | exp : self.exp.clone(), 815 | decl : self.decl.clone(), 816 | optional_exp_2 : self.optional_exp_2.clone(), 817 | statement : self.statement.clone(), 818 | } 819 | } 820 | } 821 | 822 | impl Clone for DoWhile { 823 | fn clone(&self) -> Self { 824 | DoWhile { 825 | statement : self.statement.clone(), 826 | exp : self.exp.clone(), 827 | } 828 | } 829 | } 830 | 831 | impl Clone for Break { 832 | fn clone(&self) -> Self { 833 | Break { 834 | } 835 | } 836 | } 837 | 838 | impl Clone for Continue { 839 | fn clone(&self) -> Self { 840 | Continue { 841 | } 842 | } 843 | } 844 | 845 | impl Clone for While { 846 | fn clone(&self) -> Self { 847 | While { 848 | statement : self.statement.clone(), 849 | exp : self.exp.clone(), 850 | } 851 | } 852 | } 853 | 854 | impl Clone for Statement { 855 | fn clone(&self) -> Self { 856 | Statement { 857 | _if : self._if.clone(), 858 | compound: self.compound.clone(), 859 | exp : self.exp.clone(), 860 | name : self.name.clone(), 861 | _for : self._for.clone(), 862 | _for_decl : self._for_decl.clone(), 863 | _do : self._do.clone(), 864 | _break : self._break.clone(), 865 | _continue : self._continue.clone(), 866 | _while : self._while.clone(), 867 | } 868 | } 869 | } 870 | 871 | impl Clone for Variable { 872 | fn clone(&self) -> Self { 873 | Variable { 874 | var_name : self.var_name.clone(), 875 | } 876 | } 877 | } 878 | 879 | impl Clone for Declaration { 880 | fn clone (&self) -> Self { 881 | Declaration { 882 | var : self.var.clone(), 883 | exp : self.exp.clone(), 884 | var_type : self.var_type.clone(), 885 | } 886 | } 887 | } 888 | 889 | impl Clone for Assignment { 890 | fn clone(&self) -> Self { 891 | Assignment { 892 | var : self.var.clone(), 893 | assign : self.assign.clone(), 894 | exp : self.exp.clone(), 895 | op : self.op.clone(), 896 | } 897 | } 898 | } 899 | 900 | impl Clone for ConditionalExp { 901 | fn clone(&self) -> Self { 902 | ConditionalExp { 903 | exp : self.exp.clone(), 904 | true_exp : self.true_exp.clone(), 905 | false_exp : self.false_exp.clone(), 906 | } 907 | } 908 | } 909 | 910 | impl Clone for If { 911 | fn clone(&self) -> Self { 912 | If { 913 | cond : self.cond.clone(), 914 | state : self.state.clone(), 915 | else_state : self.else_state.clone(), 916 | } 917 | } 918 | } 919 | 920 | impl Clone for BlockItem { 921 | fn clone(&self) -> Self { 922 | BlockItem { 923 | state : self.state.clone(), 924 | decl : self.decl.clone(), 925 | } 926 | } 927 | } 928 | 929 | impl Clone for OrExpression { 930 | fn clone(&self) -> Self { 931 | OrExpression { 932 | op : self.op.clone(), 933 | left_exp : self.left_exp.clone(), 934 | left_and_exp : self.left_and_exp.clone(), 935 | right_and_exp : self.right_and_exp.clone(), 936 | } 937 | } 938 | } 939 | 940 | impl Clone for AndExpression { 941 | fn clone(&self) -> Self { 942 | AndExpression { 943 | op : self.op.clone(), 944 | left_exp : self.left_exp.clone(), 945 | left_child : self.left_child.clone(), 946 | right_child : self.right_child.clone(), 947 | } 948 | } 949 | } 950 | 951 | impl Clone for BitOr { 952 | fn clone(&self) -> Self { 953 | BitOr { 954 | op : self.op.clone(), 955 | left_exp : self.left_exp.clone(), 956 | left_child : self.left_child.clone(), 957 | right_child : self.right_child.clone(), 958 | } 959 | } 960 | } 961 | 962 | impl Clone for BitXor { 963 | fn clone(&self) -> Self { 964 | BitXor { 965 | op : self.op.clone(), 966 | left_exp : self.left_exp.clone(), 967 | left_child : self.left_child.clone(), 968 | right_child : self.right_child.clone(), 969 | } 970 | } 971 | } 972 | 973 | impl Clone for BitAnd { 974 | fn clone(&self) -> Self { 975 | BitAnd { 976 | op : self.op.clone(), 977 | left_exp : self.left_exp.clone(), 978 | left_child : self.left_child.clone(), 979 | right_child : self.right_child.clone(), 980 | } 981 | } 982 | } 983 | 984 | impl Clone for EqualityExp { 985 | fn clone(&self) -> Self { 986 | EqualityExp { 987 | op : self.op.clone(), 988 | left_exp : self.left_exp.clone(), 989 | left_relation_exp : self.left_relation_exp.clone(), 990 | right_relation_exp : self.right_relation_exp.clone(), 991 | } 992 | } 993 | } 994 | 995 | impl Clone for BitShift { 996 | fn clone(&self) -> Self { 997 | BitShift { 998 | op : self.op.clone(), 999 | left_exp : self.left_exp.clone(), 1000 | left_child : self.left_child.clone(), 1001 | right_child : self.right_child.clone(), 1002 | } 1003 | } 1004 | } 1005 | 1006 | impl Clone for RelationalExp { 1007 | fn clone(&self) -> Self { 1008 | RelationalExp { 1009 | op : self.op.clone(), 1010 | left_exp : self.left_exp.clone(), 1011 | left_child : self.left_child.clone(), 1012 | right_child : self.right_child.clone(), 1013 | } 1014 | } 1015 | } 1016 | 1017 | impl Clone for AdditiveExp { 1018 | fn clone(&self) -> Self { 1019 | AdditiveExp { 1020 | op : self.op.clone(), 1021 | left_exp : self.left_exp.clone(), 1022 | left_term : self.left_term.clone(), 1023 | right_term : self.right_term.clone(), 1024 | } 1025 | } 1026 | } 1027 | 1028 | impl Clone for Term { 1029 | fn clone(&self) -> Self { 1030 | Term { 1031 | op : self.op.clone(), 1032 | left_term : self.left_term.clone(), 1033 | left_child : self.left_child.clone(), 1034 | right_child : self.right_child.clone(), 1035 | } 1036 | } 1037 | } 1038 | 1039 | impl Clone for Factor { 1040 | fn clone(&self) -> Self { 1041 | Factor { 1042 | op : self.op.clone(), 1043 | unary : self.unary.clone(), 1044 | postfix_unary : self.postfix_unary.clone(), 1045 | exp : self.exp.clone(), 1046 | val : self.val, 1047 | var: self.var.clone(), 1048 | fn_call : self.fn_call.clone(), 1049 | } 1050 | } 1051 | } 1052 | 1053 | impl Clone for Unary { 1054 | fn clone(&self) -> Self { 1055 | Unary { 1056 | op : self.op.clone(), 1057 | child : self.child.clone(), 1058 | } 1059 | } 1060 | } 1061 | 1062 | impl Clone for PostFixUnary { 1063 | fn clone(&self) -> Self { 1064 | PostFixUnary { 1065 | op : self.op.clone(), 1066 | child : self.child.clone(), 1067 | } 1068 | } 1069 | } 1070 | 1071 | pub fn print_ast (input_prog : &Program) { 1072 | println!("=====AST PRINT====="); 1073 | 1074 | for fnc in &input_prog.list_of_fnc { 1075 | println!("FUN {} {}:", fnc.return_type, fnc.name); 1076 | print!(" params: ( "); 1077 | for p in &fnc.params { 1078 | print!("{} {} ", p.param_type.clone(), p.name.clone()); 1079 | } 1080 | println!(")"); 1081 | println!(" body:"); 1082 | 1083 | for bl_item in &fnc.list_of_blk { 1084 | match bl_item.state.clone() { 1085 | Some (x) => { 1086 | print!(" {} ", x.name); 1087 | print!("[ "); 1088 | print_statement(&x); 1089 | println!(" ]"); 1090 | }, 1091 | None => (), 1092 | } 1093 | 1094 | match bl_item.decl.clone() { 1095 | Some(x) => { 1096 | print!(" decl "); 1097 | print!("[ "); 1098 | print_declaration(&x); 1099 | print!(" ]\n"); 1100 | }, 1101 | None => (), 1102 | } 1103 | } 1104 | } 1105 | 1106 | println!("=====END AST PRINT====="); 1107 | } 1108 | 1109 | pub fn print_while (input_while : &While) { 1110 | print!("while"); 1111 | print_assignment(&input_while.exp); 1112 | print!("\n {{\n"); 1113 | print_statement(&input_while.statement); 1114 | print!("\n }}") 1115 | } 1116 | 1117 | pub fn print_do (input_do : &DoWhile) { 1118 | print!("do"); 1119 | print!("\n {{\n"); 1120 | print_statement(&input_do.statement); 1121 | print!("\n }}"); 1122 | print!("while"); 1123 | print_assignment(&input_do.exp); 1124 | print!("\n"); 1125 | } 1126 | 1127 | pub fn print_for (input_for : &For) { 1128 | print!("for ("); 1129 | match (input_for.optional_exp_1.clone()) { 1130 | Some (x) => print_assignment(&x), 1131 | None => (), 1132 | } 1133 | print!(" ; "); 1134 | print_assignment(&input_for.exp); 1135 | print!(" ; "); 1136 | match (input_for.optional_exp_2.clone()) { 1137 | Some (x) => print_assignment(&x), 1138 | None => (), 1139 | } 1140 | print!(") {{\n"); 1141 | 1142 | print_statement(&input_for.statement); 1143 | 1144 | print!("}}\n"); 1145 | } 1146 | 1147 | pub fn print_for_decl (input_for_decl : &ForDecl) { 1148 | print!("for ("); 1149 | 1150 | print_declaration(&input_for_decl.decl); 1151 | print!(" ; "); 1152 | print_assignment(&input_for_decl.exp); 1153 | print!(" ; "); 1154 | match (input_for_decl.optional_exp_2.clone()) { 1155 | Some (x) => print_assignment(&x), 1156 | None => (), 1157 | } 1158 | print!(") {{\n"); 1159 | 1160 | print_statement(&input_for_decl.statement); 1161 | 1162 | print!("}}\n"); 1163 | } 1164 | 1165 | pub fn print_continue (input_cont : &Continue) { 1166 | print!("continue"); 1167 | } 1168 | 1169 | pub fn print_break (input_break : &Break) { 1170 | print!("break"); 1171 | } 1172 | 1173 | pub fn print_compound(cmpd : &Compound) { 1174 | for blk in &cmpd.list_of_blk { 1175 | match blk.state.clone() { 1176 | Some (x) => { 1177 | print!(" "); 1178 | print_statement(&x); 1179 | }, 1180 | None => { 1181 | match blk.decl.clone() { 1182 | Some (y) => { 1183 | print!(" "); 1184 | print_declaration(&y) 1185 | }, 1186 | None => (), 1187 | } 1188 | }, 1189 | } 1190 | } 1191 | } 1192 | 1193 | pub fn print_statement (state : &Statement) { 1194 | match state.exp.clone() { 1195 | Some(y) => print_assignment(&y), 1196 | None => (), 1197 | } 1198 | match state._if.clone() { 1199 | Some (y) => print_if(&y), 1200 | None => (), 1201 | } 1202 | match state.compound.clone() { 1203 | Some (y) => print_compound(&y), 1204 | None => (), 1205 | } 1206 | match state._while.clone() { 1207 | Some (y) => print_while(&y), 1208 | None => (), 1209 | } 1210 | match state._for.clone() { 1211 | Some (y) => print_for(&y), 1212 | None => (), 1213 | } 1214 | match state._for_decl.clone() { 1215 | Some (y) => print_for_decl(&y), 1216 | None => (), 1217 | } 1218 | match state._do.clone() { 1219 | Some (y) => print_do(&y), 1220 | None => (), 1221 | } 1222 | match state._continue.clone() { 1223 | Some (y) => print_continue(&y), 1224 | None => (), 1225 | } 1226 | match state._break.clone() { 1227 | Some (y) => print_break(&y), 1228 | None => (), 1229 | } 1230 | } 1231 | 1232 | pub fn print_if (if_exp : &If) { 1233 | print_assignment(&if_exp.cond); 1234 | print!(" {{\n "); 1235 | 1236 | match if_exp.state.clone() { 1237 | Some(x) => { 1238 | print!("{}", x.name); 1239 | print_statement(&*x) 1240 | }, 1241 | None => (), 1242 | } 1243 | print!("\n }}\n"); 1244 | 1245 | match if_exp.else_state.clone() { 1246 | Some(x) => { 1247 | print!(" else {{\n {}", x.name); 1248 | print_statement(&*x); 1249 | print!("\n }}"); 1250 | }, 1251 | None => (), 1252 | } 1253 | } 1254 | 1255 | pub fn print_declaration (decl : &Declaration) { 1256 | print!("{} {} = ", decl.var_type, decl.var.var_name); 1257 | print_assignment(&decl.exp); 1258 | } 1259 | 1260 | pub fn print_assignment (exp : &Assignment) { 1261 | match exp.var.clone() { 1262 | Some(var) => { 1263 | print!("{} {} ", var.var_name, exp.op); 1264 | }, 1265 | None => (), 1266 | } 1267 | 1268 | match exp.assign.clone() { 1269 | Some(assign) => { 1270 | print_assignment(&*assign); 1271 | }, 1272 | None => { 1273 | match exp.exp.clone() { 1274 | Some(exp) => { 1275 | print!("("); 1276 | print_cond_exp(&exp); 1277 | print!(")"); 1278 | }, 1279 | None => () 1280 | } 1281 | }, 1282 | } 1283 | } 1284 | 1285 | 1286 | pub fn print_cond_exp(cond_exp : &ConditionalExp) { 1287 | print_or(&cond_exp.exp); 1288 | 1289 | match cond_exp.true_exp.clone() { 1290 | Some(x) => { 1291 | match cond_exp.false_exp.clone() { 1292 | Some(y) => { 1293 | print!(" ? "); 1294 | print_assignment(&*x); 1295 | print!(" : "); 1296 | print_cond_exp(&*y); 1297 | }, 1298 | None => (), 1299 | } 1300 | }, 1301 | None => (), 1302 | } 1303 | 1304 | } 1305 | 1306 | 1307 | pub fn print_or (exp : &OrExpression) { 1308 | match exp.left_exp.clone() { 1309 | Some(lexp) => { 1310 | match exp.right_and_exp.clone() { 1311 | Some(rand_exp) => { 1312 | print!("("); 1313 | print_or(&*lexp); 1314 | print!(" {} ", exp.op); 1315 | print_and(&*rand_exp); 1316 | print!(")"); 1317 | }, 1318 | None => { 1319 | print_or(&*lexp); 1320 | }, 1321 | } 1322 | }, 1323 | None => { 1324 | match exp.left_and_exp.clone() { 1325 | Some(land_exp) => { 1326 | match exp.right_and_exp.clone() { 1327 | Some(rand_exp) => { 1328 | print!("("); 1329 | print_and(&*land_exp); 1330 | print!(" {} ", exp.op); 1331 | print_and(&(*rand_exp)); 1332 | print!(")"); 1333 | }, 1334 | None => { 1335 | print_and(&*land_exp); 1336 | }, 1337 | } 1338 | }, 1339 | None => { 1340 | }, 1341 | } 1342 | }, 1343 | } 1344 | } 1345 | 1346 | pub fn print_and (exp : &AndExpression) { 1347 | match exp.left_exp.clone() { 1348 | Some(lexp) => { 1349 | match exp.right_child.clone() { 1350 | Some(r_child) => { 1351 | print!("("); 1352 | print_and(&*lexp); 1353 | print!(" {} ", exp.op); 1354 | print_bit_or(&*r_child); 1355 | print!(")"); 1356 | }, 1357 | None => { 1358 | print_and(&*lexp); 1359 | }, 1360 | } 1361 | }, 1362 | None => { 1363 | match exp.left_child.clone() { 1364 | Some(lchild) => { 1365 | match exp.right_child.clone() { 1366 | Some(rchild) => { 1367 | print!("("); 1368 | print_bit_or(&*lchild); 1369 | print!(" {} ", exp.op); 1370 | print_bit_or(&(*rchild)); 1371 | print!(")"); 1372 | }, 1373 | None => { 1374 | print_bit_or(&*lchild); 1375 | }, 1376 | } 1377 | }, 1378 | None => { 1379 | }, 1380 | } 1381 | }, 1382 | } 1383 | } 1384 | 1385 | pub fn print_bit_or (exp : &BitOr) { 1386 | match exp.left_exp.clone() { 1387 | Some(lexp) => { 1388 | match exp.right_child.clone() { 1389 | Some(r_child) => { 1390 | print!("("); 1391 | print_bit_or(&*lexp); 1392 | print!(" {} ", exp.op); 1393 | print_bit_xor(&*r_child); 1394 | print!(")"); 1395 | }, 1396 | None => { 1397 | print_bit_or(&*lexp); 1398 | }, 1399 | } 1400 | }, 1401 | None => { 1402 | match exp.left_child.clone() { 1403 | Some(lchild) => { 1404 | match exp.right_child.clone() { 1405 | Some(rchild) => { 1406 | print!("("); 1407 | print_bit_xor(&*lchild); 1408 | print!(" {} ", exp.op); 1409 | print_bit_xor(&(*rchild)); 1410 | print!(")"); 1411 | }, 1412 | None => { 1413 | print_bit_xor(&*lchild); 1414 | }, 1415 | } 1416 | }, 1417 | None => { 1418 | }, 1419 | } 1420 | }, 1421 | } 1422 | } 1423 | 1424 | pub fn print_bit_xor (exp : &BitXor) { 1425 | match exp.left_exp.clone() { 1426 | Some(lexp) => { 1427 | match exp.right_child.clone() { 1428 | Some(r_child) => { 1429 | print!("("); 1430 | print_bit_xor(&*lexp); 1431 | print!(" {} ", exp.op); 1432 | print_bit_and(&*r_child); 1433 | print!(")"); 1434 | }, 1435 | None => { 1436 | print_bit_xor(&*lexp); 1437 | }, 1438 | } 1439 | }, 1440 | None => { 1441 | match exp.left_child.clone() { 1442 | Some(lchild) => { 1443 | match exp.right_child.clone() { 1444 | Some(rchild) => { 1445 | print!("("); 1446 | print_bit_and(&*lchild); 1447 | print!(" {} ", exp.op); 1448 | print_bit_and(&(*rchild)); 1449 | print!(")"); 1450 | }, 1451 | None => { 1452 | print_bit_and(&*lchild); 1453 | }, 1454 | } 1455 | }, 1456 | None => { 1457 | }, 1458 | } 1459 | }, 1460 | } 1461 | } 1462 | 1463 | pub fn print_bit_and (exp : &BitAnd) { 1464 | match exp.left_exp.clone() { 1465 | Some(lexp) => { 1466 | match exp.right_child.clone() { 1467 | Some(r_child) => { 1468 | print!("("); 1469 | print_bit_and(&*lexp); 1470 | print!(" {} ", exp.op); 1471 | print_eq(&*r_child); 1472 | print!(")"); 1473 | }, 1474 | None => { 1475 | print_bit_and(&*lexp); 1476 | }, 1477 | } 1478 | }, 1479 | None => { 1480 | match exp.left_child.clone() { 1481 | Some(lchild) => { 1482 | match exp.right_child.clone() { 1483 | Some(rchild) => { 1484 | print!("("); 1485 | print_eq(&*lchild); 1486 | print!(" {} ", exp.op); 1487 | print_eq(&(*rchild)); 1488 | print!(")"); 1489 | }, 1490 | None => { 1491 | print_eq(&*lchild); 1492 | }, 1493 | } 1494 | }, 1495 | None => { 1496 | }, 1497 | } 1498 | }, 1499 | } 1500 | } 1501 | 1502 | pub fn print_eq(exp : &EqualityExp) { 1503 | match exp.left_exp.clone() { 1504 | Some(lexp) => { 1505 | match exp.right_relation_exp.clone() { 1506 | Some(r_child) => { 1507 | print!("("); 1508 | print_eq(&*lexp); 1509 | print!(" {} ", exp.op); 1510 | print_rel(&*r_child); 1511 | print!(")"); 1512 | }, 1513 | None => { 1514 | print_eq(&*lexp); 1515 | }, 1516 | } 1517 | }, 1518 | None => { 1519 | match exp.left_relation_exp.clone() { 1520 | Some(lchild) => { 1521 | match exp.right_relation_exp.clone() { 1522 | Some(rchild) => { 1523 | print!("("); 1524 | print_rel(&*lchild); 1525 | print!(" {} ", exp.op); 1526 | print_rel(&(*rchild)); 1527 | print!(")"); 1528 | }, 1529 | None => { 1530 | print_rel(&*lchild); 1531 | }, 1532 | } 1533 | }, 1534 | None => { 1535 | }, 1536 | } 1537 | }, 1538 | } 1539 | } 1540 | 1541 | pub fn print_rel(exp : &RelationalExp) { 1542 | match exp.left_exp.clone() { 1543 | Some(lexp) => { 1544 | match exp.right_child.clone() { 1545 | Some(r_child) => { 1546 | print!("("); 1547 | print_rel(&*lexp); 1548 | print!(" {} ", exp.op); 1549 | print_bit_shift(&*r_child); 1550 | print!(")"); 1551 | }, 1552 | None => { 1553 | print_rel(&*lexp); 1554 | }, 1555 | } 1556 | }, 1557 | None => { 1558 | match exp.left_child.clone() { 1559 | Some(lchild) => { 1560 | match exp.right_child.clone() { 1561 | Some(rchild) => { 1562 | print!("("); 1563 | print_bit_shift(&*lchild); 1564 | print!(" {} ", exp.op); 1565 | print_bit_shift(&(*rchild)); 1566 | print!(")"); 1567 | }, 1568 | None => { 1569 | print_bit_shift(&*lchild); 1570 | }, 1571 | } 1572 | }, 1573 | None => { 1574 | }, 1575 | } 1576 | }, 1577 | } 1578 | } 1579 | 1580 | pub fn print_bit_shift(exp : &BitShift) { 1581 | match exp.left_exp.clone() { 1582 | Some(lexp) => { 1583 | match exp.right_child.clone() { 1584 | Some(r_child) => { 1585 | print!("("); 1586 | print_bit_shift(&*lexp); 1587 | print!(" {} ", exp.op); 1588 | print_add(&*r_child); 1589 | print!(")"); 1590 | }, 1591 | None => { 1592 | print_bit_shift(&*lexp); 1593 | }, 1594 | } 1595 | }, 1596 | None => { 1597 | match exp.left_child.clone() { 1598 | Some(lchild) => { 1599 | match exp.right_child.clone() { 1600 | Some(rchild) => { 1601 | print!("("); 1602 | print_add(&*lchild); 1603 | print!(" {} ", exp.op); 1604 | print_add(&(*rchild)); 1605 | print!(")"); 1606 | }, 1607 | None => { 1608 | print_add(&*lchild); 1609 | }, 1610 | } 1611 | }, 1612 | None => { 1613 | }, 1614 | } 1615 | }, 1616 | } 1617 | } 1618 | 1619 | pub fn print_add(exp : &AdditiveExp) { 1620 | match exp.left_exp.clone() { 1621 | Some(lexp) => { 1622 | match exp.right_term.clone() { 1623 | Some(r_child) => { 1624 | print!("("); 1625 | print_add(&*lexp); 1626 | print!(" {} ", exp.op); 1627 | print_term(&*r_child); 1628 | print!(")"); 1629 | }, 1630 | None => { 1631 | print_add(&*lexp); 1632 | }, 1633 | } 1634 | }, 1635 | None => { 1636 | match exp.left_term.clone() { 1637 | Some(lchild) => { 1638 | match exp.right_term.clone() { 1639 | Some(rchild) => { 1640 | print!("("); 1641 | print_term(&*lchild); 1642 | print!(" {} ", exp.op); 1643 | print_term(&(*rchild)); 1644 | print!(")"); 1645 | }, 1646 | None => { 1647 | print_term(&*lchild); 1648 | }, 1649 | } 1650 | }, 1651 | None => { 1652 | }, 1653 | } 1654 | }, 1655 | } 1656 | } 1657 | 1658 | pub fn print_term (term : &Term) { 1659 | match term.left_term.clone() { 1660 | Some(lterm) => { 1661 | match term.right_child.clone() { 1662 | Some(rfactor) => { 1663 | print!("("); 1664 | print_term(&*lterm); 1665 | print!(" {} ", term.op); 1666 | print_postfix_unary(&(*rfactor)); 1667 | print!(")"); 1668 | }, 1669 | None => { 1670 | print_term(&*lterm); 1671 | }, 1672 | } 1673 | }, 1674 | None => { 1675 | match term.left_child.clone() { 1676 | Some(lfactor) => { 1677 | match term.right_child.clone() { 1678 | Some(rfactor) => { 1679 | print!("("); 1680 | print_postfix_unary(&(*lfactor)); 1681 | print!(" {} ", term.op); 1682 | print_postfix_unary(&(*rfactor)); 1683 | print!(")"); 1684 | }, 1685 | None => { 1686 | print_postfix_unary(&(*lfactor)); 1687 | }, 1688 | } 1689 | }, 1690 | None => { 1691 | }, 1692 | } 1693 | }, 1694 | } 1695 | } 1696 | 1697 | 1698 | pub fn print_factor (factor : &Factor) { 1699 | match factor.postfix_unary.clone() { 1700 | Some(pf_un) => { 1701 | print_postfix_unary(&*pf_un); 1702 | }, 1703 | None => { 1704 | match factor.unary.clone() { 1705 | Some(un) => { 1706 | print_unary(&*un); 1707 | }, 1708 | None => { 1709 | match factor.exp.clone() { 1710 | Some(e) => { 1711 | print_assignment(&*e); 1712 | }, 1713 | None => { 1714 | match factor.val { 1715 | Some(v) => { 1716 | print!("{}", v); 1717 | }, 1718 | None => { 1719 | match factor.var.clone() { 1720 | Some(v) => { 1721 | print!("{}", v.var_name); 1722 | }, 1723 | None => (), 1724 | } 1725 | }, 1726 | } 1727 | }, 1728 | } 1729 | } 1730 | } 1731 | }, 1732 | } 1733 | } 1734 | 1735 | pub fn print_unary (unary : &Unary) { 1736 | print!("{}(", unary.op); 1737 | match unary.child.clone() { 1738 | Some(child) => { 1739 | print_factor(&(*child)); 1740 | print!(")"); 1741 | }, 1742 | None => { 1743 | }, 1744 | } 1745 | } 1746 | 1747 | pub fn print_postfix_unary (pf_unary : &PostFixUnary) { 1748 | match pf_unary.child.clone() { 1749 | Some(fact) => { 1750 | print_factor(&(*fact)); 1751 | }, 1752 | None => { 1753 | }, 1754 | } 1755 | print!("{}", pf_unary.op); 1756 | } 1757 | 1758 | pub fn parse_program(token_vec : &mut Vec) -> Program { 1759 | let mut result : Program = Program::new(); 1760 | 1761 | while (peek_next_token(token_vec).value != "EOFile") { 1762 | result.list_of_fnc.push(parse_function(token_vec)); 1763 | } 1764 | 1765 | result 1766 | } 1767 | 1768 | pub fn get_option_token( op : Option ) -> lexer::Token { 1769 | match op { 1770 | None => { 1771 | println!("Failed to get token from option"); 1772 | std::process::exit(1); 1773 | }, 1774 | Some(x) => { x }, 1775 | } 1776 | } 1777 | 1778 | pub fn get_next_token(token_vec : &mut Vec) -> lexer::Token { 1779 | assert!(token_vec.len() >=1, "Token vector is not at least of size 1."); 1780 | 1781 | let tok : lexer::Token = get_option_token(token_vec.first().cloned()); 1782 | token_vec.remove(0); 1783 | //println!("Token obtained: {}", tok); 1784 | tok 1785 | } 1786 | 1787 | pub fn peek_next_token(token_vec : &Vec) -> lexer::Token { 1788 | assert!(token_vec.len() > 0, "Token vector is not at least of size 1."); 1789 | get_option_token(token_vec.first().cloned()) 1790 | } 1791 | 1792 | pub fn peek_two_tokens(token_vec : &Vec) -> lexer::Token { 1793 | assert!(token_vec.len() >=2, "Token vector is not at least of size 2."); 1794 | 1795 | let mut tok_clone = token_vec.clone(); 1796 | tok_clone.remove(0); 1797 | get_option_token(tok_clone.first().cloned()) 1798 | } 1799 | 1800 | pub fn peek_n_tokens(token_vec : &Vec, n : i32) -> lexer::Token { 1801 | assert!(token_vec.len() >=2, "Token vector is not at least of size 2."); 1802 | assert!(n >= 2, "Expects greater than two for usage."); 1803 | 1804 | let mut tok_clone = token_vec.clone(); 1805 | for i in 0..n { 1806 | tok_clone.remove(0); 1807 | } 1808 | get_option_token(tok_clone.first().cloned()) 1809 | } 1810 | 1811 | pub fn parse_function(token_vec : &mut Vec) -> Function { 1812 | 1813 | let mut result : Function = Function::new(); 1814 | let mut tok : lexer::Token = get_next_token(token_vec); 1815 | 1816 | assert!(tok.name == "Type", "Invalid type, saw {}", tok.name); 1817 | result.return_type = tok.value; 1818 | 1819 | tok = get_next_token(token_vec); 1820 | assert!(tok.name == "Identifier", "Invalid identifier"); 1821 | result.name = tok.value; 1822 | 1823 | tok = get_next_token(token_vec); 1824 | assert!(tok.name == "Punc" && tok.value == "(", "Invalid punc. (\"(\")"); 1825 | tok = get_next_token(token_vec); 1826 | 1827 | while (tok.value != ")") { 1828 | assert!(tok.value != "EOFunc" && tok.name != "EOF TOKEN", "Incorrect syntax, saw {}.", tok.value); 1829 | assert!(tok.value == "int", "Failed param type check, saw {}", tok.value); 1830 | let mut parameter : Parameter = Parameter::new(); 1831 | parameter.param_type = tok.value.clone(); 1832 | tok = get_next_token(token_vec); 1833 | assert!(tok.name == "Identifier", "Bad param name."); 1834 | parameter.name = tok.value.clone(); 1835 | result.params.push(parameter); 1836 | tok = get_next_token(token_vec); 1837 | if (tok.value == ",") { 1838 | tok = get_next_token(token_vec); 1839 | } 1840 | } 1841 | 1842 | assert!(tok.name == "Punc" && tok.value == ")", "Invalid punc. (\")\")"); 1843 | 1844 | tok = get_next_token(token_vec); 1845 | if (tok.value == "{") { 1846 | result.is_definition = true; 1847 | assert!(tok.name == "Punc" && tok.value == "{", "Invalid punc. (\"{\")"); 1848 | 1849 | // Block check 1850 | while (peek_next_token(token_vec).value != "}") { 1851 | result.list_of_blk.push(parse_block_item(token_vec)); 1852 | } 1853 | 1854 | tok = get_next_token(token_vec); 1855 | assert!(tok.name == "Punc" && tok.value == "}", "Invalid punc. (\"}\")"); 1856 | } 1857 | else { 1858 | // Otherwise it is just an empty function, so we must look for a semicolon. 1859 | assert!(tok.name == "Punc" && tok.value == ";", "Invalid punc (;), saw {}.", tok.value); 1860 | } 1861 | result 1862 | } 1863 | 1864 | 1865 | pub fn parse_block_item(token_vec : &mut Vec) -> BlockItem { 1866 | let mut result : BlockItem = BlockItem::new(); 1867 | let mut tok : lexer::Token = peek_next_token(token_vec); 1868 | 1869 | if (tok.name=="Type") { 1870 | result.decl = Some(parse_declaration(token_vec)); 1871 | 1872 | tok = get_next_token(token_vec); 1873 | assert!(tok.value == ";", "Missing semicolon, saw {}", tok.value); 1874 | } 1875 | else { 1876 | result.state = Some(parse_statement(token_vec)); 1877 | } 1878 | 1879 | result 1880 | } 1881 | 1882 | 1883 | pub fn parse_compound(token_vec : &mut Vec) -> Compound { 1884 | let mut result : Compound = Compound::new(); 1885 | let mut tok : lexer::Token = peek_next_token(token_vec); 1886 | 1887 | assert!(tok.name == "Punc" && tok.value == "{", "Invalid cmpd punc: (\"{\")"); 1888 | token_vec.remove(0); 1889 | tok = peek_next_token(token_vec); 1890 | 1891 | while (!(tok.name == "Punc" && tok.value == "}")) { 1892 | result.list_of_blk.push(parse_block_item(token_vec)); 1893 | tok = peek_next_token(token_vec); 1894 | } 1895 | 1896 | assert!(tok.name == "Punc" && tok.value == "}", "Invalid cmpd punc: (\"}\")"); 1897 | token_vec.remove(0); 1898 | result 1899 | } 1900 | 1901 | 1902 | pub fn parse_while(token_vec : &mut Vec) -> While { 1903 | let mut result : While = While::new(); 1904 | token_vec.remove(0); 1905 | let mut tok : lexer::Token = peek_next_token(token_vec); 1906 | 1907 | assert!(tok.value == "(", "missing ( in while, saw {}", tok.value); 1908 | token_vec.remove(0); 1909 | result.exp = parse_assign(token_vec); 1910 | tok = peek_next_token(token_vec); 1911 | assert!(tok.value == ")", "missing ) in while, saw {}", tok.value); 1912 | token_vec.remove(0); 1913 | result.statement = Box::new(parse_statement(token_vec)); 1914 | 1915 | result 1916 | } 1917 | 1918 | 1919 | pub fn parse_for(token_vec : &mut Vec) -> For { 1920 | let mut result : For = For::new(); 1921 | token_vec.remove(0); 1922 | let mut tok : lexer::Token = peek_next_token(token_vec); 1923 | 1924 | assert!(tok.value == "(", "missing ( in for, saw {}", tok.value); 1925 | token_vec.remove(0); 1926 | tok = peek_next_token(token_vec); 1927 | if (tok.value != ";") { 1928 | result.optional_exp_1 = Some(parse_assign(token_vec)); 1929 | } 1930 | 1931 | tok = peek_next_token(token_vec); 1932 | assert!(tok.value == ";", "missing ; in for, saw {}", tok.value); 1933 | token_vec.remove(0); 1934 | tok = peek_next_token(token_vec); 1935 | if (tok.value != ";") { 1936 | result.exp= parse_assign(token_vec); 1937 | } 1938 | else { 1939 | result.exp = Assignment::set_to_one(); 1940 | } 1941 | 1942 | tok = peek_next_token(token_vec); 1943 | assert!(tok.value == ";", "missing ; in for, saw {}", tok.value); 1944 | token_vec.remove(0); 1945 | tok = peek_next_token(token_vec); 1946 | if (tok.value != ")") { 1947 | result.optional_exp_2 = Some(parse_assign(token_vec)); 1948 | } 1949 | 1950 | tok = peek_next_token(token_vec); 1951 | assert!(tok.value == ")", "missing ) in for, saw {}", tok.value); 1952 | token_vec.remove(0); 1953 | 1954 | result.statement = Box::new(parse_statement(token_vec)); 1955 | 1956 | result 1957 | } 1958 | 1959 | 1960 | pub fn parse_for_decl(token_vec : &mut Vec) -> ForDecl { 1961 | let mut result : ForDecl = ForDecl::new(); 1962 | token_vec.remove(0); 1963 | let mut tok : lexer::Token = peek_next_token(token_vec); 1964 | 1965 | assert!(tok.value == "(", "missing ( in for_decl, saw {}", tok.value); 1966 | token_vec.remove(0); 1967 | tok = peek_next_token(token_vec); 1968 | assert!(tok.value == "int", "missing int in for_decl, saw {}", tok.value); 1969 | result.decl = parse_declaration(token_vec); 1970 | 1971 | tok = peek_next_token(token_vec); 1972 | assert!(tok.value == ";", "missing ; in for_decl, saw {}", tok.value); 1973 | token_vec.remove(0); 1974 | tok = peek_next_token(token_vec); 1975 | if (tok.value != ";") { 1976 | result.exp= parse_assign(token_vec); 1977 | } 1978 | else { 1979 | result.exp = Assignment::set_to_one(); 1980 | } 1981 | 1982 | tok = peek_next_token(token_vec); 1983 | assert!(tok.value == ";", "missing ; in for_decl, saw {}", tok.value); 1984 | token_vec.remove(0); 1985 | tok = peek_next_token(token_vec); 1986 | if (tok.value != ")") { 1987 | result.optional_exp_2 = Some(parse_assign(token_vec)); 1988 | } 1989 | 1990 | tok = peek_next_token(token_vec); 1991 | assert!(tok.value == ")", "missing ) in for_decl, saw {}", tok.value); 1992 | token_vec.remove(0); 1993 | 1994 | result.statement = Box::new(parse_statement(token_vec)); 1995 | 1996 | result 1997 | } 1998 | 1999 | 2000 | pub fn parse_do_while(token_vec : &mut Vec) -> DoWhile { 2001 | let mut result : DoWhile = DoWhile::new(); 2002 | token_vec.remove(0); 2003 | result.statement = Box::new(parse_statement(token_vec)); 2004 | 2005 | let mut tok : lexer::Token = peek_next_token(token_vec); 2006 | token_vec.remove(0); 2007 | assert!(tok.value == "while", "missing \"while\" in do-while, saw {}", tok.value); 2008 | tok = peek_next_token(token_vec); 2009 | 2010 | assert!(tok.value == "(", "missing ( in do-while, saw {}", tok.value); 2011 | token_vec.remove(0); 2012 | result.exp = parse_assign(token_vec); 2013 | tok = peek_next_token(token_vec); 2014 | assert!(tok.value == ")", "missing ) in do-while, saw {}", tok.value); 2015 | token_vec.remove(0); 2016 | 2017 | result 2018 | } 2019 | 2020 | 2021 | pub fn parse_statement(token_vec : &mut Vec) -> Statement { 2022 | let mut result : Statement = Statement::new(); 2023 | let mut tok : lexer::Token = peek_next_token(token_vec); 2024 | 2025 | // We must set this up to accept three cases: 2026 | // * Var dec 2027 | // * Var assign 2028 | // * Return 2029 | 2030 | // Get expression 2031 | 2032 | // Modify this statement based on expression/tok values 2033 | if (tok.name == "Keyword") { 2034 | if (tok.value == "if") { 2035 | result.name = String::from("if"); 2036 | result._if = Some(parse_if(token_vec)); 2037 | } 2038 | else if (tok.value == "return") { 2039 | result.name = String::from("return"); 2040 | token_vec.remove(0); 2041 | result.exp = Some(parse_assign(token_vec)); 2042 | 2043 | tok = get_next_token(token_vec); 2044 | assert!(tok.value == ";", "Missing semicolon, saw {}", tok.value); 2045 | } 2046 | else if (tok.value == "while") { 2047 | result._while = Some(parse_while(token_vec)); 2048 | } 2049 | else if (tok.value == "for") { 2050 | let tok_clone : lexer::Token; 2051 | if (peek_n_tokens(token_vec, 2).value == "int" && peek_n_tokens(token_vec, 2).name == "Type") { 2052 | result._for_decl = Some(parse_for_decl(token_vec)); 2053 | } 2054 | else { 2055 | result._for = Some(parse_for(token_vec)); 2056 | } 2057 | } 2058 | else if (tok.value == "do") { 2059 | result._do = Some(parse_do_while(token_vec)); 2060 | } 2061 | else if (tok.value == "break" || tok.value == "continue") { 2062 | result.name = tok.value.clone(); 2063 | match tok.value.as_str() { 2064 | "break" => result._break = Some(Break::new()), 2065 | "continue" => result._continue = Some(Continue::new()), 2066 | _ => (), 2067 | } 2068 | token_vec.remove(0); 2069 | } 2070 | } 2071 | else if (tok.name == "Punc" && tok.value == "{") { 2072 | result.compound = Some(parse_compound(token_vec)); 2073 | } 2074 | else if (tok.name == "Punc" && tok.value == ";") { 2075 | result.name = String::from("empty"); 2076 | token_vec.remove(0); 2077 | } 2078 | else { 2079 | result.name = String::from("exp"); 2080 | result.exp = Some(parse_assign(token_vec)); 2081 | 2082 | tok = get_next_token(token_vec); 2083 | assert!(tok.value == ";", "Missing semicolon, saw {}", tok.value); 2084 | 2085 | } 2086 | 2087 | result 2088 | } 2089 | 2090 | pub fn parse_if(token_vec : &mut Vec) -> If { 2091 | let mut result : If = If::new(); 2092 | let mut tok : lexer::Token = peek_next_token(token_vec); 2093 | 2094 | token_vec.remove(0); 2095 | result.cond = parse_assign(token_vec); 2096 | result.state = Some(Box::new(parse_statement(token_vec))); 2097 | 2098 | tok = peek_next_token(token_vec); 2099 | if (tok.value == "else") { 2100 | token_vec.remove(0); 2101 | result.else_state = Some(Box::new(parse_statement(token_vec))); 2102 | } 2103 | 2104 | 2105 | result 2106 | } 2107 | 2108 | pub fn parse_declaration(token_vec : &mut Vec) -> Declaration { 2109 | let mut result : Declaration = Declaration::new(); 2110 | let mut tok : lexer::Token = peek_next_token(token_vec); 2111 | 2112 | assert!(tok.name == "Type" && 2113 | (tok.value == "int"), 2114 | "Invalid declaration, saw: {}", tok.value); 2115 | 2116 | result.var_type = tok.value; 2117 | token_vec.remove(0); 2118 | tok = get_next_token(token_vec); 2119 | result.var = Variable {var_name : tok.value.clone()}; 2120 | 2121 | tok = peek_next_token(token_vec); 2122 | if (tok.value == "=" && tok.name == "AssignOp") { 2123 | token_vec.remove(0); 2124 | result.exp = parse_assign(token_vec); 2125 | } 2126 | else { 2127 | // Default to zero. 2128 | result.exp = Assignment::set_to_zero(); 2129 | } 2130 | 2131 | result 2132 | } 2133 | 2134 | pub fn is_assignment_op(s : String) -> bool { 2135 | let op = vec!["=", "+=", "-=", "*=", "/=", "&=", "|=", "^=", ">>=", "<<=", "%="]; 2136 | op.contains(&s.as_str()) 2137 | } 2138 | 2139 | pub fn parse_assign(token_vec : &mut Vec) -> Assignment { 2140 | let mut result : Assignment = Assignment::new(); 2141 | let tok : lexer::Token = peek_next_token(token_vec); 2142 | 2143 | assert!(tok.name == "Num" || 2144 | tok.value == "(" || 2145 | valid_unary(tok.value.clone()) || 2146 | valid_postfix_unary(tok.value.clone()) || 2147 | tok.name == "Identifier", 2148 | "Invalid assignment, saw: {}", tok.value); 2149 | 2150 | let mut next_tok = peek_two_tokens(&token_vec); 2151 | 2152 | if (tok.name == "Identifier" && is_assignment_op(next_tok.value.clone())) { 2153 | 2154 | result.op = next_tok.value.clone(); 2155 | 2156 | result.var = Some(Variable {var_name : tok.value.clone()}); 2157 | while (is_assignment_op(next_tok.value.clone())) { 2158 | 2159 | token_vec.remove(0); 2160 | token_vec.remove(0); 2161 | 2162 | result.exp = Some(parse_cond(token_vec)); 2163 | 2164 | result.assign = Some(Box::new(Assignment { 2165 | var : result.var.clone(), 2166 | assign : result.assign.clone(), 2167 | exp : result.exp.clone(), 2168 | op : result.op.clone(), 2169 | })); 2170 | 2171 | result.var = None; 2172 | result.exp = None; 2173 | 2174 | next_tok = peek_next_token(token_vec); 2175 | } 2176 | } 2177 | else { 2178 | // Not an assignment, move on. 2179 | result.exp = Some(parse_cond(token_vec)); 2180 | } 2181 | 2182 | result 2183 | } 2184 | 2185 | pub fn parse_cond(token_vec : &mut Vec) -> ConditionalExp { 2186 | let mut result : ConditionalExp = ConditionalExp::new(); 2187 | result.exp = parse_or_exp(token_vec); 2188 | 2189 | if (peek_next_token(token_vec).value == "?") { 2190 | token_vec.remove(0); 2191 | result.true_exp = Some(Box::new(parse_assign(token_vec))); 2192 | 2193 | assert!(peek_next_token(token_vec).value == ":", "Ternary missing \":\", saw {}", peek_next_token(token_vec).value); 2194 | 2195 | token_vec.remove(0); 2196 | result.false_exp = Some(Box::new(parse_cond(token_vec))); 2197 | } 2198 | 2199 | result 2200 | } 2201 | 2202 | pub fn valid_unary(s : String) -> bool { 2203 | let op = vec!["!", "~", "-", "+", "++", "--"]; 2204 | return op.contains(&(s.as_str())) 2205 | } 2206 | 2207 | pub fn valid_postfix_unary(s : String) -> bool { 2208 | let op = vec!["++", "--"]; 2209 | return op.contains(&(s.as_str())) 2210 | } 2211 | 2212 | pub fn parse_or_exp(token_vec : &mut Vec) -> OrExpression { 2213 | let mut result : OrExpression = OrExpression::new(); 2214 | let mut tok : lexer::Token = peek_next_token(token_vec); 2215 | 2216 | assert!(tok.name == "Num" || 2217 | tok.value == "(" || 2218 | valid_unary(tok.value.clone()) || 2219 | valid_postfix_unary(tok.value.clone()) || 2220 | tok.name == "Identifier", 2221 | "Invalid or_exp, saw \"{}\" : \"{}\"...", tok.name, tok.value); 2222 | 2223 | result.left_and_exp = Some(Box::new(parse_and_exp(token_vec))); 2224 | 2225 | tok = peek_next_token(token_vec); 2226 | 2227 | while (tok.value == "||") { 2228 | result.op = String::from(tok.value.clone()); 2229 | get_next_token(token_vec); 2230 | 2231 | result.right_and_exp = Some(Box::new(parse_and_exp(token_vec))); 2232 | tok = peek_next_token(token_vec); 2233 | 2234 | result.left_exp = Some(Box::new(OrExpression { 2235 | op : result.op.clone(), 2236 | left_exp : result.left_exp.clone(), 2237 | left_and_exp : result.left_and_exp.clone(), 2238 | right_and_exp : result.right_and_exp.clone(), 2239 | })); 2240 | 2241 | result.left_and_exp = None; 2242 | result.right_and_exp = None; 2243 | result.op = String::new(); 2244 | } 2245 | result 2246 | } 2247 | 2248 | pub fn parse_and_exp(token_vec : &mut Vec) -> AndExpression { 2249 | let mut result : AndExpression = AndExpression::new(); 2250 | let mut tok : lexer::Token = peek_next_token(token_vec); 2251 | 2252 | assert!(tok.name == "Num" || 2253 | tok.value == "(" || 2254 | valid_unary(tok.value.clone()) || 2255 | valid_postfix_unary(tok.value.clone()) || 2256 | tok.name == "Identifier", "Invalid and_exp, saw {}.", tok.value); 2257 | 2258 | result.left_child = Some(Box::new(parse_bitwise_or(token_vec))); 2259 | 2260 | tok = peek_next_token(token_vec); 2261 | 2262 | while (tok.value == "&&") { 2263 | result.op = String::from(tok.value.clone()); 2264 | get_next_token(token_vec); 2265 | 2266 | result.right_child = Some(Box::new(parse_bitwise_or(token_vec))); 2267 | tok = peek_next_token(token_vec); 2268 | 2269 | result.left_exp = Some(Box::new(AndExpression { 2270 | op : result.op.clone(), 2271 | left_exp : result.left_exp.clone(), 2272 | left_child : result.left_child.clone(), 2273 | right_child : result.right_child.clone(), 2274 | })); 2275 | 2276 | result.left_child = None; 2277 | result.right_child = None; 2278 | result.op = String::new(); 2279 | } 2280 | result 2281 | } 2282 | 2283 | pub fn parse_bitwise_or(token_vec : &mut Vec) -> BitOr { 2284 | let mut result : BitOr = BitOr::new(); 2285 | let mut tok : lexer::Token = peek_next_token(token_vec); 2286 | 2287 | assert!(tok.name == "Num" || 2288 | tok.value == "(" || 2289 | valid_unary(tok.value.clone()) || 2290 | valid_postfix_unary(tok.value.clone()) || 2291 | tok.name == "Identifier", 2292 | "Invalid rel_exp: {}.", tok.value); 2293 | 2294 | result.left_child = Some(Box::new(parse_bitwise_xor(token_vec))); 2295 | 2296 | tok = peek_next_token(token_vec); 2297 | 2298 | while (tok.value == "|") { 2299 | result.op = String::from(tok.value.clone()); 2300 | get_next_token(token_vec); 2301 | 2302 | result.right_child = Some(Box::new(parse_bitwise_xor(token_vec))); 2303 | tok = peek_next_token(token_vec); 2304 | 2305 | result.left_exp = Some(Box::new(BitOr { 2306 | op : result.op.clone(), 2307 | left_exp : result.left_exp.clone(), 2308 | left_child : result.left_child.clone(), 2309 | right_child : result.right_child.clone(), 2310 | })); 2311 | 2312 | result.left_child = None; 2313 | result.right_child = None; 2314 | result.op = String::new(); 2315 | } 2316 | 2317 | 2318 | result 2319 | } 2320 | 2321 | pub fn parse_bitwise_xor(token_vec : &mut Vec) -> BitXor { 2322 | let mut result : BitXor = BitXor::new(); 2323 | let mut tok : lexer::Token = peek_next_token(token_vec); 2324 | 2325 | assert!(tok.name == "Num" || 2326 | tok.value == "(" || 2327 | valid_unary(tok.value.clone()) || 2328 | valid_postfix_unary(tok.value.clone()) || 2329 | tok.name == "Identifier", 2330 | "Invalid rel_exp: {}.", tok.value); 2331 | 2332 | result.left_child = Some(Box::new(parse_bitwise_and(token_vec))); 2333 | 2334 | tok = peek_next_token(token_vec); 2335 | 2336 | while (tok.value == "^") { 2337 | result.op = String::from(tok.value.clone()); 2338 | get_next_token(token_vec); 2339 | 2340 | result.right_child = Some(Box::new(parse_bitwise_and(token_vec))); 2341 | tok = peek_next_token(token_vec); 2342 | 2343 | result.left_exp = Some(Box::new(BitXor { 2344 | op : result.op.clone(), 2345 | left_exp : result.left_exp.clone(), 2346 | left_child : result.left_child.clone(), 2347 | right_child : result.right_child.clone(), 2348 | })); 2349 | 2350 | result.left_child = None; 2351 | result.right_child = None; 2352 | result.op = String::new(); 2353 | } 2354 | 2355 | 2356 | result 2357 | } 2358 | 2359 | pub fn parse_bitwise_and(token_vec : &mut Vec) -> BitAnd { 2360 | let mut result : BitAnd = BitAnd::new(); 2361 | let mut tok : lexer::Token = peek_next_token(token_vec); 2362 | 2363 | assert!(tok.name == "Num" || 2364 | tok.value == "(" || 2365 | valid_unary(tok.value.clone()) || 2366 | valid_postfix_unary(tok.value.clone()) || 2367 | tok.name == "Identifier", 2368 | "Invalid rel_exp: {}.", tok.value); 2369 | 2370 | result.left_child = Some(Box::new(parse_equal_exp(token_vec))); 2371 | 2372 | tok = peek_next_token(token_vec); 2373 | 2374 | while (tok.value == "&") { 2375 | result.op = String::from(tok.value.clone()); 2376 | get_next_token(token_vec); 2377 | 2378 | result.right_child = Some(Box::new(parse_equal_exp(token_vec))); 2379 | tok = peek_next_token(token_vec); 2380 | 2381 | result.left_exp = Some(Box::new(BitAnd { 2382 | op : result.op.clone(), 2383 | left_exp : result.left_exp.clone(), 2384 | left_child : result.left_child.clone(), 2385 | right_child : result.right_child.clone(), 2386 | })); 2387 | 2388 | result.left_child = None; 2389 | result.right_child = None; 2390 | result.op = String::new(); 2391 | } 2392 | 2393 | 2394 | result 2395 | } 2396 | 2397 | pub fn parse_equal_exp(token_vec : &mut Vec) -> EqualityExp { 2398 | let mut result : EqualityExp = EqualityExp::new(); 2399 | let mut tok : lexer::Token = peek_next_token(token_vec); 2400 | 2401 | assert!(tok.name == "Num" || 2402 | tok.value == "(" || 2403 | valid_unary(tok.value.clone()) || 2404 | valid_postfix_unary(tok.value.clone()) || 2405 | tok.name == "Identifier", 2406 | "Invalid equal_exp: {}.", tok.value); 2407 | 2408 | result.left_relation_exp = Some(Box::new(parse_rel_exp(token_vec))); 2409 | 2410 | tok = peek_next_token(token_vec); 2411 | 2412 | while (tok.value == "==" || tok.value == "!=") { 2413 | result.op = String::from(tok.value.clone()); 2414 | get_next_token(token_vec); 2415 | 2416 | result.right_relation_exp = Some(Box::new(parse_rel_exp(token_vec))); 2417 | tok = peek_next_token(token_vec); 2418 | 2419 | result.left_exp = Some(Box::new(EqualityExp { 2420 | op : result.op.clone(), 2421 | left_exp : result.left_exp.clone(), 2422 | left_relation_exp : result.left_relation_exp.clone(), 2423 | right_relation_exp : result.right_relation_exp.clone(), 2424 | })); 2425 | 2426 | result.left_relation_exp = None; 2427 | result.right_relation_exp = None; 2428 | result.op = String::new(); 2429 | } 2430 | result 2431 | } 2432 | 2433 | 2434 | pub fn parse_rel_exp(token_vec : &mut Vec) -> RelationalExp { 2435 | let mut result : RelationalExp = RelationalExp::new(); 2436 | let mut tok : lexer::Token = peek_next_token(token_vec); 2437 | 2438 | assert!(tok.name == "Num" || 2439 | tok.value == "(" || 2440 | valid_unary(tok.value.clone()) || 2441 | valid_postfix_unary(tok.value.clone()) || 2442 | tok.name == "Identifier", 2443 | "Invalid rel_exp: {}.", tok.value); 2444 | 2445 | result.left_child = Some(Box::new(parse_bitwise_shift(token_vec))); 2446 | 2447 | tok = peek_next_token(token_vec); 2448 | 2449 | while (tok.value == ">" || tok.value == ">=" || tok.value == "<" || tok.value == "<=") { 2450 | result.op = String::from(tok.value.clone()); 2451 | get_next_token(token_vec); 2452 | 2453 | result.right_child = Some(Box::new(parse_bitwise_shift(token_vec))); 2454 | tok = peek_next_token(token_vec); 2455 | 2456 | result.left_exp = Some(Box::new(RelationalExp { 2457 | op : result.op.clone(), 2458 | left_exp : result.left_exp.clone(), 2459 | left_child : result.left_child.clone(), 2460 | right_child : result.right_child.clone(), 2461 | })); 2462 | 2463 | result.left_child = None; 2464 | result.right_child = None; 2465 | result.op = String::new(); 2466 | } 2467 | 2468 | 2469 | result 2470 | } 2471 | 2472 | pub fn parse_bitwise_shift(token_vec : &mut Vec) -> BitShift { 2473 | let mut result : BitShift = BitShift::new(); 2474 | let mut tok : lexer::Token = peek_next_token(token_vec); 2475 | 2476 | assert!(tok.name == "Num" || 2477 | tok.value == "(" || 2478 | valid_unary(tok.value.clone()) || 2479 | valid_postfix_unary(tok.value.clone()) || 2480 | tok.name == "Identifier", 2481 | "Invalid rel_exp: {}.", tok.value); 2482 | 2483 | result.left_child = Some(Box::new(parse_add_exp(token_vec))); 2484 | 2485 | tok = peek_next_token(token_vec); 2486 | 2487 | while (tok.value == ">>" || tok.value == "<<") { 2488 | result.op = String::from(tok.value.clone()); 2489 | get_next_token(token_vec); 2490 | 2491 | result.right_child = Some(Box::new(parse_add_exp(token_vec))); 2492 | tok = peek_next_token(token_vec); 2493 | 2494 | result.left_exp = Some(Box::new(BitShift { 2495 | op : result.op.clone(), 2496 | left_exp : result.left_exp.clone(), 2497 | left_child : result.left_child.clone(), 2498 | right_child : result.right_child.clone(), 2499 | })); 2500 | 2501 | result.left_child = None; 2502 | result.right_child = None; 2503 | result.op = String::new(); 2504 | } 2505 | 2506 | 2507 | result 2508 | } 2509 | 2510 | 2511 | pub fn parse_add_exp(token_vec : &mut Vec) -> AdditiveExp { 2512 | let mut result : AdditiveExp = AdditiveExp::new(); 2513 | let mut tok : lexer::Token = peek_next_token(token_vec); 2514 | 2515 | assert!(tok.name == "Num" || 2516 | tok.value == "(" || 2517 | valid_unary(tok.value.clone()) || 2518 | valid_postfix_unary(tok.value.clone()) || 2519 | tok.name == "Identifier", 2520 | "Invalid add_exp: {}.", tok.value); 2521 | 2522 | result.left_term = Some(Box::new(parse_term(token_vec))); 2523 | 2524 | tok = peek_next_token(token_vec); 2525 | 2526 | while (tok.value == "-" || tok.value == "+") { 2527 | result.op = String::from(tok.value.clone()); 2528 | get_next_token(token_vec); 2529 | 2530 | result.right_term = Some(Box::new(parse_term(token_vec))); 2531 | tok = peek_next_token(token_vec); 2532 | 2533 | result.left_exp = Some(Box::new(AdditiveExp { 2534 | op : result.op.clone(), 2535 | left_exp : result.left_exp.clone(), 2536 | left_term: result.left_term.clone(), 2537 | right_term : result.right_term.clone(), 2538 | })); 2539 | 2540 | result.left_term= None; 2541 | result.right_term= None; 2542 | result.op = String::new(); 2543 | } 2544 | 2545 | result 2546 | } 2547 | 2548 | pub fn parse_term(token_vec : &mut Vec) -> Term { 2549 | let mut result : Term = Term::new(); 2550 | let mut tok : lexer::Token = peek_next_token(token_vec); 2551 | 2552 | assert!(tok.name == "Num" || 2553 | tok.value == "(" || 2554 | valid_unary(tok.value.clone()) || 2555 | valid_postfix_unary(tok.value.clone()) || 2556 | tok.name == "Identifier", 2557 | "Invalid term: {}.", tok.value); 2558 | 2559 | let left_child : Factor = parse_factor(token_vec); 2560 | result.left_child = Some(Box::new(parse_postfix_unary(token_vec, left_child.clone()))); 2561 | tok = peek_next_token(token_vec); 2562 | 2563 | while (tok.value == "*" || tok.value == "/" || tok.value == "%") { 2564 | result.op = String::from(tok.value.clone()); 2565 | tok = get_next_token(token_vec); 2566 | 2567 | if (tok.value == "/" && peek_next_token(token_vec).name == "Num") { 2568 | if (peek_next_token(token_vec).value.parse::().unwrap() == 0) { 2569 | println!("Tried dividing by zero."); 2570 | std::process::exit(1); 2571 | } 2572 | } 2573 | 2574 | let right_child : Factor = parse_factor(token_vec); 2575 | result.right_child = Some(Box::new(parse_postfix_unary(token_vec, right_child.clone()))); 2576 | 2577 | tok = peek_next_token(token_vec); 2578 | 2579 | result.left_term = Some(Box::new(Term { 2580 | op : result.op.clone(), 2581 | left_term : result.left_term.clone(), 2582 | left_child : result.left_child.clone(), 2583 | right_child : result.right_child.clone(), 2584 | })); 2585 | 2586 | result.left_child = None; 2587 | result.right_child = None; 2588 | result.op = String::new(); 2589 | } 2590 | 2591 | result 2592 | } 2593 | 2594 | 2595 | pub fn parse_fn_call(token_vec : &mut Vec) -> FnCall { 2596 | let mut result : FnCall = FnCall::new(); 2597 | let mut tok : lexer::Token = peek_next_token(token_vec); 2598 | 2599 | result.name = tok.value; 2600 | token_vec.remove(0); 2601 | tok = get_next_token(token_vec); 2602 | assert!(tok.value == "(", "Missing ( in function call."); 2603 | tok = peek_next_token(token_vec); 2604 | 2605 | while (tok.value != ")") { 2606 | result.args.push(parse_assign(token_vec)); 2607 | tok = peek_next_token(token_vec); 2608 | if (tok.value == ",") { 2609 | token_vec.remove(0); 2610 | tok = peek_next_token(token_vec); 2611 | } 2612 | } 2613 | assert!(tok.value == ")", "Missing ) in function call."); 2614 | result 2615 | } 2616 | 2617 | 2618 | pub fn parse_factor(token_vec : &mut Vec) -> Factor { 2619 | let mut result : Factor = Factor::new(); 2620 | let mut tok : lexer::Token = peek_next_token(token_vec); 2621 | 2622 | 2623 | if (tok.value == "(") { 2624 | token_vec.remove(0); 2625 | result.exp = Some(Box::new(parse_assign(token_vec))); 2626 | tok = get_next_token(token_vec); 2627 | assert!(tok.value==")", "Missing closing paren, saw {}.", tok.value); 2628 | } 2629 | else if (valid_unary(tok.value.clone()) || valid_postfix_unary(tok.value.clone())) { 2630 | result.unary = Some(Box::new(parse_unary(token_vec))); 2631 | } 2632 | else if (tok.name == "Num") { 2633 | result.val = Some(tok.value.clone().parse::().unwrap()); 2634 | token_vec.remove(0); 2635 | //println!("Found num: {}", tok.value); 2636 | } 2637 | else if (tok.name == "Identifier") { 2638 | // Either variable or function! 2639 | if (peek_two_tokens(token_vec).value == "(") { 2640 | result.fn_call = Some(parse_fn_call(token_vec)); 2641 | } 2642 | else { 2643 | result.var = Some(Variable { var_name : tok.value.clone() }); 2644 | } 2645 | token_vec.remove(0); 2646 | //println!("Found identifier: {}", tok.value); 2647 | } 2648 | 2649 | result 2650 | } 2651 | 2652 | pub fn parse_unary(token_vec : &mut Vec) -> Unary { 2653 | let mut result : Unary = Unary::new(); 2654 | let tok : lexer::Token = get_next_token(token_vec); 2655 | 2656 | result.op = String::from(tok.value); 2657 | result.child = Some(Box::new(parse_factor(token_vec))); 2658 | 2659 | result 2660 | } 2661 | 2662 | 2663 | pub fn parse_postfix_unary(token_vec : &mut Vec, factor : Factor) -> PostFixUnary { 2664 | let mut result : PostFixUnary = PostFixUnary::new(); 2665 | let tok : lexer::Token = peek_next_token(token_vec); 2666 | 2667 | if (tok.value.clone() == "--" || tok.value.clone() == "++") { 2668 | result.op = tok.value.clone(); 2669 | token_vec.remove(0); 2670 | } 2671 | 2672 | result.child = Some(Box::new(factor)); 2673 | 2674 | //result.child = Some(Box::new(parse_factor(token_vec))); 2675 | 2676 | result 2677 | } 2678 | 2679 | pub fn print_tokens(token_vec : &Vec) { 2680 | println!("=====Resulting tokens====="); 2681 | for token in &*token_vec { 2682 | println!("Token: {}", token); 2683 | } 2684 | println!("=====End of tokens====="); 2685 | } 2686 | 2687 | pub fn parse_to_ast(filename : &String) -> Program { 2688 | // Take in file. 2689 | let mut file_contents = fs::read_to_string(filename).expect("Could not read file."); 2690 | print!("=====Contents of file=====\n{}", file_contents); 2691 | print!("=====End of file contents=====\n"); 2692 | 2693 | // Convert to tokens 2694 | let mut token_vec : Vec = lexer::lexer(&mut file_contents); 2695 | //print_tokens(&token_vec); 2696 | 2697 | // Parse tokens into AST 2698 | let result_ast : Program = parse_program(&mut token_vec); 2699 | //print_ast(&result_ast); 2700 | 2701 | result_ast 2702 | } 2703 | 2704 | -------------------------------------------------------------------------------- /src/parser/lexer.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_parens)] 2 | #![allow(unused_variables)] 3 | 4 | use std::str; 5 | use std::fmt; 6 | 7 | pub struct Token { 8 | pub name : String, 9 | pub value : String, 10 | } 11 | 12 | impl Clone for Token { 13 | fn clone(&self) -> Self { 14 | Token { name: self.name.clone(), value: self.value.clone()} 15 | } 16 | } 17 | 18 | impl fmt::Display for Token { 19 | fn fmt (&self, f: &mut fmt:: Formatter) -> fmt::Result { 20 | write!(f, "name: {}, value: {}", self.name, self.value) 21 | } 22 | } 23 | 24 | 25 | pub fn is_number (c : char) -> bool { 26 | let nums = "0123456789"; 27 | nums.contains(c) 28 | } 29 | 30 | pub fn is_letter (c : char) -> bool { 31 | let letters = "abcdefghijklmnopqrstuvwxyz"; 32 | letters.contains(c) 33 | } 34 | 35 | pub fn is_punctuation (c : char) -> bool { 36 | let punc = "{}();,"; 37 | punc.contains(c) 38 | } 39 | 40 | pub fn is_op (c : char) -> bool { 41 | let op = "-~!+*/%&|^?:"; 42 | op.contains(c) 43 | } 44 | 45 | pub fn is_unary (c : char) -> bool { 46 | let op = "-~!"; 47 | op.contains(c) 48 | } 49 | 50 | pub fn is_second_char_check (c : char) -> bool { 51 | let op = "=|&<>+-"; 52 | op.contains(c) 53 | } 54 | 55 | pub fn is_third_char_check (c : char) -> bool { 56 | let op = "="; 57 | op.contains(c) 58 | } 59 | 60 | pub fn is_a_two_char_op (val : &str) -> bool { 61 | let op = vec!["+=", "-=", "/=", "*=", "%=", "&=", "^=", "|=", "++", "--", "<", ">", "<=", ">=", "==", "!=", "||", "&&", "<<", ">>"]; 62 | op.contains(&val) 63 | } 64 | 65 | pub fn is_a_three_char_op (val : &str) -> bool { 66 | let op = vec!["<<=", ">>="]; 67 | op.contains(&val) 68 | } 69 | 70 | pub fn is_assign_op (c : char) -> bool { 71 | c == '=' 72 | } 73 | 74 | pub fn read_identifier (input : &mut String) -> Token { 75 | let keywords = vec!["return", "if", "else", "for", "while", "do", "break", "continue"]; 76 | let types = vec!["int"]; 77 | 78 | 79 | let mut iden_name = String::new(); 80 | let tmp = input.clone(); 81 | for c in tmp.chars() { 82 | if (is_number(c) || is_letter(c)) { 83 | iden_name.push(c); 84 | input.remove(0); 85 | } 86 | else { 87 | break; 88 | } 89 | } 90 | 91 | if (keywords.contains(&&*iden_name)) { 92 | Token {name : String::from("Keyword"), value : iden_name} 93 | } 94 | else if (types.contains(&&*iden_name)) { 95 | Token {name: String::from("Type"), value : iden_name} 96 | } 97 | else { 98 | Token {name : String::from("Identifier"), value : iden_name} 99 | } 100 | } 101 | 102 | pub fn read_number (input : &mut String) -> Token { 103 | let mut iden_name = String::new(); 104 | let tmp = input.clone(); 105 | for c in tmp.chars() { 106 | if (!c.is_whitespace() && is_number(c)) { 107 | iden_name.push(c); 108 | input.remove(0); 109 | } 110 | else { 111 | break; 112 | } 113 | } 114 | 115 | Token {name : String::from("Num"), value : iden_name} 116 | } 117 | 118 | pub fn read_punc (input : &mut String) -> Token { 119 | let ret_punc = input.chars().next().unwrap().to_string(); 120 | input.remove(0); 121 | Token {name : String::from("Punc"), value : ret_punc} 122 | } 123 | 124 | pub fn read_op (input : &mut String) -> Token { 125 | let ret_op = input.chars().next().unwrap().to_string(); 126 | input.remove(0); 127 | Token{name : String::from("Op"), value : ret_op} 128 | } 129 | 130 | pub fn read_assign_op(input : &mut String) -> Token { 131 | input.remove(0); 132 | Token{name : String::from("AssignOp"), value : String::from("=")} 133 | } 134 | 135 | pub fn read_multi_op(input : &mut String, ret_op : String) -> Token { 136 | for x in 0..ret_op.len() { 137 | input.remove(0); 138 | } 139 | let op = vec!["+=", "-=", "/=", "*=", "%=", "^=", "&=", "|=", "<<=", ">>="]; 140 | if (op.contains(&ret_op.as_str())) { 141 | Token{name : String::from("AssignOp"), value : ret_op} 142 | } 143 | else { 144 | Token{name : String::from("Op"), value : ret_op} 145 | } 146 | } 147 | 148 | pub fn lexer(input : &mut String) -> Vec { 149 | let mut token_vec : Vec = Vec::new(); 150 | let mut c : char; 151 | 152 | while (input.len() > 0) { 153 | c = input.chars().next().unwrap(); 154 | 155 | if (!c.is_whitespace()) { 156 | if (input.len() > 1) { 157 | let mut tmp_input = input.clone(); 158 | tmp_input.remove(0); 159 | let second_char : char = tmp_input.chars().next().unwrap(); 160 | let two_char_val : String = if (second_char.is_whitespace() || !is_second_char_check(second_char)) { 161 | c.to_string() 162 | } 163 | else { 164 | c.to_string() + second_char.to_string().as_str() 165 | }; 166 | 167 | if (input.len() > 2) { 168 | tmp_input.remove(0); 169 | let third_char : char = tmp_input.chars().next().unwrap(); 170 | 171 | 172 | 173 | let three_char_val : String = if (two_char_val.len() == 2 && 174 | !third_char.is_whitespace() && 175 | is_third_char_check(third_char)) { 176 | two_char_val.clone() + third_char.to_string().as_str() 177 | } 178 | else { 179 | c.to_string() 180 | }; 181 | 182 | if (is_a_three_char_op(three_char_val.as_str())) { 183 | token_vec.push(read_multi_op(input, three_char_val.clone())); 184 | continue; 185 | } 186 | else if (is_a_two_char_op(two_char_val.as_str())) { 187 | token_vec.push(read_multi_op(input, two_char_val.clone())); 188 | continue; 189 | } 190 | } 191 | else { 192 | if (is_a_two_char_op(two_char_val.as_str())) { 193 | token_vec.push(read_multi_op(input, two_char_val.clone())); 194 | continue; 195 | } 196 | } 197 | } 198 | if (is_letter(c)) { 199 | // Must be identifier, as no quotes (not supported yet). 200 | token_vec.push(read_identifier(input)); 201 | } 202 | else if (is_assign_op(c)) { 203 | token_vec.push(read_assign_op(input)); 204 | } 205 | else if (is_number(c)) { 206 | token_vec.push(read_number(input)); 207 | } 208 | else if (is_punctuation(c)) { 209 | token_vec.push(read_punc(input)); 210 | } 211 | else if (is_op(c)) { 212 | token_vec.push(read_op(input)); 213 | } 214 | else { 215 | println!("Found a character that the lexer does not recognize: {}.", c); 216 | std::process::exit(1); 217 | } 218 | } 219 | else { 220 | input.remove(0); 221 | } 222 | } 223 | 224 | //token_vec.push(Token{name : String::from("EOF TOKEN"), value : String::from("EOFunc")}); 225 | token_vec.push(Token{name : String::from("EOF TOKEN"), value : String::from("EOFile")}); 226 | token_vec 227 | } 228 | 229 | -------------------------------------------------------------------------------- /test_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rust_fail_count=0 4 | rust_total_count=0 5 | compile_fail_count=0 6 | compile_total_count=0 7 | run_fail_count=0 8 | run_total_count=0 9 | 10 | 11 | fail() { 12 | echo "${2} test => ${1} ----- FAILED" 13 | } 14 | 15 | pass() { 16 | echo "${2} test => ${1} ----- PASSED" 17 | } 18 | 19 | test_compile_run() { 20 | if [ -e "${1%.*}" ]; then 21 | rm "${1%.*}" 22 | fi 23 | 24 | compile_total_count=$((compile_total_count+1)) 25 | 26 | gcc -m32 ${1} -o "${1%.*}" &> /dev/null 27 | if [ "$?" -ne 0 ]; then 28 | fail ${1} "compile" 29 | compile_fail_count=$((compile_fail_count+1)) 30 | return 101; 31 | else 32 | pass ${1} "compile" 33 | fi 34 | 35 | run_total_count=$((run_total_count+1)) 36 | "./${1%.*}" > /dev/null 37 | ret_val="$?" 38 | if [ -e "${1%.*}" ]; then 39 | rm "${1%.*}" 40 | fi 41 | 42 | gcc -m32 "${1%.*}.c" -o "${1%.*}" > /dev/null 43 | "./${1%.*}" > /dev/null 44 | 45 | actual_val="$?" 46 | 47 | if [ -e "${1%.*}" ]; then 48 | rm "${1%.*}" 49 | fi 50 | 51 | if [ ${actual_val} -eq ${ret_val} ]; then 52 | pass ${1} "run" 53 | else 54 | fail ${1} "run" 55 | echo "Saw ${ret_val}, wanted ${actual_val}." 56 | run_fail_count=$((run_fail_count+1)) 57 | return 101; 58 | fi 59 | } 60 | 61 | run_test() { 62 | if [ -e "${1%.*}.s" ]; then 63 | rm "${1%.*}.s" 64 | fi 65 | 66 | cargo run ${1} &> /dev/null 67 | 68 | ret_val="$?" 69 | 70 | 71 | if [ ${2} -eq 0 ]; then 72 | if [ $ret_val -eq 0 ]; then 73 | pass ${1} "Rust" 74 | elif [ $ret_val -ne 0 ]; then 75 | fail ${1} "Rust" 76 | rust_fail_count=$((rust_fail_count+1)) 77 | fi 78 | elif [ ${2} -eq 1 ]; then 79 | if [ $ret_val -ne 0 ]; then 80 | pass ${1} "Rust" 81 | elif [ $ret_val -eq 0 ]; then 82 | fail ${1} "Rust" 83 | rust_fail_count=$((rust_fail_count+1)) 84 | fi 85 | fi 86 | 87 | rust_total_count=$((rust_total_count+1)) 88 | } 89 | 90 | for dir in ./examples/*; do 91 | for topic in ${dir}/*; do 92 | for tests in "${topic}/*.c"; do 93 | for test in ${tests}; do 94 | #echo ${test} 95 | if [[ ${test} = *"Passing"* ]]; then 96 | run_test "${test}" 0 97 | #echo "SHOULD PASS: $test" 98 | elif [[ ${test} = *"Failing"* ]]; then 99 | run_test "${test}" 1 100 | #echo "SHOULD \'FAIL\': $test" 101 | fi 102 | done 103 | done 104 | done 105 | done 106 | 107 | for dir in ./examples/Passing/*; do 108 | for topic in "${dir}/*.s"; do 109 | for test in ${topic}; do 110 | test_compile_run "${test}" 111 | 112 | done 113 | done 114 | done 115 | 116 | echo "Rust: Failed ${rust_fail_count} test cases out of ${rust_total_count}." 117 | echo "Compiling: Failed ${compile_fail_count} test cases out of ${compile_total_count}." 118 | echo "Return result: Failed ${run_fail_count} test cases out of ${run_total_count}." 119 | --------------------------------------------------------------------------------