├── LICENSE ├── README.md ├── stage_1 ├── invalid │ ├── missing_paren.c │ ├── missing_retval.c │ ├── no_brace.c │ ├── no_semicolon.c │ ├── no_space.c │ └── wrong_case.c └── valid │ ├── multi_digit.c │ ├── newlines.c │ ├── no_newlines.c │ ├── return_0.c │ ├── return_2.c │ └── spaces.c ├── stage_10 ├── invalid │ ├── fun_redefined_as_var.c │ ├── multiple_global_defs.c │ ├── non_constant_init.c │ ├── use_before_declaration.c │ ├── var_redefined_as_fun.c │ └── variable_used_as_fun.c └── valid │ ├── forward_declaration.c │ ├── fun_shadowed_by_variable.c │ ├── global.c │ ├── global_not_initialized.c │ ├── global_shadowed.c │ └── multiple_global.c ├── stage_2 ├── invalid │ ├── missing_const.c │ ├── missing_semicolon.c │ ├── nested_missing_const.c │ └── wrong_order.c └── valid │ ├── bitwise.c │ ├── bitwise_zero.c │ ├── neg.c │ ├── nested_ops.c │ ├── nested_ops_2.c │ ├── not_five.c │ └── not_zero.c ├── stage_3 ├── invalid │ ├── malformed_paren.c │ ├── missing_first_op.c │ ├── missing_second_op.c │ └── no_semicolon.c └── valid │ ├── add.c │ ├── associativity.c │ ├── associativity_2.c │ ├── div.c │ ├── div_neg.c │ ├── mult.c │ ├── parens.c │ ├── precedence.c │ ├── sub.c │ ├── sub_neg.c │ ├── unop_add.c │ └── unop_parens.c ├── stage_4 ├── invalid │ ├── missing_first_op.c │ ├── missing_mid_op.c │ ├── missing_second_op.c │ └── missing_semicolon.c └── valid │ ├── and_false.c │ ├── and_true.c │ ├── eq_false.c │ ├── eq_true.c │ ├── ge_false.c │ ├── ge_true.c │ ├── gt_false.c │ ├── gt_true.c │ ├── le_false.c │ ├── le_true.c │ ├── lt_false.c │ ├── lt_true.c │ ├── ne_false.c │ ├── ne_true.c │ ├── or_false.c │ ├── or_true.c │ ├── precedence.c │ ├── precedence_2.c │ ├── precedence_3.c │ ├── precedence_4.c │ ├── skip_on_failure_multi_short_circuit.c │ ├── skip_on_failure_short_circuit_and.c │ └── skip_on_failure_short_circuit_or.c ├── stage_5 ├── invalid │ ├── redefine.c │ ├── syntax_err_bad_decl.c │ ├── syntax_err_bad_decl_2.c │ ├── syntax_err_bad_lvalue.c │ ├── syntax_err_bad_lvalue_2.c │ ├── syntax_err_no_semicolon.c │ ├── undeclared_var.c │ └── var_declared_late.c └── valid │ ├── assign.c │ ├── assign_val.c │ ├── exp_return_val.c │ ├── initialize.c │ ├── missing_return.c │ ├── multiple_vars.c │ ├── no_initialize.c │ ├── refer.c │ └── unused_exp.c ├── stage_6 ├── invalid │ ├── expression │ │ ├── incomplete_ternary.c │ │ ├── malformed_ternary.c │ │ ├── malformed_ternary_2.c │ │ └── ternary_assign.c │ └── statement │ │ ├── declare_statement.c │ │ ├── if_assignment.c │ │ └── mismatched_nesting.c └── valid │ ├── expression │ ├── assign_ternary.c │ ├── multiple_ternary.c │ ├── nested_ternary.c │ ├── nested_ternary_2.c │ ├── rh_assignment.c │ ├── ternary.c │ ├── ternary_short_circuit.c │ └── ternary_short_circuit_2.c │ └── statement │ ├── else.c │ ├── if_nested.c │ ├── if_nested_2.c │ ├── if_nested_3.c │ ├── if_nested_4.c │ ├── if_nested_5.c │ ├── if_not_taken.c │ ├── if_taken.c │ └── multiple_if.c ├── stage_7 ├── invalid │ ├── double_define.c │ ├── out_of_scope.c │ ├── syntax_err_extra_brace.c │ └── syntax_err_missing_brace.c └── valid │ ├── consecutive_blocks.c │ ├── consecutive_declarations.c │ ├── declare_after_block.c │ ├── declare_block.c │ ├── declare_late.c │ ├── multi_nesting.c │ ├── nested_if.c │ └── nested_scope.c ├── stage_8 ├── invalid │ ├── break_not_in_loop.c │ ├── continue_not_in_loop.c │ ├── out_of_scope.c │ ├── out_of_scope_do_while.c │ ├── syntax_err_do_no_semicolon.c │ ├── syntax_err_empty_clause.c │ ├── syntax_err_paren_mismatch.c │ ├── syntax_err_statement_in_condition.c │ ├── syntax_err_too_few_for_clauses.c │ └── syntax_err_too_many_for_clauses.c └── valid │ ├── break.c │ ├── continue.c │ ├── continue_empty_post.c │ ├── do_while.c │ ├── empty_expression.c │ ├── for.c │ ├── for_decl.c │ ├── for_empty.c │ ├── for_nested_scope.c │ ├── for_variable_shadow.c │ ├── nested_break.c │ ├── nested_while.c │ ├── return_in_while.c │ ├── while_multi_statement.c │ └── while_single_statement.c ├── stage_9 ├── invalid │ ├── bad_arg.c │ ├── declaration_mismatch.c │ ├── declaration_mismatch_2.c │ ├── redefine_function.c │ ├── redefine_variable.c │ └── too_many_args.c └── valid │ ├── expression_args.c │ ├── fib.c │ ├── forward_decl.c │ ├── forward_decl_args.c │ ├── forward_decl_multi_arg.c │ ├── fun_in_expr.c │ ├── hello_world.c │ ├── later_decl.c │ ├── multi_arg.c │ ├── mutual_recursion.c │ ├── no_arg.c │ ├── precedence.c │ ├── rename_function_param.c │ ├── single_arg.c │ └── variable_as_arg.c └── test_compiler.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Nora Sandler 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 | # Write a C Compiler! 2 | 3 | **This repo is no longer active. The latest version of this test suite, which accompanies the [Writing a C Compiler book](https://nostarch.com/writing-c-compiler), is available [here](https://github.com/nlsandler/writing-a-c-compiler-tests/).** 4 | 5 | This is a set of C test programs to help you write your own compiler. They were written to accompany [this tutorial](https://norasandler.com/2017/11/29/Write-a-Compiler.html). 6 | 7 | ## Usage 8 | 9 | ### test all 10 | ``` 11 | ./test_compiler.sh /path/to/your/compiler 12 | ``` 13 | 14 | ### test specific stages 15 | To test stage 1 and stage 3, 16 | ``` 17 | ./test_compiler.sh /path/to/your/compiler 1 3 18 | ``` 19 | To test from stage 1 to stage 6, 20 | ``` 21 | ./test_compiler.sh /path/to/your/compiler `seq 1 6` 22 | ``` 23 | 24 | In order to use this script, your compiler needs to follow this spec: 25 | 26 | 1. It can be invoked from the command line, taking only a C source file as an argument, e.g.: `./YOUR_COMPILER /path/to/program.c` 27 | 28 | 2. When passed `program.c`, it generates executable `program` in the same directory. 29 | 30 | 3. It doesn’t generate assembly or an executable if parsing fails (this is what the test script checks for invalid test programs). 31 | 32 | The script doesn’t check whether your compiler outputs sensible error messages, but you can use the invalid test programs to test that manually. 33 | 34 | ## Contribute 35 | 36 | Additional test cases welcome! You can also file issues here, either about the test suite itself or about the content of the tutorial. 37 | -------------------------------------------------------------------------------- /stage_1/invalid/missing_paren.c: -------------------------------------------------------------------------------- 1 | int main( { 2 | return 0; 3 | } -------------------------------------------------------------------------------- /stage_1/invalid/missing_retval.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return; 3 | } -------------------------------------------------------------------------------- /stage_1/invalid/no_brace.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0; 3 | -------------------------------------------------------------------------------- /stage_1/invalid/no_semicolon.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0 3 | } 4 | -------------------------------------------------------------------------------- /stage_1/invalid/no_space.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return0; 3 | } -------------------------------------------------------------------------------- /stage_1/invalid/wrong_case.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | RETURN 0; 3 | } -------------------------------------------------------------------------------- /stage_1/valid/multi_digit.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 100; 3 | } -------------------------------------------------------------------------------- /stage_1/valid/newlines.c: -------------------------------------------------------------------------------- 1 | 2 | int 3 | main 4 | ( 5 | ) 6 | { 7 | return 8 | 0 9 | ; 10 | } -------------------------------------------------------------------------------- /stage_1/valid/no_newlines.c: -------------------------------------------------------------------------------- 1 | int main(){return 0;} -------------------------------------------------------------------------------- /stage_1/valid/return_0.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0; 3 | } -------------------------------------------------------------------------------- /stage_1/valid/return_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2; 3 | } -------------------------------------------------------------------------------- /stage_1/valid/spaces.c: -------------------------------------------------------------------------------- 1 | int main ( ) { return 0 ; } -------------------------------------------------------------------------------- /stage_10/invalid/fun_redefined_as_var.c: -------------------------------------------------------------------------------- 1 | int foo() { 2 | return 3; 3 | } 4 | 5 | int foo = 4; 6 | 7 | int main() { 8 | return foo; 9 | } -------------------------------------------------------------------------------- /stage_10/invalid/multiple_global_defs.c: -------------------------------------------------------------------------------- 1 | int foo = 3; 2 | 3 | int main() { 4 | return foo; 5 | } 6 | 7 | int foo = 0; -------------------------------------------------------------------------------- /stage_10/invalid/non_constant_init.c: -------------------------------------------------------------------------------- 1 | int foo = 3; 2 | int bar = foo + 1; 3 | 4 | int main() { 5 | return bar; 6 | } -------------------------------------------------------------------------------- /stage_10/invalid/use_before_declaration.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return foo; 3 | } 4 | 5 | int foo = 3; -------------------------------------------------------------------------------- /stage_10/invalid/var_redefined_as_fun.c: -------------------------------------------------------------------------------- 1 | int foo = 4; 2 | 3 | int foo() { 4 | return 3; 5 | } 6 | 7 | int main() { 8 | return foo; 9 | } -------------------------------------------------------------------------------- /stage_10/invalid/variable_used_as_fun.c: -------------------------------------------------------------------------------- 1 | int foo = 3; 2 | 3 | int main() { 4 | return foo(); 5 | } -------------------------------------------------------------------------------- /stage_10/valid/forward_declaration.c: -------------------------------------------------------------------------------- 1 | int foo; 2 | 3 | int main() { 4 | return foo; 5 | } 6 | 7 | int foo = 3; -------------------------------------------------------------------------------- /stage_10/valid/fun_shadowed_by_variable.c: -------------------------------------------------------------------------------- 1 | int foo() { 2 | return 3; 3 | } 4 | 5 | int main() { 6 | int foo = 5; 7 | return foo; 8 | } -------------------------------------------------------------------------------- /stage_10/valid/global.c: -------------------------------------------------------------------------------- 1 | int foo = 4; 2 | 3 | int main() { 4 | return foo + 3; 5 | } -------------------------------------------------------------------------------- /stage_10/valid/global_not_initialized.c: -------------------------------------------------------------------------------- 1 | int foo; 2 | 3 | int main() { 4 | for (int i = 0; i < 3; i = i + 1) 5 | foo = foo + 1; 6 | return foo; 7 | } -------------------------------------------------------------------------------- /stage_10/valid/global_shadowed.c: -------------------------------------------------------------------------------- 1 | int a = 3; 2 | 3 | int main() { 4 | int ret = 0; 5 | if (a) { 6 | int a = 0; 7 | ret = 4; 8 | } 9 | return ret; 10 | } -------------------------------------------------------------------------------- /stage_10/valid/multiple_global.c: -------------------------------------------------------------------------------- 1 | int a = 3; 2 | int b = 4; 3 | 4 | int main() { 5 | return a * b; 6 | } -------------------------------------------------------------------------------- /stage_2/invalid/missing_const.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !; 3 | } -------------------------------------------------------------------------------- /stage_2/invalid/missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !5 3 | } -------------------------------------------------------------------------------- /stage_2/invalid/nested_missing_const.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !~; 3 | } -------------------------------------------------------------------------------- /stage_2/invalid/wrong_order.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 4-; 3 | } -------------------------------------------------------------------------------- /stage_2/valid/bitwise.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return ~12; 3 | } 4 | -------------------------------------------------------------------------------- /stage_2/valid/bitwise_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return ~0; 3 | } -------------------------------------------------------------------------------- /stage_2/valid/neg.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -5; 3 | } -------------------------------------------------------------------------------- /stage_2/valid/nested_ops.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !-3; 3 | } -------------------------------------------------------------------------------- /stage_2/valid/nested_ops_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -~0; 3 | } -------------------------------------------------------------------------------- /stage_2/valid/not_five.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !5; 3 | } -------------------------------------------------------------------------------- /stage_2/valid/not_zero.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return !0; 3 | } -------------------------------------------------------------------------------- /stage_3/invalid/malformed_paren.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 (- 3); 3 | } -------------------------------------------------------------------------------- /stage_3/invalid/missing_first_op.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return /3; 3 | } -------------------------------------------------------------------------------- /stage_3/invalid/missing_second_op.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 + ; 3 | } -------------------------------------------------------------------------------- /stage_3/invalid/no_semicolon.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2*2 3 | } -------------------------------------------------------------------------------- /stage_3/valid/add.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 + 2; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/associativity.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 - 2 - 3; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/associativity_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 6 / 3 / 2; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/div.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 4 / 2; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/div_neg.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return (-12) / 5; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/mult.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 * 3; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/parens.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 * (3 + 4); 3 | } -------------------------------------------------------------------------------- /stage_3/valid/precedence.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 + 3 * 4; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/sub.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 - 2; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/sub_neg.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2- -1; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/unop_add.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return ~2 + 3; 3 | } -------------------------------------------------------------------------------- /stage_3/valid/unop_parens.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return ~(1 + 1); 3 | } -------------------------------------------------------------------------------- /stage_4/invalid/missing_first_op.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return <= 2; 3 | } -------------------------------------------------------------------------------- /stage_4/invalid/missing_mid_op.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 < > 3; 3 | } -------------------------------------------------------------------------------- /stage_4/invalid/missing_second_op.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 && 3 | } -------------------------------------------------------------------------------- /stage_4/invalid/missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 || 2 3 | } -------------------------------------------------------------------------------- /stage_4/valid/and_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 && 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/and_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 && -1; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/eq_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 == 2; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/eq_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 == 1; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/ge_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 >= 2; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/ge_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 >= 1; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/gt_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 > 2; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/gt_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 > 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/le_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 <= -1; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/le_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0 <= 2; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/lt_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 < 1; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/lt_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 < 2; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/ne_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0 != 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/ne_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return -1 != -2; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/or_false.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 0 || 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/or_true.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 || 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/precedence.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 || 0 && 2; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/precedence_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return (1 || 0) && 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/precedence_3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 == 2 > 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/precedence_4.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 2 == 2 || 0; 3 | } -------------------------------------------------------------------------------- /stage_4/valid/skip_on_failure_multi_short_circuit.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | a || (a = 3) || (a = 4); 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_4/valid/skip_on_failure_short_circuit_and.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | int b = 0; 4 | a && (b = 5); 5 | return b; 6 | } -------------------------------------------------------------------------------- /stage_4/valid/skip_on_failure_short_circuit_or.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int b = 0; 4 | a || (b = 5); 5 | return b; 6 | } -------------------------------------------------------------------------------- /stage_5/invalid/redefine.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int a = 2; 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_5/invalid/syntax_err_bad_decl.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | ints a = 1; 3 | return a; 4 | } -------------------------------------------------------------------------------- /stage_5/invalid/syntax_err_bad_decl_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int foo bar = 3; 3 | return bar; 4 | } -------------------------------------------------------------------------------- /stage_5/invalid/syntax_err_bad_lvalue.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | a + 3 = 4; 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_5/invalid/syntax_err_bad_lvalue_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | !a = 3; 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_5/invalid/syntax_err_no_semicolon.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2 3 | a = a + 4; 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_5/invalid/undeclared_var.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return a; 3 | } -------------------------------------------------------------------------------- /stage_5/invalid/var_declared_late.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | a = 1 + 2; 3 | int a; 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_5/valid/assign.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | a = 2; 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_5/valid/assign_val.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | int b = a = 0; 4 | return b; 5 | } -------------------------------------------------------------------------------- /stage_5/valid/exp_return_val.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | int b; 4 | a = b = 4; 5 | return a - b; 6 | } -------------------------------------------------------------------------------- /stage_5/valid/initialize.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /stage_5/valid/missing_return.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | 3 | } -------------------------------------------------------------------------------- /stage_5/valid/multiple_vars.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int b = 2; 4 | return a + b; 5 | } -------------------------------------------------------------------------------- /stage_5/valid/no_initialize.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /stage_5/valid/refer.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | return a; 4 | } -------------------------------------------------------------------------------- /stage_5/valid/unused_exp.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | 2 + 2; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /stage_6/invalid/expression/incomplete_ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 ? 2; 3 | } -------------------------------------------------------------------------------- /stage_6/invalid/expression/malformed_ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 ? 2 : 3 : 4; 3 | } -------------------------------------------------------------------------------- /stage_6/invalid/expression/malformed_ternary_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | return 1 ? 2 ? 3 : 4; 3 | } -------------------------------------------------------------------------------- /stage_6/invalid/expression/ternary_assign.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | int b = 1; 4 | a > b ? a = 1 : a = 0; 5 | return a; 6 | } -------------------------------------------------------------------------------- /stage_6/invalid/statement/declare_statement.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (5) 3 | int i = 0; 4 | } -------------------------------------------------------------------------------- /stage_6/invalid/statement/if_assignment.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int flag = 0; 3 | int a = if (flag) 4 | 2; 5 | else 6 | 3; 7 | return a; 8 | } -------------------------------------------------------------------------------- /stage_6/invalid/statement/mismatched_nesting.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | if (1) 4 | return 1; 5 | else 6 | return 2; 7 | else 8 | return 3; 9 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/assign_ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | a = 1 ? 2 : 3; 4 | return a; 5 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/multiple_ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1 > 2 ? 3 : 4; 3 | int b = 1 > 2 ? 5 : 6; 4 | return a + b; 5 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/nested_ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int b = 2; 4 | int flag = 0; 5 | 6 | return a > b ? 5 : flag ? 6 : 7; 7 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/nested_ternary_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1 ? 2 ? 3 : 4 : 5; 3 | int b = 0 ? 2 ? 3 : 4 : 5; 4 | return a * b; 5 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/rh_assignment.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int flag = 1; 3 | int a = 0; 4 | flag ? a = 1 : (a = 0); 5 | return a; 6 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/ternary.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | return a > -1 ? 4 : 5; 4 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/ternary_short_circuit.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int b = 0; 4 | a ? (b = 1) : (b = 2); 5 | return b; 6 | } -------------------------------------------------------------------------------- /stage_6/valid/expression/ternary_short_circuit_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | int b = 0; 4 | a ? (b = 1) : (b = 2); 5 | return b; 6 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/else.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | if (a) 4 | return 1; 5 | else 6 | return 2; 7 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/if_nested.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int b = 0; 4 | if (a) 5 | b = 1; 6 | else if (b) 7 | b = 2; 8 | return b; 9 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/if_nested_2.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | int b = 1; 4 | if (a) 5 | b = 1; 6 | else if (b) 7 | b = 2; 8 | return b; 9 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/if_nested_3.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | if (1) 4 | if (2) 5 | a = 3; 6 | else 7 | a = 4; 8 | 9 | return a; 10 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/if_nested_4.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | if (1) 4 | if (0) 5 | a = 3; 6 | else 7 | a = 4; 8 | 9 | return a; 10 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/if_nested_5.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | if (0) 4 | if (0) 5 | a = 3; 6 | else 7 | a = 4; 8 | else 9 | a = 1; 10 | 11 | return a; 12 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/if_not_taken.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | int b = 0; 4 | if (a) 5 | b = 1; 6 | return b; 7 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/if_taken.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int b = 0; 4 | if (a) 5 | b = 1; 6 | return b; 7 | } -------------------------------------------------------------------------------- /stage_6/valid/statement/multiple_if.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | int b = 0; 4 | 5 | if (a) 6 | a = 2; 7 | else 8 | a = 3; 9 | 10 | if (b) 11 | b = 4; 12 | else 13 | b = 5; 14 | 15 | return a + b; 16 | } -------------------------------------------------------------------------------- /stage_7/invalid/double_define.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | { 3 | int a; 4 | int a; 5 | } 6 | } -------------------------------------------------------------------------------- /stage_7/invalid/out_of_scope.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | { 3 | int a = 2; 4 | } 5 | return a; 6 | } -------------------------------------------------------------------------------- /stage_7/invalid/syntax_err_extra_brace.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if(0){ 3 | return 1; 4 | }} 5 | return 2; 6 | } -------------------------------------------------------------------------------- /stage_7/invalid/syntax_err_missing_brace.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if(0){ 3 | return 1; 4 | return 2; 5 | } -------------------------------------------------------------------------------- /stage_7/valid/consecutive_blocks.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | { 4 | int a = 2; 5 | } 6 | { 7 | return a; 8 | } 9 | } -------------------------------------------------------------------------------- /stage_7/valid/consecutive_declarations.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | { 4 | int b = 1; 5 | a = b; 6 | } 7 | { 8 | int b = 2; 9 | a = a + b; 10 | } 11 | return a; 12 | } -------------------------------------------------------------------------------- /stage_7/valid/declare_after_block.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 0; 3 | { 4 | int a = 2; 5 | } 6 | int b = 3; 7 | return b; 8 | } -------------------------------------------------------------------------------- /stage_7/valid/declare_block.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (5) { 3 | int i = 0; 4 | return i; 5 | } 6 | } -------------------------------------------------------------------------------- /stage_7/valid/declare_late.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | { 4 | a = 3; 5 | int a = 0; 6 | } 7 | return a; 8 | } -------------------------------------------------------------------------------- /stage_7/valid/multi_nesting.c: -------------------------------------------------------------------------------- 1 | int main(){ 2 | int a = 2; 3 | if (a < 3) { 4 | { 5 | int a = 3; 6 | return a; 7 | } 8 | return a; 9 | } 10 | } -------------------------------------------------------------------------------- /stage_7/valid/nested_if.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | if (a) { 4 | int b = 2; 5 | return b; 6 | } else { 7 | int c = 3; 8 | if (a < c) { 9 | return 4; 10 | } else { 11 | return 5; 12 | } 13 | } 14 | return a; 15 | } -------------------------------------------------------------------------------- /stage_7/valid/nested_scope.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 2; 3 | int b = 3; 4 | { 5 | int a = 1; 6 | b = b + a; 7 | } 8 | return b; 9 | } -------------------------------------------------------------------------------- /stage_8/invalid/break_not_in_loop.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | break; 3 | } -------------------------------------------------------------------------------- /stage_8/invalid/continue_not_in_loop.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | continue; 3 | } -------------------------------------------------------------------------------- /stage_8/invalid/out_of_scope.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | 3 | while (1) { 4 | int a = 2; 5 | } 6 | 7 | return a; 8 | } -------------------------------------------------------------------------------- /stage_8/invalid/out_of_scope_do_while.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | do { 3 | int a = 2; 4 | } while (a); 5 | return 0; 6 | } -------------------------------------------------------------------------------- /stage_8/invalid/syntax_err_do_no_semicolon.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | do 3 | 3; 4 | while (4) 5 | } -------------------------------------------------------------------------------- /stage_8/invalid/syntax_err_empty_clause.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 2; )) 3 | int a = 0; 4 | } -------------------------------------------------------------------------------- /stage_8/invalid/syntax_err_paren_mismatch.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 2; )) 3 | int a = 0; 4 | } -------------------------------------------------------------------------------- /stage_8/invalid/syntax_err_statement_in_condition.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | while(int a) { 3 | 2; 4 | } 5 | } -------------------------------------------------------------------------------- /stage_8/invalid/syntax_err_too_few_for_clauses.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 2; i < 3) 3 | 3; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /stage_8/invalid/syntax_err_too_many_for_clauses.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (;;;) 3 | 3; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /stage_8/valid/break.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int sum = 0; 3 | for (int i = 0; i < 10; i = i + 1) { 4 | sum = sum + i; 5 | if (sum > 10) 6 | break; 7 | } 8 | return sum; 9 | } -------------------------------------------------------------------------------- /stage_8/valid/continue.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int sum = 0; 3 | for (int i = 0; i < 10; i = i + 1) { 4 | if ((sum / 2) * 2 != sum) 5 | continue; 6 | sum = sum + i; 7 | } 8 | return sum; 9 | } -------------------------------------------------------------------------------- /stage_8/valid/continue_empty_post.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int sum = 0; 3 | for (int i = 0; i < 10;) { 4 | i = i + 1; 5 | if (i % 2) 6 | continue; 7 | sum = sum + i; 8 | } 9 | return sum; 10 | } -------------------------------------------------------------------------------- /stage_8/valid/do_while.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | do { 4 | a = a * 2; 5 | } while(a < 11); 6 | 7 | return a; 8 | } -------------------------------------------------------------------------------- /stage_8/valid/empty_expression.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 3; 3 | ; 4 | for (int i = 0; i < 10; i = i + 1) 5 | ; 6 | return i; 7 | } -------------------------------------------------------------------------------- /stage_8/valid/for.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | 4 | for (a = 0; a < 3; a = a + 1) 5 | a = a * 2; 6 | return a; 7 | } -------------------------------------------------------------------------------- /stage_8/valid/for_decl.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | 4 | for (int i = 0; i < 3; i = i + 1) 5 | a = a + 1; 6 | return a; 7 | } -------------------------------------------------------------------------------- /stage_8/valid/for_empty.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | for (; ; ) { 4 | a = a + 1; 5 | if (a > 3) 6 | break; 7 | } 8 | 9 | return a; 10 | } -------------------------------------------------------------------------------- /stage_8/valid/for_nested_scope.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 0; 3 | int j = 0; 4 | 5 | for (int i = 100; i > 0; i = i - 1) { 6 | int i = 0; 7 | int k = j; 8 | int j = k * 2 + i; 9 | } 10 | 11 | int k = 3; 12 | 13 | return j + k; 14 | } -------------------------------------------------------------------------------- /stage_8/valid/for_variable_shadow.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 0; 3 | int j = 0; 4 | for (i = 0; i < 10; i = i + 1) { 5 | int k = i; 6 | for (int i = k; i < 10; i = i + 1) 7 | j = j + 1; 8 | } 9 | return j + i; 10 | } -------------------------------------------------------------------------------- /stage_8/valid/nested_break.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int ans = 0; 3 | for (int i = 0; i < 10; i = i + 1) 4 | for (int j = 0; j < 10; j = j + 1) 5 | if ((i / 2)*2 == i) 6 | break; 7 | else 8 | ans = ans + i; 9 | return ans; 10 | } -------------------------------------------------------------------------------- /stage_8/valid/nested_while.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | 4 | while (a / 3 < 20) { 5 | int b = 1; 6 | while (b < 10) 7 | b = b*2; 8 | a = a + b; 9 | } 10 | 11 | return a; 12 | } -------------------------------------------------------------------------------- /stage_8/valid/return_in_while.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | while (1) { 3 | return 2; 4 | } 5 | } -------------------------------------------------------------------------------- /stage_8/valid/while_multi_statement.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | int b = 1; 4 | 5 | while (a < 5) { 6 | a = a + 2; 7 | b = b * a; 8 | } 9 | 10 | return a; 11 | } -------------------------------------------------------------------------------- /stage_8/valid/while_single_statement.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 0; 3 | 4 | while (a < 5) 5 | a = a + 2; 6 | 7 | return a; 8 | } -------------------------------------------------------------------------------- /stage_9/invalid/bad_arg.c: -------------------------------------------------------------------------------- 1 | int foo(int a){ 2 | return 3 + a; 3 | } 4 | 5 | int main(){ 6 | return foo(); 7 | } -------------------------------------------------------------------------------- /stage_9/invalid/declaration_mismatch.c: -------------------------------------------------------------------------------- 1 | int foo(int a); 2 | 3 | int main() { 4 | return 5; 5 | } 6 | 7 | int foo(int a, int b) { 8 | return 4; 9 | } -------------------------------------------------------------------------------- /stage_9/invalid/declaration_mismatch_2.c: -------------------------------------------------------------------------------- 1 | int foo(int a, int b); 2 | 3 | int main() { 4 | return 5; 5 | } 6 | 7 | int foo(int a) { 8 | return 4; 9 | } -------------------------------------------------------------------------------- /stage_9/invalid/redefine_function.c: -------------------------------------------------------------------------------- 1 | int foo(){ 2 | return 3; 3 | } 4 | 5 | int main() { 6 | return foo(); 7 | } 8 | 9 | int foo(){ 10 | return 4; 11 | } -------------------------------------------------------------------------------- /stage_9/invalid/redefine_variable.c: -------------------------------------------------------------------------------- 1 | int foo(int x) { 2 | int x = 3; 3 | } 4 | 5 | int main() { 6 | foo(1); 7 | } -------------------------------------------------------------------------------- /stage_9/invalid/too_many_args.c: -------------------------------------------------------------------------------- 1 | int foo(int a) { 2 | return a + 1; 3 | } 4 | 5 | int main() { 6 | return foo(1, 2); 7 | } -------------------------------------------------------------------------------- /stage_9/valid/expression_args.c: -------------------------------------------------------------------------------- 1 | int add(int a, int b) { 2 | return a + b; 3 | } 4 | 5 | int main() { 6 | int sum = add(1 + 2, 4); 7 | return sum + sum; 8 | } 9 | -------------------------------------------------------------------------------- /stage_9/valid/fib.c: -------------------------------------------------------------------------------- 1 | int fib(int n) { 2 | if (n == 0 || n == 1) { 3 | return n; 4 | } else { 5 | return fib(n - 1) + fib(n - 2); 6 | } 7 | } 8 | 9 | int main() { 10 | int n = 5; 11 | return fib(n); 12 | } -------------------------------------------------------------------------------- /stage_9/valid/forward_decl.c: -------------------------------------------------------------------------------- 1 | int foo(); 2 | 3 | int main() { 4 | return foo(); 5 | } 6 | 7 | int foo() { 8 | return 3; 9 | } -------------------------------------------------------------------------------- /stage_9/valid/forward_decl_args.c: -------------------------------------------------------------------------------- 1 | int foo(int a); 2 | 3 | int main(){ 4 | return foo(3); 5 | } 6 | 7 | int foo(int a){ 8 | return a + 1; 9 | } -------------------------------------------------------------------------------- /stage_9/valid/forward_decl_multi_arg.c: -------------------------------------------------------------------------------- 1 | int foo(int a, int b); 2 | 3 | int main() { 4 | return foo(1, 2); 5 | } 6 | 7 | int foo(int x, int y){ 8 | return x - y; 9 | } -------------------------------------------------------------------------------- /stage_9/valid/fun_in_expr.c: -------------------------------------------------------------------------------- 1 | int sum(int a, int b) { 2 | return a + b; 3 | } 4 | 5 | int main() { 6 | int a = sum(1, 2) - (sum(1, 2) / 2) * 2; 7 | int b = 2*sum(3, 4) + sum(1, 2); 8 | return b - a; 9 | } -------------------------------------------------------------------------------- /stage_9/valid/hello_world.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 | } -------------------------------------------------------------------------------- /stage_9/valid/later_decl.c: -------------------------------------------------------------------------------- 1 | int foo(int a) { 2 | return a + 1; 3 | } 4 | 5 | int main() { 6 | return foo(4); 7 | } 8 | 9 | int foo(int a); -------------------------------------------------------------------------------- /stage_9/valid/multi_arg.c: -------------------------------------------------------------------------------- 1 | int sub_3(int x, int y, int z) { 2 | return x - y - z; 3 | } 4 | 5 | int main() { 6 | return sub_3(10, 4, 2); 7 | } -------------------------------------------------------------------------------- /stage_9/valid/mutual_recursion.c: -------------------------------------------------------------------------------- 1 | int foo(int a); 2 | int bar(int b); 3 | 4 | int main() { 5 | return foo(5); 6 | } 7 | 8 | int foo(int a) { 9 | if (a <= 0) { 10 | return a; 11 | } 12 | 13 | return a + bar(a - 1); 14 | } 15 | 16 | int bar(int b) { 17 | if (b <= 0) { 18 | return b; 19 | } 20 | 21 | return b + bar(b / 2); 22 | } -------------------------------------------------------------------------------- /stage_9/valid/no_arg.c: -------------------------------------------------------------------------------- 1 | int three(){ 2 | return 3; 3 | } 4 | 5 | int main() { 6 | return three(); 7 | } -------------------------------------------------------------------------------- /stage_9/valid/precedence.c: -------------------------------------------------------------------------------- 1 | int three() { 2 | return 3; 3 | } 4 | 5 | int main() { 6 | return !three(); 7 | } -------------------------------------------------------------------------------- /stage_9/valid/rename_function_param.c: -------------------------------------------------------------------------------- 1 | int foo(int b); 2 | 3 | int main(){ 4 | return foo(3); 5 | } 6 | 7 | int foo(int a){ 8 | return a + 1; 9 | } -------------------------------------------------------------------------------- /stage_9/valid/single_arg.c: -------------------------------------------------------------------------------- 1 | int twice(int x){ 2 | return 2 * x; 3 | } 4 | 5 | int main() { 6 | return twice(3); 7 | } -------------------------------------------------------------------------------- /stage_9/valid/variable_as_arg.c: -------------------------------------------------------------------------------- 1 | int foo(int x) { 2 | return x + 1; 3 | } 4 | 5 | int main() { 6 | int a = 1; 7 | return foo(a); 8 | } 9 | -------------------------------------------------------------------------------- /test_compiler.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | padding_dots=$(printf '%0.1s' "."{1..60}) 4 | padlength=50 5 | cmp=$1 6 | success_total=0 7 | failure_total=0 8 | 9 | print_test_name () { 10 | test_name=$1 11 | printf '%s' "$test_name" 12 | printf '%*.*s' 0 $((padlength - ${#test_name})) "$padding_dots" 13 | } 14 | 15 | test_success () { 16 | echo "OK" 17 | ((success++)) 18 | } 19 | 20 | test_failure () { 21 | echo "FAIL" 22 | ((fail++)) 23 | } 24 | 25 | test_not_implemented () { 26 | echo "NOT IMPLEMENTED" 27 | } 28 | 29 | run_our_program () { 30 | actual_out=`./$1 2>/dev/null` 31 | actual_exit_code=$? 32 | rm $1 2>/dev/null 33 | } 34 | 35 | run_correct_program () { 36 | expected_out=`./a.out` 37 | expected_exit_code=$? 38 | rm a.out 39 | } 40 | 41 | compare_program_results () { 42 | # make sure exit code is correct 43 | if [ "$expected_exit_code" -ne "$actual_exit_code" ] || [ "$expected_out" != "$actual_out" ] 44 | then 45 | test_failure 46 | else 47 | test_success 48 | fi 49 | } 50 | 51 | test_stage () { 52 | success=0 53 | fail=0 54 | echo "====================================================" 55 | echo "STAGE $1" 56 | echo "===================Valid Programs===================" 57 | for prog in `find . -type f -name "*.c" -path "./stage_$1/valid/*" -not -path "*/valid_multifile/*" 2>/dev/null`; do 58 | 59 | gcc -w $prog 60 | run_correct_program 61 | 62 | base="${prog%.*}" #name of executable (filename w/out extension) 63 | test_name="${base##*valid/}" 64 | 65 | print_test_name $test_name 66 | $cmp $prog 2>/dev/null 67 | status=$? 68 | 69 | if [[ $test_name == "skip_on_failure"* ]]; then 70 | # this may depend on features we haven't implemented yet 71 | # if compilation succeeds, make sure it gives the right result 72 | # otherwise don't count it as success or failure 73 | if [[ -f $base ]] && [[ $status -eq 0 ]]; then 74 | # it succeeded, so run it and make sure it gives the right result 75 | run_our_program $base 76 | compare_program_results 77 | else 78 | test_not_implemented 79 | fi 80 | else 81 | run_our_program $base 82 | compare_program_results 83 | fi 84 | done 85 | # programs with multiple source files 86 | for dir in `ls -d stage_$1/valid_multifile/* 2>/dev/null` ; do 87 | gcc -w $dir/* 88 | 89 | run_correct_program 90 | 91 | base="${dir%.*}" #name of executable (directory w/out extension) 92 | test_name="${base##*valid_multifile/}" 93 | 94 | # need to explicitly specify output name 95 | $cmp -o "$test_name" $dir/* >/dev/null 96 | 97 | print_test_name $test_name 98 | 99 | # check output/exit codes 100 | run_our_program $test_name 101 | compare_program_results 102 | 103 | done 104 | echo "===================Invalid Programs=================" 105 | for prog in `ls stage_$1/invalid/{,**/}*.c 2>/dev/null`; do 106 | 107 | base="${prog%.*}" #name of executable (filename w/out extension) 108 | test_name="${base##*invalid/}" 109 | 110 | $cmp $prog >/dev/null 2>&1 111 | status=$? #failed, as we expect, if exit code != 0 112 | print_test_name $test_name 113 | 114 | # make sure neither executable nor assembly was produced 115 | # and exit code is non-zero 116 | if [[ -f $base || -f $base".s" ]] 117 | then 118 | test_failure 119 | rm $base 2>/dev/null 120 | rm $base".s" 2>/dev/null 121 | else 122 | test_success 123 | fi 124 | done 125 | echo "===================Stage $1 Summary=================" 126 | printf "%d successes, %d failures\n" $success $fail 127 | ((success_total=success_total+success)) 128 | ((failure_total=failure_total + fail)) 129 | } 130 | 131 | total_summary () { 132 | echo "===================TOTAL SUMMARY====================" 133 | printf "%d successes, %d failures\n" $success_total $failure_total 134 | } 135 | 136 | if [ "$1" == "" ]; then 137 | echo "USAGE: ./test_compiler.sh /path/to/compiler [stages(optional)]" 138 | echo "EXAMPLE(test specific stages): ./test_compiler.sh ./mycompiler 1 2 4" 139 | echo "EXAMPLE(test all): ./test_compiler.sh ./mycompiler" 140 | exit 1 141 | fi 142 | 143 | if test 1 -lt $#; then 144 | testcases=("$@") # [1..-1] is testcases 145 | for i in `seq 2 $#`; do 146 | test_stage ${testcases[$i-1]} 147 | done 148 | total_summary 149 | exit 0 150 | fi 151 | 152 | num_stages=10 153 | 154 | for i in `seq 1 $num_stages`; do 155 | test_stage $i 156 | done 157 | 158 | total_summary 159 | --------------------------------------------------------------------------------