├── .github └── workflows │ ├── examples.yml │ ├── main.yml │ └── metrics.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── analysis ├── analyze-dynamic-var-results.py ├── analyze-file-char-distribution.py ├── measure-file-size.sh └── requirements.txt ├── arm.c ├── artifact.md ├── attic ├── cc.sh ├── codegen-test.c ├── readfile.sh ├── six-cc │ ├── Makefile │ ├── six-cc-tests │ │ ├── ack.c │ │ ├── ack.golden │ │ ├── ack.sh │ │ ├── argc.c │ │ ├── argc.golden │ │ ├── argc.sh │ │ ├── arith-indirect.c │ │ ├── arith-indirect.golden │ │ ├── arith-indirect.sh │ │ ├── arith.c │ │ ├── arith.golden │ │ ├── arith.sh │ │ ├── close.c │ │ ├── close.golden │ │ ├── close.sh │ │ ├── conditions.c │ │ ├── conditions.golden │ │ ├── conditions.sh │ │ ├── empty.c │ │ ├── empty.golden │ │ ├── empty.sh │ │ ├── empty.txt │ │ ├── enums.c │ │ ├── enums.golden │ │ ├── enums.sh │ │ ├── even-odd.c │ │ ├── even-odd.golden │ │ ├── even-odd.sh │ │ ├── fgetc.c │ │ ├── fgetc.golden │ │ ├── fgetc.sh │ │ ├── fib.c │ │ ├── fib.golden │ │ ├── fib.sh │ │ ├── fopen-empty.c │ │ ├── fopen-empty.golden │ │ ├── fopen-empty.sh │ │ ├── fopen-many.c │ │ ├── fopen-many.golden │ │ ├── fopen-many.sh │ │ ├── fopen-trailing.c │ │ ├── fopen-trailing.golden │ │ ├── fopen-trailing.sh │ │ ├── getchar-interlaced.c │ │ ├── getchar-interlaced.golden │ │ ├── getchar-interlaced.sh │ │ ├── getchar.c │ │ ├── getchar.golden │ │ ├── getchar.sh │ │ ├── if.c │ │ ├── if.golden │ │ ├── if.sh │ │ ├── increment.c │ │ ├── increment.golden │ │ ├── increment.sh │ │ ├── init.c │ │ ├── init.golden │ │ ├── init.sh │ │ ├── initialization.c │ │ ├── initialization.golden │ │ ├── initialization.sh │ │ ├── memset.c │ │ ├── memset.golden │ │ ├── memset.sh │ │ ├── nested-calls.c │ │ ├── nested-calls.golden │ │ ├── nested-calls.sh │ │ ├── no-trailing.txt │ │ ├── print.c │ │ ├── print.golden │ │ ├── print.sh │ │ ├── return.c │ │ ├── return.golden │ │ ├── return.sh │ │ ├── short-circuit.c │ │ ├── short-circuit.golden │ │ ├── short-circuit.sh │ │ ├── string.c │ │ ├── string.golden │ │ ├── string.sh │ │ ├── strlen.c │ │ ├── strlen.golden │ │ ├── strlen.sh │ │ ├── struct-enum.c │ │ ├── struct-enum.golden │ │ ├── struct-enum.sh │ │ ├── struct.c │ │ ├── struct.golden │ │ ├── struct.sh │ │ ├── switch.c │ │ ├── switch.golden │ │ ├── switch.sh │ │ ├── test.c │ │ ├── test.golden │ │ ├── test.sh │ │ ├── test2.c │ │ ├── test2.golden │ │ ├── test2.sh │ │ ├── while-continue.c │ │ ├── while-continue.golden │ │ ├── while-continue.sh │ │ ├── while-fun-call.c │ │ ├── while-fun-call.golden │ │ ├── while-fun-call.sh │ │ ├── winter-pi2.c │ │ ├── winter-pi2.golden │ │ └── winter-pi2.sh │ ├── six-cc.scm │ └── test-six-cc-all-options.py └── tokenizer-with-switch.c ├── benchmark-bootstrap-with-options.sh ├── benchmark-bootstrap.sh ├── benchmarks ├── compile-times │ └── run.sh ├── example-execution-times │ └── run.sh ├── long-lines │ ├── cat.c │ ├── long-line-1000.txt │ ├── long-line-10000.txt │ ├── long-line-2000.txt │ ├── long-line-20000.txt │ ├── long-line-4000.txt │ ├── long-line-5000.txt │ ├── long-line-50000.txt │ ├── long-line-6000.txt │ ├── long-line-8000.txt │ └── run.sh └── memory-size-slowdown │ ├── memory-size-slowdown.c │ └── run.sh ├── bootstrap-pnut-exe.sh ├── bootstrap-pnut-sh-by-pnut-exe.sh ├── bootstrap-pnut-sh.sh ├── debug.c ├── diff-pnut-sh.sh ├── doc ├── paper-SLE24.pdf └── presentation-SLE24.pdf ├── elf.c ├── env.c ├── examples ├── all-chars.c ├── base64.c ├── c4-libs │ ├── fcntl.h │ ├── memory.h │ ├── stdio.h │ ├── stdlib.h │ └── unistd.h ├── c4.c ├── cat.c ├── compiled │ ├── all-chars.sh │ ├── base64.sh │ ├── c4.sh │ ├── cat.sh │ ├── cp.sh │ ├── echo.sh │ ├── empty.sh │ ├── fib.sh │ ├── hello.sh │ ├── non_zero.sh │ ├── print-reverse.sh │ ├── repl.sh │ ├── reverse.sh │ ├── select-file.sh │ ├── sha256sum.sh │ ├── sum-array.sh │ ├── wc-stdin.sh │ ├── wc.sh │ ├── welcome.sh │ └── winterpi.sh ├── cp.c ├── echo.c ├── empty.c ├── fib.c ├── hello.c ├── non_zero.c ├── posix-utils.sh ├── prepare.sh ├── print-reverse.c ├── repl.c ├── reverse.c ├── select-file.c ├── sha256sum.c ├── sum-array.c ├── wc-stdin.c ├── wc.c ├── welcome.c └── winterpi.c ├── exe.c ├── mach-o.c ├── make-artifact.sh ├── make-sh-runtime.c ├── pnut-lib.c ├── pnut.c ├── portable_libc ├── include │ ├── crt1.h │ ├── crti.h │ ├── ctype.h │ ├── math.h │ ├── setjmp.h │ ├── signal.h │ ├── stdarg.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ ├── sys │ │ ├── time.h │ │ └── types.h │ └── unistd.h ├── makefile ├── portable_libc.c ├── src │ ├── crt1.c │ ├── crti.c │ ├── ctype.c │ ├── math.c │ ├── setjmp.c │ ├── signal.c │ ├── stdio.c │ ├── stdlib.c │ ├── string.c │ ├── time.c │ └── unistd.c └── test.c ├── run-pnut-variant.sh ├── run-tests.sh ├── sh-runtime.c ├── sh.c ├── shell-benchmarks ├── assignment-in-arith.sh ├── bench-cat.sh ├── bench-puts.c ├── bench-puts.sh ├── cat-default.sh ├── cat.sh ├── char-to-int-conversion │ ├── case.sh │ ├── lookup_table.sh │ ├── run.sh │ └── subshell.sh ├── dynamic-variables-code.sh ├── dynamic-variables.sh ├── echo.sh ├── get_char.sh ├── get_char_code_fast.sh ├── get_char_code_slow.sh ├── get_char_data.txt ├── long-line-1000.txt ├── long-line-10000.txt ├── long-line-4000.txt ├── long-line-5000.txt ├── long-line-50000.txt ├── num-comparison.sh ├── run-bench-puts.sh ├── string-concat-quoting.sh ├── string-concat.sh ├── string-length.sh ├── string-pack-unpack-benchmark-code.sh ├── string-pack-unpack-benchmark.sh ├── variable-assignment.sh └── variable_name_length.sh ├── shell-playground ├── adding_new_$_variables.sh ├── arity.sh ├── is_defined.sh ├── local_var_as_param.sh ├── multi-expression-posix.sh ├── multi-expression.sh ├── print_return.sh └── while_fun_call.sh ├── test-tokenizer.sh ├── tests ├── _all │ ├── comma.c │ ├── comma.golden │ ├── compound.c │ ├── compound.golden │ ├── do_while.c │ ├── do_while.golden │ ├── enum-tests │ │ ├── enum-suite.c │ │ └── enum-suite.golden │ ├── examples │ │ ├── sha256sum.c │ │ └── sha256sum.golden │ ├── for-empty.c │ ├── for-empty.golden │ ├── free-malloc-tests │ │ ├── malloc-free-simple-suite.c │ │ └── malloc-free-simple-suite.golden │ ├── globals.c │ ├── globals.golden │ ├── inline.c │ ├── inline.golden │ ├── input-output │ │ ├── emit-all-chars.c │ │ ├── emit-all-chars.golden │ │ ├── file-with-newlines.txt │ │ ├── read-newlines.c │ │ ├── read-newlines.golden │ │ ├── read-unicode.c │ │ ├── read-unicode.golden │ │ └── unicode.txt │ ├── line_continuation.c │ ├── line_continuation.golden │ ├── logical-negation.c │ ├── logical-negation.golden │ ├── preprocessor │ │ ├── if │ │ │ ├── if.c │ │ │ ├── if.golden │ │ │ ├── ifdef.c │ │ │ └── ifdef.golden │ │ ├── include │ │ │ ├── include-bracket.c │ │ │ ├── include-bracket.golden │ │ │ ├── include-no-newline.c │ │ │ ├── include-no-newline.golden │ │ │ ├── include-no-newline.h │ │ │ ├── include.c │ │ │ ├── include.golden │ │ │ ├── include1.h │ │ │ ├── include2.h │ │ │ ├── include3.h │ │ │ ├── include4.h │ │ │ ├── include5.h │ │ │ ├── include6.h │ │ │ ├── multiple-include.c │ │ │ ├── multiple-include.golden │ │ │ ├── multiple-include.h │ │ │ ├── relative-include.c │ │ │ ├── relative-include.golden │ │ │ └── relative │ │ │ │ ├── include1.h │ │ │ │ ├── include2.h │ │ │ │ ├── include4.h │ │ │ │ └── nested │ │ │ │ └── include3.h │ │ └── macro │ │ │ ├── builtin-stubbed.c │ │ │ ├── builtin-stubbed.golden │ │ │ ├── builtin.c │ │ │ ├── builtin.golden │ │ │ ├── fun-like.c │ │ │ ├── fun-like.golden │ │ │ ├── object-like.c │ │ │ ├── object-like.golden │ │ │ ├── recursion-limit-error.c │ │ │ ├── recursion-limit-error.golden │ │ │ ├── recursion-limit.c │ │ │ ├── recursion-limit.golden │ │ │ ├── self-reference.c │ │ │ ├── self-reference.golden │ │ │ ├── stringification.c │ │ │ ├── stringification.golden │ │ │ ├── token-pasting.c │ │ │ └── token-pasting.golden │ ├── six-cc-tests │ │ ├── ack.c │ │ ├── ack.golden │ │ ├── argc.c │ │ ├── argc.golden │ │ ├── arith-indirect.c │ │ ├── arith-indirect.golden │ │ ├── arith.c │ │ ├── arith.golden │ │ ├── conditions.c │ │ ├── conditions.golden │ │ ├── empty.c │ │ ├── empty.golden │ │ ├── empty.txt │ │ ├── enums.c │ │ ├── enums.golden │ │ ├── even-odd.c │ │ ├── even-odd.golden │ │ ├── fgetc.c │ │ ├── fgetc.golden │ │ ├── fib.c │ │ ├── fib.golden │ │ ├── fopen-empty.c │ │ ├── fopen-empty.golden │ │ ├── fopen-many.c │ │ ├── fopen-many.golden │ │ ├── fopen-trailing.c │ │ ├── fopen-trailing.golden │ │ ├── getchar-interlaced.c-deactivated │ │ ├── getchar-interlaced.golden │ │ ├── getchar.c-deactivated │ │ ├── getchar.golden │ │ ├── if.c │ │ ├── if.golden │ │ ├── increment.c │ │ ├── increment.golden │ │ ├── init.c │ │ ├── init.golden │ │ ├── initialization.c │ │ ├── initialization.golden │ │ ├── no-trailing.txt │ │ ├── print.c-deactivated │ │ ├── print.golden │ │ ├── return.c-deactivated │ │ ├── return.golden │ │ ├── short-circuit.c │ │ ├── short-circuit.golden │ │ ├── string.c │ │ ├── string.golden │ │ ├── strlen.c │ │ ├── strlen.golden │ │ ├── struct-enum.c │ │ ├── struct-enum.golden │ │ ├── struct.c │ │ ├── struct.golden │ │ ├── switch.c │ │ ├── switch.golden │ │ ├── test.c │ │ ├── test.golden │ │ ├── test2.c │ │ ├── test2.golden │ │ ├── while-continue.c │ │ ├── while-continue.golden │ │ ├── while-fun-call.c │ │ ├── while-fun-call.golden │ │ ├── winter-pi2.c │ │ └── winter-pi2.golden │ ├── strings-with-nul.c │ ├── strings-with-nul.golden │ ├── switch.c │ ├── switch.golden │ ├── switch_double_break.c │ ├── switch_double_break.golden │ ├── switch_if.c │ ├── switch_if.golden │ ├── tcc-expansion.c │ ├── tcc-expansion.golden │ ├── variable-declaration-tests │ │ ├── global-simple.c │ │ ├── global-simple.golden │ │ ├── local-global-interaction-simple.c │ │ ├── local-global-interaction-simple.golden │ │ ├── local-simple.c │ │ ├── local-simple.golden │ │ ├── shadowing-globals.c │ │ └── shadowing-globals.golden │ ├── void_cast.c │ ├── void_cast.golden │ ├── void_functions.c │ └── void_functions.golden ├── _bug │ ├── negative-zero.c │ ├── negative-zero.golden │ ├── self-reference-macro-with-macro-args.c │ └── self-reference-macro-with-macro-args.golden ├── _exe │ ├── anonymous-struct.c │ ├── anonymous-struct.golden │ ├── array-function-param.c │ ├── array-function-param.golden │ ├── fixed-width │ │ ├── literals.c │ │ └── literals.golden │ ├── goto.c │ ├── goto.golden │ ├── indirect-calls.c │ ├── indirect-calls.golden │ ├── initializers-global.c │ ├── initializers-global.golden │ ├── initializers-local.c │ ├── initializers-local.golden │ ├── input-output │ │ ├── all-chars.txt │ │ ├── printf.c │ │ ├── printf.golden │ │ ├── read-all-chars.c │ │ └── read-all-chars.golden │ ├── pointer-comparisons.c │ ├── pointer-comparisons.golden │ ├── record-of-functions.c │ ├── record-of-functions.golden │ ├── sizeof.c │ ├── sizeof.golden │ ├── static_vars.c │ ├── static_vars.golden │ ├── struct-flexible-array.c │ ├── struct-flexible-array.golden │ ├── struct.c │ ├── struct.golden │ ├── switch.c │ ├── switch.golden │ ├── tagged-union.c │ ├── tagged-union.golden │ ├── typedef.c │ └── typedef.golden └── _sh │ ├── checks │ ├── address_of_global.c │ ├── address_of_global.golden │ ├── address_of_local.c │ ├── address_of_local.golden │ ├── break_outside_loop.c │ ├── break_outside_loop.golden │ ├── continue_outside_loop.c │ ├── continue_outside_loop.golden │ ├── extern_vars.c │ ├── extern_vars.golden │ ├── global_var_underscore.c │ ├── global_var_underscore.golden │ ├── initializer_nested.c │ ├── initializer_nested.golden │ ├── initializer_too_large.c │ ├── initializer_too_large.golden │ ├── initializer_too_large_str.c │ ├── initializer_too_large_str.golden │ ├── invalid_printf.c │ ├── invalid_printf.golden │ ├── local_array_arg.c │ ├── local_array_arg.golden │ ├── local_array_param.c │ ├── local_array_param.golden │ ├── local_struct_arg.c │ ├── local_struct_arg.golden │ ├── local_struct_param.c │ ├── local_struct_param.golden │ ├── local_var_shadowing.c │ ├── local_var_shadowing.golden │ ├── local_var_underscore.c │ ├── local_var_underscore.golden │ ├── shortcut_eval_outside_condition.c │ ├── shortcut_eval_outside_condition.golden │ ├── sizeof_array.c │ ├── sizeof_array.golden │ ├── sizeof_expr.c │ ├── sizeof_expr.golden │ ├── static_vars.c │ ├── static_vars.golden │ ├── struct_no_nested_array.c │ ├── struct_no_nested_array.golden │ ├── struct_no_nested_struct.c │ ├── struct_no_nested_struct.golden │ ├── switch_early_exit.c │ ├── switch_early_exit.golden │ ├── switch_fallthrough.c │ ├── switch_fallthrough.golden │ ├── switch_no_body.c │ ├── switch_no_body.golden │ ├── ternary_with_fun_call.c │ ├── ternary_with_fun_call.golden │ ├── var_IFS.c │ └── var_IFS.golden │ ├── goto.c │ ├── goto.golden │ ├── initializer.c │ ├── initializer.golden │ ├── input-output │ ├── all-chars.txt │ ├── printf.c │ ├── printf.golden │ ├── printf_runtime.c │ ├── printf_runtime.golden │ ├── read-all-chars.c │ └── read-all-chars.golden │ ├── nested_loops.c │ ├── nested_loops.golden │ ├── scoping.c │ ├── scoping.golden │ ├── struct.c │ ├── struct.golden │ ├── switch.c │ └── switch.golden ├── utils ├── keywords.txt └── perfect-hash.scm ├── woody.sh └── x86.c /.github/workflows/examples.yml: -------------------------------------------------------------------------------- 1 | name: examples-up-to-date 2 | 3 | on: 4 | pull_request: # Should trigger on pull requests for all branches 5 | branches: 6 | - '**' # Matches all branches 7 | 8 | jobs: 9 | regenerate-examples: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | 15 | - name: Regenerate examples 16 | run: | 17 | sh ./examples/prepare.sh 18 | if [ $? -ne 0 ]; then 19 | echo "Failed to regenerate examples" 20 | exit 1 21 | fi 22 | 23 | - name: Diff examples 24 | run: | 25 | git add examples/ 26 | files=$(git diff HEAD --name-only) 27 | if [ -n "$files" ]; then 28 | echo "Examples are out of date. Please run ./examples/prepare.sh" 29 | echo "The following files are out of date:" 30 | echo "$files" 31 | exit 1 32 | fi 33 | -------------------------------------------------------------------------------- /.github/workflows/metrics.yml: -------------------------------------------------------------------------------- 1 | name: metrics 2 | 3 | on: 4 | pull_request: # Should trigger on pull requests for all branches 5 | branches: 6 | - '**' # Matches all branches 7 | 8 | jobs: 9 | measure-file-size: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | 15 | - name: Install gcc and clang 16 | run: | 17 | set -e 18 | sudo apt-get update 19 | sudo apt-get install -y build-essential bc 20 | 21 | - name: Measure file size 22 | run: | 23 | sh analysis/measure-file-size.sh 24 | if [ $? -ne 0 ]; then 25 | echo "Failed to measure file size" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X Finder artifacts 2 | .DS_Store 3 | */.DS_Store 4 | # Tests artifacts 5 | tests/*.sh 6 | tests/**/*.exe 7 | tests/**/*.err 8 | tests/**/*.output 9 | # Build artifacts 10 | build/* 11 | artifact/* 12 | artifact.zip 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024, Marc Feeley 2 | Copyright (c) 2024, Laurent Huberdeau 3 | Copyright (c) 2024, Cassandre Hamel 4 | Copyright (c) 2024, Stefan Monnier 5 | 6 | Redistribution and use in source and binary forms, with or without modification, 7 | are permitted provided that the following conditions are met: 8 | 9 | Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 23 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /analysis/requirements.txt: -------------------------------------------------------------------------------- 1 | matplotlib -------------------------------------------------------------------------------- /arm.c: -------------------------------------------------------------------------------- 1 | // arm codegen 2 | 3 | // TODO! 4 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/ack.c: -------------------------------------------------------------------------------- 1 | int ack(int m, int n) 2 | { 3 | int a; /* Local variable so that the function is not simple */ 4 | if (m == 0) return n + 1; 5 | if(m > 0 && n == 0) return ack(m - 1, 1); 6 | return ack(m - 1, ack(m, n - 1)); 7 | } 8 | 9 | int main() { 10 | int m = 3; 11 | int n = 3; 12 | printf("ack(%d, %d) = %d", m, n, ack(m, n)); 13 | } 14 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/ack.golden: -------------------------------------------------------------------------------- 1 | ack(3, 3) = 61 -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/argc.c: -------------------------------------------------------------------------------- 1 | /* args: abc def hij */ 2 | int main(int argc, char_ptr args) { 3 | int i = 0; 4 | printf("Number of arguments: %d\n", argc); 5 | printf("Arguments:\n"); 6 | while (i < argc) { 7 | printf("argv[%d] = %s\n", i, args[i]); 8 | i++; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/argc.golden: -------------------------------------------------------------------------------- 1 | Number of arguments: 4 2 | Arguments: 3 | argv[0] = six-cc-tests/argc.sh 4 | argv[1] = abc 5 | argv[2] = def 6 | argv[3] = hij 7 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/arith-indirect.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int_ptr arr; 3 | int acc; 4 | int i; 5 | 6 | arr = malloc(100); 7 | 8 | for(i = 0; i < 100; i++) { 9 | arr[i] = i; 10 | } 11 | 12 | acc = 0; 13 | for(i = 0; i < 100; i++) { 14 | acc += arr[i] * 13; 15 | } 16 | printf("acc: %d\n", acc); 17 | 18 | acc = 0; 19 | for(i = 0; i < 100; i++) { 20 | acc += (*(arr + i)) * 13; 21 | } 22 | printf("acc: %d\n", acc); 23 | } 24 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/arith-indirect.golden: -------------------------------------------------------------------------------- 1 | acc: 64350 2 | acc: 64350 3 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/arith.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int x; 3 | int y; 4 | int z; 5 | 6 | x = 42; 7 | y = 128; 8 | 9 | z = ++x; 10 | printf("x: %d, y: %d, z: %d\n", x, y, z); 11 | z = --x; 12 | printf("x: %d, y: %d, z: %d\n", x, y, z); 13 | z = x++; 14 | printf("x: %d, y: %d, z: %d\n", x, y, z); 15 | z = x--; 16 | printf("x: %d, y: %d, z: %d\n", x, y, z); 17 | z = x += y; 18 | printf("x: %d, y: %d, z: %d\n", x, y, z); 19 | z = x -= y; 20 | printf("x: %d, y: %d, z: %d\n", x, y, z); 21 | z = x *= y; 22 | printf("x: %d, y: %d, z: %d\n", x, y, z); 23 | z = x /= y; 24 | printf("x: %d, y: %d, z: %d\n", x, y, z); 25 | z = x %= y; 26 | printf("x: %d, y: %d, z: %d\n", x, y, z); 27 | z = x &= y; 28 | printf("x: %d, y: %d, z: %d\n", x, y, z); 29 | z = x |= y; 30 | printf("x: %d, y: %d, z: %d\n", x, y, z); 31 | z = x ^= y; 32 | printf("x: %d, y: %d, z: %d\n", x, y, z); 33 | z = x <<= y; 34 | printf("x: %d, y: %d, z: %d\n", x, y, z); 35 | z = x >>= y; 36 | printf("x: %d, y: %d, z: %d\n", x, y, z); 37 | z = ~z; 38 | printf("x: %d, y: %d, z: %d\n", x, y, z); 39 | z = +z; 40 | printf("x: %d, y: %d, z: %d\n", x, y, z); 41 | z = 1 ? x : y; 42 | printf("x: %d, y: %d, z: %d\n", x, y, z); 43 | z = 0 ? x : y; 44 | printf("x: %d, y: %d, z: %d\n", x, y, z); 45 | } 46 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/arith.golden: -------------------------------------------------------------------------------- 1 | x: 43, y: 128, z: 43 2 | x: 42, y: 128, z: 42 3 | x: 43, y: 128, z: 42 4 | x: 42, y: 128, z: 43 5 | x: 170, y: 128, z: 170 6 | x: 42, y: 128, z: 42 7 | x: 5376, y: 128, z: 5376 8 | x: 42, y: 128, z: 42 9 | x: 42, y: 128, z: 42 10 | x: 0, y: 128, z: 0 11 | x: 128, y: 128, z: 128 12 | x: 0, y: 128, z: 0 13 | x: 0, y: 128, z: 0 14 | x: 0, y: 128, z: 0 15 | x: 0, y: 128, z: -1 16 | x: 0, y: 128, z: -1 17 | x: 0, y: 128, z: 0 18 | x: 0, y: 128, z: 128 19 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/close.c: -------------------------------------------------------------------------------- 1 | int hash(char_ptr s) { 2 | int hash; 3 | int ix; 4 | hash = 0; 5 | ix = 0; 6 | while (s[ix] != 0) { 7 | hash = s[ix] + (hash << 6) + (hash << 16) - hash; 8 | hash = hash & 65535; /* Most shells have 32-bit integers, so we have to make sure we don't "overflow" */ 9 | ix++; 10 | } 11 | return ix; 12 | } 13 | 14 | int main() { 15 | int MAX_SIZE; 16 | int_ptr f; 17 | char_ptr s; 18 | int len; 19 | int h; 20 | MAX_SIZE = 200; 21 | s = malloc(MAX_SIZE); 22 | f = open("six-cc-tests/close.c", 0); 23 | len = read(f, s, MAX_SIZE - 1); 24 | s[len] = 0; 25 | close(f); 26 | printf("Read content: %s\n", s); 27 | printf("File descriptor: %s\n", f); 28 | printf("Quote: \"\n", len); 29 | printf("Backslash: \\\n", len); 30 | printf("Read len: %d\n", len); 31 | printf("Read result: %.*s\n", len, s); 32 | printf("hash: %d\n", hash(s)); 33 | } 34 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/close.golden: -------------------------------------------------------------------------------- 1 | Read content: int hash(char_ptr s) { 2 | int hash; 3 | int ix; 4 | hash = 0; 5 | ix = 0; 6 | while (s[ix] != 0) { 7 | hash = s[ix] + (hash << 6) + (hash << 16) - hash; 8 | hash = hash & 65535; /* Most shells have 32-bit int 9 | File descriptor: six-cc-tests/close.c 10 | Quote: " 11 | Backslash: \ 12 | Read len: 199 13 | Read result: int hash(char_ptr s) { 14 | int hash; 15 | int ix; 16 | hash = 0; 17 | ix = 0; 18 | while (s[ix] != 0) { 19 | hash = s[ix] + (hash << 6) + (hash << 16) - hash; 20 | hash = hash & 65535; /* Most shells have 32-bit int 21 | hash: 199 22 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/conditions.c: -------------------------------------------------------------------------------- 1 | void main() { 2 | int i = 0; 3 | int j = 5; 4 | int k = 12; 5 | char_ptr p = "_hello"; 6 | 7 | if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '_') 8 | { 9 | printf("p: %c\n", *p); 10 | } 11 | if ((*p >= 'a' || *p <= 'z') && (*p >= 'A' || *p <= 'Z') && !(*p >= '0' || *p <= '9') && *p == '_') 12 | { 13 | printf("p: %c\n", *p); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/conditions.golden: -------------------------------------------------------------------------------- 1 | p: _ 2 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/empty.c: -------------------------------------------------------------------------------- 1 | void test() { 2 | while(1) 3 | return 1; 4 | } 5 | 6 | int main() { 7 | int x = 1; 8 | test(); 9 | while(0); 10 | 11 | for(; x == 0; x = 1); 12 | 13 | if (0); 14 | } 15 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/attic/six-cc/six-cc-tests/empty.golden -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/attic/six-cc/six-cc-tests/empty.txt -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/enums.c: -------------------------------------------------------------------------------- 1 | /* Test that enum variables can be shadowed by local bindings */ 2 | enum ChildEnum() { VAL; NEXT; LL_SIZE; } 3 | 4 | enum ParentEnum() { VAL; NEXT; LL_SIZE; VAL2; NEXT2; LL_SIZE2; } 5 | 6 | struct TestStruct() { 7 | int VAL; 8 | int NEXT; 9 | int LL_SIZE; 10 | } 11 | 12 | void shadow(int NEXT) { 13 | int VAL; 14 | VAL = 123; 15 | NEXT = 456; 16 | printf("VAL: %d, NEXT: %d\n", VAL, NEXT); 17 | } 18 | 19 | int main() { 20 | printf("VAL: %d, NEXT: %d\n", VAL, NEXT); 21 | shadow(789); 22 | printf("VAL: %d, NEXT: %d\n", VAL, NEXT); 23 | } 24 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/enums.golden: -------------------------------------------------------------------------------- 1 | VAL: 0, NEXT: 1 2 | VAL: 123, NEXT: 456 3 | VAL: 0, NEXT: 1 4 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/even-odd.c: -------------------------------------------------------------------------------- 1 | int abs(int number) 2 | { 3 | if(number < 0) return -number; 4 | return number; 5 | } 6 | 7 | int even(int number) 8 | { 9 | int a; /* Local variable so that the function is not simple */ 10 | if(number == 0) return 1; 11 | return odd(abs(number)-1); 12 | } 13 | 14 | int odd(int number) 15 | { 16 | int a; /* Local variable so that the function is not simple */ 17 | if( number == 0 ) return 0; 18 | return even(abs(number)-1); 19 | } 20 | 21 | int main() { 22 | int n1; 23 | int n2; 24 | n1 = even(10); 25 | n2 = odd(10); 26 | printf("n1 = %d\n", n1); 27 | printf("n2 = %d\n", n2); 28 | } 29 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/even-odd.golden: -------------------------------------------------------------------------------- 1 | n1 = 1 2 | n2 = 0 3 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fgetc.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | FILE_ptr f; 3 | char c; 4 | f = fopen("six-cc-tests/fgetc.c", 0); 5 | while ((c = fgetc(f)) != EOF) { 6 | putchar(c); 7 | } 8 | fclose(f); 9 | } 10 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fgetc.golden: -------------------------------------------------------------------------------- 1 | int main() { 2 | FILE_ptr f; 3 | char c; 4 | f = fopen("six-cc-tests/fgetc.c", 0); 5 | while ((c = fgetc(f)) != EOF) { 6 | putchar(c); 7 | } 8 | fclose(f); 9 | } 10 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fib.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int n123; 3 | n123 = fib(15); 4 | printf("%d\n", n123); 5 | } 6 | 7 | int fib(int n) { 8 | int n2; 9 | int n3; 10 | if (n <= 1) { 11 | return n; 12 | } 13 | 14 | n2 = fib(n - 1); 15 | n3 = fib(n - 2); 16 | n2 = n2 + n3; 17 | return n2; 18 | } 19 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fib.golden: -------------------------------------------------------------------------------- 1 | 610 2 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fopen-empty.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | FILE_ptr f; 3 | char c; 4 | f = fopen("six-cc-tests/empty.txt", "r"); 5 | while ((c = fgetc(f)) != EOF) { 6 | putchar(c); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fopen-empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/attic/six-cc/six-cc-tests/fopen-empty.golden -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fopen-many.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | FILE_ptr f; 3 | char c; 4 | int i = 0; 5 | for (i = 0; i < 100; i++) { 6 | f = fopen("six-cc-tests/fgetc.c", "r"); 7 | while ((c = fgetc(f)) != EOF) { 8 | putchar(c); 9 | } 10 | fclose(f); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fopen-trailing.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | FILE_ptr f; 3 | char c; 4 | f = fopen("six-cc-tests/no-trailing.txt", "r"); 5 | while ((c = fgetc(f)) != EOF) { 6 | putchar(c); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/fopen-trailing.golden: -------------------------------------------------------------------------------- 1 | abcdefghijklmnopqrstuvwxyz -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/getchar-interlaced.c: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | /* Compare stdin with file, output matching prefix */ 3 | int main() { 4 | char c1; 5 | char c2; 6 | FILE_ptr f; 7 | f = fopen("six-cc-tests/getchar-interlaced.c", 0); 8 | while ((c1 = getchar()) && (c2 = fgetc(f)) && c1 == c2 && c1 != EOF) { 9 | putchar(c1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/getchar-interlaced.golden: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | /* Compare stdin with file, output matching prefix */ 3 | int main() { 4 | char c1; 5 | char c2; 6 | FILE_ptr f; 7 | f = fopen("six-cc-tests/getchar-interlaced.c", 0); 8 | while ((c1 = getchar()) && (c2 = fgetc(f)) && c1 == c2 && c1 != EOF) { 9 | putchar(c1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/getchar.c: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | int main() { 3 | char c; 4 | while ((c = getchar()) != EOF) { 5 | putchar(c); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/getchar.golden: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | /* Compare stdin with file, output matching prefix */ 3 | int main() { 4 | char c1; 5 | char c2; 6 | FILE_ptr f; 7 | f = fopen("six-cc-tests/getchar-interlaced.c", 0); 8 | while ((c1 = getchar()) && (c2 = fgetc(f)) && c1 == c2 && c1 != EOF) { 9 | putchar(c1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/if.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int x; 3 | int y; 4 | 5 | x = 42; 6 | y = 128; 7 | 8 | if (x < y) { 9 | printf("if (x < y)\n"); 10 | } else { 11 | printf("else (x >= y)\n"); 12 | } 13 | 14 | if (x > y) { 15 | printf("x > y\n"); 16 | } else if (x == y) { 17 | printf("else if (x == y)\n"); 18 | } 19 | 20 | if (x > y) { 21 | printf("if (x > y)\n"); 22 | } else if (x == y) { 23 | printf("else if (x == y)\n"); 24 | } else { 25 | printf("else (x < y)\n"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/if.golden: -------------------------------------------------------------------------------- 1 | if (x < y) 2 | else (x < y) 3 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/increment.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | int b; 4 | int x; 5 | int y; 6 | int z; 7 | 8 | x = 3; 9 | y = x++; 10 | x = 3; 11 | z = ++x; 12 | 13 | a = 0; 14 | b = 0; 15 | while (a < 10) { 16 | b += a++; 17 | } 18 | printf("a: %d, b: %d, x: %d, y: %d, z: %d\n", a, b, x, y, z); 19 | } 20 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/increment.golden: -------------------------------------------------------------------------------- 1 | a: 10, b: 45, x: 4, y: 3, z: 4 2 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/init.c: -------------------------------------------------------------------------------- 1 | void main() { 2 | int i = 0; 3 | int j = 5; 4 | int k; 5 | char_ptr s; 6 | char_ptr t = "Hello, world!"; 7 | k = 42; 8 | printf("i: %d, j: %d, k: %d\n", i, j, k); 9 | printf("t: %s\n", t); 10 | } 11 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/init.golden: -------------------------------------------------------------------------------- 1 | i: 0, j: 5, k: 42 2 | t: Hello, world! 3 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/initialization.c: -------------------------------------------------------------------------------- 1 | void main() { 2 | int i = 28; 3 | int j = 14; 4 | int k = i + j; 5 | printf("i: %d, j: %d, k: %d\n", i, j, k); 6 | } 7 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/initialization.golden: -------------------------------------------------------------------------------- 1 | i: 28, j: 14, k: 42 2 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/memset.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int MAX_SIZE; 3 | char_ptr s; 4 | char_ptr s2; 5 | char_ptr f; 6 | int len; 7 | int res; 8 | int i; 9 | MAX_SIZE = 100; 10 | malloc(MAX_SIZE); 11 | s = malloc(MAX_SIZE); 12 | s2 = malloc(MAX_SIZE); 13 | f = open("six-cc-tests/memset.c", 0); 14 | len = read(f, s, MAX_SIZE - 1); 15 | s[len] = 0; 16 | /* Initialize s2 with s */ 17 | for (i = 0; i < len; i++) { 18 | s2[i] = s[i]; 19 | 20 | } 21 | printf("s = s2: %d\n", memcmp(s, s2, len)); 22 | s[12] += 25; 23 | printf("s[12] = 25: %d\n", memcmp(s, s2, len)); 24 | } 25 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/memset.golden: -------------------------------------------------------------------------------- 1 | s = s2: 0 2 | s[12] = 25: 25 3 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/nested-calls.c: -------------------------------------------------------------------------------- 1 | int abc(int x) { 2 | return x + 1; 3 | } 4 | 5 | int def(int x) { 6 | return x * 2; 7 | } 8 | 9 | int hij(int x, int y) { 10 | return x * y; 11 | } 12 | 13 | int counter; 14 | counter = 10; 15 | 16 | int decrement(int i) { 17 | i--; 18 | return i; 19 | } 20 | 21 | int r[2801]; 22 | 23 | int main() { 24 | abc(123); 25 | r[abc(123)] = 2000; 26 | printf("%d\n", r[abc(123)]); 27 | /* while (counter = decrement(counter)) { */ 28 | while (counter--) { 29 | printf("Counter: %d\n", counter); 30 | } 31 | printf("%d\n", abc(42)); /* 43 */ 32 | printf("%d\n", abc(def(123))); /* (123 * 2) + 1 */ 33 | printf("%d\n", hij(abc(123), def(123))); /* (123 + 1) * (123 * 2) = 30504 */ 34 | printf("%d\n", hij(abc(123), def(123)) + abc(123)); /* 30504 + 124 = 30628 */ 35 | printf("%d %d\n", hij(2, 3), abc(123)); /* 6 124 */ 36 | } 37 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/nested-calls.golden: -------------------------------------------------------------------------------- 1 | 2000 2 | Counter: 9 3 | Counter: 8 4 | Counter: 7 5 | Counter: 6 6 | Counter: 5 7 | Counter: 4 8 | Counter: 3 9 | Counter: 2 10 | Counter: 1 11 | Counter: 0 12 | 43 13 | 247 14 | 30504 15 | 30628 16 | 6 124 17 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/no-trailing.txt: -------------------------------------------------------------------------------- 1 | abcdefghijklmnopqrstuvwxyz -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/print.c: -------------------------------------------------------------------------------- 1 | void main() 2 | { 3 | char_ptr str; 4 | str = "ABCDEFHIJKLMNOPQRSTUVWXYZ"; 5 | printf("%d\n", 42); 6 | printf("Beau %s\n", "velo"); 7 | printf("Beau %s %s\n", "velo (%s)", "bleu"); 8 | 9 | printf("Beau %s %s %s\n", "velo (%s)", "bleu", "rouge"); 10 | 11 | printf("%c", 'A'); 12 | printf("%c", 'L'); 13 | printf("%c", 'L'); 14 | printf("%c\n", 'O'); 15 | 16 | printf("Allo in hex: 0x%x 0x%x 0x%x 0x%x\n", 'A', 'L', 'L', 'O'); 17 | 18 | printf("_\n"); 19 | 20 | printf("alphabet:\n%s\n", str); 21 | printf("4 first letters of the alphabet with .*s:\n%.*s\n", 4, str); 22 | printf("4 first letters of the alphabet with 0.4s:\n%0.4s\n", str); 23 | printf("Last 4 letters of the alphabet with padding:\n%26.s\n", "ABCDEFHIJKLMNOPQRSTUVWXYZ" + 20); 24 | printf("The alphabet twice: %s %s\n", "ABCDEFHIJKLMNOPQRSTUVWXYZ", "ABCDEFHIJKLMNOPQRSTUVWXYZ"); 25 | } 26 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/print.golden: -------------------------------------------------------------------------------- 1 | 42 2 | Beau velo 3 | Beau velo (%s) bleu 4 | Beau velo (%s) bleu rouge 5 | ALLO 6 | Allo in hex: 0x41 0x4c 0x4c 0x4f 7 | _ 8 | alphabet: 9 | ABCDEFHIJKLMNOPQRSTUVWXYZ 10 | 4 first letters of the alphabet with .*s: 11 | ABCD 12 | 4 first letters of the alphabet with 0.4s: 13 | ABCD 14 | Last 4 letters of the alphabet with padding: 15 | VWXYZ 16 | The alphabet twice: ABCDEFHIJKLMNOPQRSTUVWXYZ ABCDEFHIJKLMNOPQRSTUVWXYZ 17 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/return.c: -------------------------------------------------------------------------------- 1 | int test() { 2 | int i; 3 | if (1) { 4 | return; 5 | } 6 | } 7 | 8 | 9 | int main() { 10 | test(); 11 | } 12 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/return.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/attic/six-cc/six-cc-tests/return.golden -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/short-circuit.c: -------------------------------------------------------------------------------- 1 | /* Test that the lazy evaluation properties of || and && are respected */ 2 | 3 | void DO_NOT_CALL(int x) { 4 | int a; /* Local variable so that the function is not simple */ 5 | printf("Boom!"); 6 | exit(1); 7 | return x; 8 | } 9 | 10 | void SHOULD_BE_CALLED(int x) { 11 | int a; /* Local variable so that the function is not simple */ 12 | if (x) { 13 | printf("Ah!\n"); 14 | } 15 | else { 16 | printf("Oh!\n"); 17 | } 18 | return x; 19 | } 20 | 21 | int main() { 22 | if (1 || DO_NOT_CALL(1)) { 23 | printf("This should print 1\n"); 24 | } 25 | if (0 || SHOULD_BE_CALLED(1)) { 26 | printf("This should print 2\n"); 27 | } 28 | if (0 || SHOULD_BE_CALLED(0)) { 29 | printf("This should not print\n"); 30 | } 31 | if (1 && SHOULD_BE_CALLED(1)) { 32 | printf("This should print 3\n"); 33 | } 34 | if (1 && SHOULD_BE_CALLED(0)) { 35 | printf("This should not print\n"); 36 | } 37 | if (0 && DO_NOT_CALL(1)) { 38 | printf("This should not print\n"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/short-circuit.golden: -------------------------------------------------------------------------------- 1 | This should print 1 2 | Ah! 3 | This should print 2 4 | Oh! 5 | Ah! 6 | This should print 3 7 | Oh! 8 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/string.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | char_ptr str = "LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT,"; 3 | int i = 0; 4 | while (i < 39) { 5 | printf("%0.4s\n", str + i * 5); 6 | i++; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/string.golden: -------------------------------------------------------------------------------- 1 | LEA 2 | IMM 3 | JMP 4 | JSR 5 | BZ 6 | BNZ 7 | ENT 8 | ADJ 9 | LEV 10 | LI 11 | LC 12 | SI 13 | SC 14 | PSH 15 | OR 16 | XOR 17 | AND 18 | EQ 19 | NE 20 | LT 21 | GT 22 | LE 23 | GE 24 | SHL 25 | SHR 26 | ADD 27 | SUB 28 | MUL 29 | DIV 30 | MOD 31 | OPEN 32 | READ 33 | CLOS 34 | PRTF 35 | MALC 36 | FREE 37 | MSET 38 | MCMP 39 | EXIT 40 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/strlen.c: -------------------------------------------------------------------------------- 1 | /* typedef char *char_ptr; */ 2 | 3 | int string_len(char_ptr s) { 4 | int ix; 5 | ix = 0; 6 | while (s[ix] != 0) { 7 | ix++; 8 | } 9 | return ix; 10 | } 11 | 12 | int string_sum(char_ptr s) { 13 | int sum; 14 | sum = 0; 15 | while (*s != 0) { 16 | sum += *s; 17 | s++; 18 | } 19 | return sum; 20 | } 21 | 22 | int iota_array(int start, int max) { 23 | int i; 24 | int_ptr arr; 25 | arr = malloc(max - start); 26 | for (i = 0; i + start < max; i++) { 27 | arr[i] = i + start; 28 | } 29 | return arr; 30 | } 31 | 32 | int array_sum(int_ptr arr, int len) { 33 | int sum; 34 | int i; 35 | sum = 0; 36 | i = 0; 37 | while (i < len) { 38 | sum += arr[i]; 39 | i++; 40 | } 41 | return sum; 42 | } 43 | 44 | int main() { 45 | int n1; 46 | int n2; 47 | int n3; 48 | int arr; 49 | arr = iota_array(0, 50); 50 | n1 = string_len([1,2,3,4,5,0]); 51 | n2 = string_sum("Hello, world!"); 52 | n3 = array_sum(arr, 50); 53 | printf("n1 = %d\n", n1); 54 | printf("n2 = %d\n", n2); 55 | printf("n3 = %d\n", n3); 56 | } 57 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/strlen.golden: -------------------------------------------------------------------------------- 1 | n1 = 5 2 | n2 = 1161 3 | n3 = 1225 4 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/struct-enum.c: -------------------------------------------------------------------------------- 1 | /* Simulating structs using enums like in c4.c */ 2 | enum LinkedList() { VAL; NEXT; LL_SIZE; } 3 | 4 | int_ptr iota_linked_list(int max) { 5 | int i; 6 | int_ptr head; 7 | int_ptr last; 8 | int_ptr node; 9 | if (max == 0) return NULL; 10 | head = malloc(LL_SIZE); 11 | head[VAL] = 0; 12 | last = head; 13 | i = 1; 14 | while (i < max) { 15 | node = malloc(LL_SIZE); 16 | node[VAL] = i; 17 | node[NEXT] = NULL; 18 | last[NEXT] = node; 19 | last = node; 20 | 21 | i++; 22 | } 23 | 24 | return head; 25 | } 26 | 27 | int linked_list_sum(int_ptr head) { 28 | int sum; 29 | sum = 0; 30 | while (head != NULL) { 31 | sum += head[VAL]; 32 | head = head[NEXT]; 33 | } 34 | 35 | return sum; 36 | } 37 | 38 | int main() { 39 | int_ptr ll; 40 | int sum; 41 | char_ptr str; 42 | 43 | ll = iota_linked_list(1000); 44 | 45 | sum = linked_list_sum(ll); 46 | printf("Sum: %d\n", sum); 47 | } 48 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/struct-enum.golden: -------------------------------------------------------------------------------- 1 | Sum: 499500 2 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/struct.c: -------------------------------------------------------------------------------- 1 | /* Simulating structs using enums like in c4.c */ 2 | struct LinkedList() { void val; void next; } 3 | 4 | int_ptr iota_linked_list(int max) { 5 | int i; 6 | int_ptr head; 7 | int_ptr last; 8 | int_ptr node; 9 | if (max == 0) return NULL; 10 | head = malloc(2); 11 | head->val = 0; 12 | last = head; 13 | i = 1; 14 | while (i < max) { 15 | node = malloc(2); 16 | node->val = i; 17 | node->next = NULL; 18 | last->next = node; 19 | last = node; 20 | 21 | i++; 22 | } 23 | 24 | return head; 25 | } 26 | 27 | int linked_list_sum(int_ptr head) { 28 | int sum; 29 | sum = 0; 30 | while (head != NULL) { 31 | sum += head->val; 32 | head = head->next; 33 | } 34 | 35 | return sum; 36 | } 37 | 38 | int linked_list_sum_except_last(int_ptr head) { 39 | int sum; 40 | sum = 0; 41 | while (head != NULL && head->next != NULL) { 42 | sum += head->val; 43 | head = head->next; 44 | } 45 | 46 | return sum; 47 | } 48 | 49 | int main() { 50 | int_ptr ll; 51 | 52 | ll = iota_linked_list(1000); 53 | 54 | printf("Sum: %d\n", linked_list_sum(ll)); 55 | printf("Sum: %d\n", linked_list_sum_except_last(NULL)); 56 | printf("Sum: %d\n", linked_list_sum_except_last(ll)); 57 | } 58 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/struct.golden: -------------------------------------------------------------------------------- 1 | Sum: 499500 2 | Sum: 0 3 | Sum: 498501 4 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/switch.c: -------------------------------------------------------------------------------- 1 | enum Category() { 2 | LOWERCASE = 1; 3 | UPPERCASE; 4 | NEWLINE; 5 | OTHER; 6 | } 7 | 8 | /* For all ascii characters, categorize them into 4 categories */ 9 | int categorize_char(char c) { 10 | int a; 11 | switch (c) { 12 | case 'a': 13 | case 'b': 14 | case 'c': 15 | case 'd': 16 | case 'e': 17 | case 'f': 18 | case 'g': 19 | case 'h': 20 | case 'i': 21 | case 'j': 22 | case 'k': 23 | case 'l': 24 | case 'm': 25 | case 'n': 26 | case 'o': 27 | case 'p': 28 | case 'q': 29 | case 'r': 30 | case 's': 31 | case 't': 32 | case 'u': 33 | case 'v': 34 | case 'w': 35 | case 'x': 36 | case 'y': 37 | case 'z': 38 | a = LOWERCASE; 39 | return LOWERCASE; 40 | case 'A': 41 | case 'B': 42 | case 'C': 43 | case 'D': 44 | case 'E': 45 | case 'F': 46 | case 'G': 47 | case 'H': 48 | case 'I': 49 | case 'J': 50 | case 'K': 51 | case 'L': 52 | case 'M': 53 | case 'N': 54 | case 'O': 55 | case 'P': 56 | case 'Q': 57 | case 'R': 58 | case 'S': 59 | case 'T': 60 | case 'U': 61 | case 'V': 62 | case 'W': 63 | case 'X': 64 | case 'Y': 65 | case 'Z': 66 | return UPPERCASE; 67 | case '\n': 68 | return NEWLINE; 69 | default: 70 | return OTHER; 71 | } 72 | /* Dead code, but puts the switch in non-tail call position */ 73 | return a; 74 | } 75 | 76 | int main() { 77 | FILE_ptr f; 78 | char c; 79 | f = fopen("six-cc-tests/fgetc.c", "r"); 80 | while ((c = fgetc(f)) != EOF) { 81 | printf("'%c' = %d: %d\n", c, c, categorize_char(c)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/test.c: -------------------------------------------------------------------------------- 1 | void main() { 2 | /* print a number to stdout */ 3 | int NL; 4 | int ZERO; 5 | int n; 6 | int p; 7 | int digit; 8 | NL = 10; 9 | ZERO = 48; 10 | n = 31416; 11 | p = 1; 12 | 13 | while (p * 10 <= n) p = p * 10; 14 | 15 | while (p > 0) { 16 | digit = n / p; 17 | putchar(ZERO + digit); 18 | n = n % p; 19 | p = p / 10; 20 | } 21 | 22 | putchar(NL); 23 | } 24 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/test.golden: -------------------------------------------------------------------------------- 1 | 31416 2 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/test2.c: -------------------------------------------------------------------------------- 1 | int square(int x) { 2 | return x*x; 3 | } 4 | 5 | void main() 6 | { 7 | int n; 8 | 9 | /* print a number to stdout */ 10 | 11 | int p; 12 | int digit; 13 | 14 | n = square(10); 15 | p = 1; 16 | 17 | while (p * 10 <= n) p = p * 10; 18 | 19 | while (p > 0) { 20 | digit = n / p; 21 | putchar(48 + digit); 22 | n = n % p; 23 | p = p / 10; 24 | } 25 | 26 | putchar(10); 27 | } 28 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/test2.golden: -------------------------------------------------------------------------------- 1 | 100 2 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/while-continue.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (i = 0; i < 35; i++) { 3 | /* Skip over even numbers*/ 4 | if (i % 2 == 0) { 5 | continue; 6 | } 7 | printf("%d: ", i); 8 | if (i % 3 == 0) { 9 | printf("fizz"); 10 | } 11 | if (i % 5 == 0) { 12 | printf("buzz"); 13 | } 14 | printf(".\n"); 15 | if (i == 12) break; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/while-continue.golden: -------------------------------------------------------------------------------- 1 | 1: . 2 | 3: fizz. 3 | 5: buzz. 4 | 7: . 5 | 9: fizz. 6 | 11: . 7 | 13: . 8 | 15: fizzbuzz. 9 | 17: . 10 | 19: . 11 | 21: fizz. 12 | 23: . 13 | 25: buzz. 14 | 27: fizz. 15 | 29: . 16 | 31: . 17 | 33: fizz. 18 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/while-fun-call.c: -------------------------------------------------------------------------------- 1 | int emit_line(int line, FILE_ptr f) { 2 | char c; 3 | printf("%d: ", line); 4 | while ((c = fgetc(f)) && c != EOF && c != '\n') { 5 | putchar(c); 6 | } 7 | if (c != EOF) { 8 | putchar('\n'); 9 | } 10 | return c; 11 | } 12 | 13 | int main() { 14 | FILE_ptr f1; 15 | FILE_ptr f2; 16 | char c1; 17 | char c2; 18 | int i = 0; 19 | f1 = fopen("six-cc-tests/fgetc.c", "r"); 20 | f2 = fopen("six-cc-tests/while-fun-call.c", "r"); 21 | while (1) { 22 | c1 = emit_line(i, f1); 23 | c2 = emit_line(i, f2); 24 | if (c1 == EOF || c2 == EOF) break; 25 | i += 1; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/while-fun-call.golden: -------------------------------------------------------------------------------- 1 | 0: int main() { 2 | 0: int emit_line(int line, FILE_ptr f) { 3 | 1: FILE_ptr f; 4 | 1: char c; 5 | 2: char c; 6 | 2: printf("%d: ", line); 7 | 3: f = fopen("six-cc-tests/fgetc.c", 0); 8 | 3: while ((c = fgetc(f)) && c != EOF && c != '\n') { 9 | 4: while ((c = fgetc(f)) != EOF) { 10 | 4: putchar(c); 11 | 5: putchar(c); 12 | 5: } 13 | 6: } 14 | 6: if (c != EOF) { 15 | 7: fclose(f); 16 | 7: putchar('\n'); 17 | 8: } 18 | 8: } 19 | 9: 9: return c; 20 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/winter-pi2.c: -------------------------------------------------------------------------------- 1 | /* #include */ 2 | 3 | /* https://cs.uwaterloo.ca/~alopez-o/math-faq/mathtext/node12.html */ 4 | 5 | int r[2801]; 6 | int i; 7 | int k; 8 | int b; 9 | int d; 10 | int c = 0; 11 | 12 | int main() { 13 | int newline; 14 | int newline2; 15 | newline = identity(10, 2, 3); 16 | 17 | for (; i < 2800; i++) { 18 | r[i] = 2000; 19 | } 20 | r[i] = 0; 21 | 22 | for (k = 280; k > 0; k = k - 14) { 23 | 24 | d = 0; 25 | i = k; 26 | for (;;) { 27 | d = d + r[i] * 10000; 28 | b = 2 * i - 1; 29 | 30 | r[i] = d % b; 31 | d = d / b; 32 | i--; 33 | if (i == 0) break; 34 | d = d * i; 35 | } 36 | putchar(48 + (c + d / 10000) / 1000 % 10); 37 | putchar(48 + (c + d / 10000) / 100 % 10); 38 | putchar(48 + (c + d / 10000) / 10 % 10); 39 | putchar(48 + (c + d / 10000) % 10); 40 | c = d % 10000; 41 | } 42 | 43 | putchar(newline); 44 | 45 | return 0; 46 | } 47 | 48 | int identity(int x, int y, int z) { 49 | return x; 50 | } 51 | -------------------------------------------------------------------------------- /attic/six-cc/six-cc-tests/winter-pi2.golden: -------------------------------------------------------------------------------- 1 | 31415926535897932384626433832795028841971693993751058209749445923078164062862089 2 | -------------------------------------------------------------------------------- /attic/six-cc/test-six-cc-all-options.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import subprocess 3 | 4 | parser = argparse.ArgumentParser() 5 | 6 | parser.add_argument('--shell', type=str, help='Which shell to run the tests with', default="ksh") 7 | shell = parser.parse_args().shell 8 | 9 | boolean_options = ["true", "false"] 10 | 11 | options = [ ["--malloc-init"] # , "--malloc-no-init"] 12 | , ["--free-unsets-vars", "--free-noop"] 13 | , ["--zero-globals", "--no-zero-globals"] 14 | , ["--inline-inplace-arithmetic", "--no-inline-inplace-arithmetic"] 15 | , ["--prefix-local-vars", "--no-prefix-local-vars"] 16 | , ["--init-string-inline", "--init-string-upfront"] 17 | , ["--use-shell-conditions"] # , "--use-arithmetic-conditions", ] 18 | , ["--use-arithmetic-assignment", "--use-regular-assignment"] 19 | , ["--optimize-readonly-params", "--no-optimize-readonly-params"] 20 | , ["--optimize-return-loc", "--no-optimize-return-loc"] 21 | , ["--numeric-chars", "--no-numeric-chars"] 22 | ] 23 | 24 | def generate_options(opts): 25 | if len(opts) == 0: 26 | yield ""; 27 | else: 28 | for opt in opts[0]: 29 | for rest in generate_options(opts[1:]): 30 | yield f"{opt} " + rest 31 | 32 | for six_cc_options in generate_options(options): 33 | print(f"Running tests with {shell} with options: {six_cc_options}") 34 | subprocess.run(f"SHELL=\"{shell}\" SIX_CC_OPTIONS=\"{six_cc_options}\" QUIET=1 make test-six-cc", shell=True) 35 | -------------------------------------------------------------------------------- /benchmark-bootstrap-with-options.sh: -------------------------------------------------------------------------------- 1 | shells="ksh dash bash yash zsh" 2 | 3 | with_options() { 4 | for shell in $shells; do 5 | ./benchmark-bootstrap.sh $shell $@ 6 | done 7 | } 8 | 9 | # Bootstrap benchmarks: 10 | # - Baseline 11 | # - With set 12 | # - Including C code 13 | # - Inlined characters 14 | # - Optimize long lines 15 | 16 | with_options 17 | with_options "-DSH_SAVE_VARS_WITH_SET" 18 | with_options "-DSH_INCLUDE_C_CODE" 19 | with_options "-DSH_INLINE_CHAR_LITERAL" 20 | with_options "-DOPTIMIZE_LONG_LINES" 21 | -------------------------------------------------------------------------------- /benchmarks/long-lines/cat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * compile with: 3 | * 4 | * $ ksh pnut.sh cat.c > cat.sh 5 | * 6 | * execute with: 7 | * 8 | * $ ksh cat.sh FILE1 FILE2 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #define BUF_SIZE 1024 16 | 17 | char buf[BUF_SIZE]; 18 | 19 | void cat_fd(int fd) { 20 | int n = BUF_SIZE; 21 | while (n == BUF_SIZE) { 22 | n = read(fd, buf, BUF_SIZE); 23 | if (n < 0 || write(1, buf, n) != n) exit(1); 24 | } 25 | } 26 | 27 | void cat_file(char *filename) { 28 | int fd = open(filename, 0); 29 | if (fd < 0) exit(1); 30 | cat_fd(fd); 31 | close(fd); 32 | } 33 | 34 | int main(int argc, char **myargv) { 35 | 36 | int i; 37 | 38 | if (argc >= 2) { 39 | for (i=1; i&1 | fgrep real | sed -e "s/real[^0-9]*//g" -e "s/m/*60000+/g" -e "s/s//g" -e "s/\\+0\\./-1000+1/g" -e "s/\\.//g"` )) 20 | print_time $TIME_MS "for: $1 base with lines of length $len" 21 | 22 | TIME_MS=$(( `bash -c "time $1 $COMP_DIR/cat-long-lines.sh $DIR/long-line-$len.txt" 2>&1 | fgrep real | sed -e "s/real[^0-9]*//g" -e "s/m/*60000+/g" -e "s/s//g" -e "s/\\+0\\./-1000+1/g" -e "s/\\.//g"` )) 23 | print_time $TIME_MS "for: $1 fast with lines of length $len" 24 | } 25 | 26 | lengths="1000 2000 5000 10000 20000" 27 | shells="dash bash yash zsh ksh" 28 | 29 | # Compile pnut with 30 | PNUT_OPTIONS="-DRT_NO_INIT_GLOBALS -Dsh" 31 | gcc -o $COMP_DIR/pnut-sh-base.exe $PNUT_OPTIONS pnut.c 32 | gcc -o $COMP_DIR/pnut-sh-long-lines.exe $PNUT_OPTIONS -DOPTIMIZE_LONG_LINES pnut.c 33 | 34 | ./$COMP_DIR/pnut-sh-base.exe $DIR/cat.c > $COMP_DIR/cat-base.sh 35 | ./$COMP_DIR/pnut-sh-long-lines.exe $DIR/cat.c > $COMP_DIR/cat-long-lines.sh 36 | 37 | for len in $lengths; do 38 | for shell in $shells; do 39 | with_size "$shell" $len 40 | done 41 | done 42 | -------------------------------------------------------------------------------- /benchmarks/memory-size-slowdown/memory-size-slowdown.c: -------------------------------------------------------------------------------- 1 | // Allocate a large array and sum its elements. 2 | // Runtime should be proportional to ARR_SIZE, but some shells show superlinear 3 | // running time. 4 | 5 | // #define ARR_SIZE 10000 6 | 7 | void main() { 8 | int* arr = malloc(ARR_SIZE); 9 | int sum = 0; 10 | int i = 0; 11 | for (i = 0; i < ARR_SIZE; i++) { 12 | arr[i] = 0; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /benchmarks/memory-size-slowdown/run.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | DIR="benchmarks/memory-size-slowdown" 4 | COMP_DIR="$DIR/compiled" 5 | 6 | # Create the compiled directory if it doesn't exist 7 | mkdir -p $COMP_DIR 8 | 9 | print_time() 10 | { 11 | ms=$1 12 | printf "%s %s\n" "$((ms/1000)).$((ms/100%10))$((ms/10%10))$((ms%10))s" "$2" 13 | } 14 | 15 | with_size() { 16 | # shell=$1 17 | env_size=$2 18 | gcc -E -P -DARR_SIZE=$env_size $DIR/memory-size-slowdown.c > $COMP_DIR/memory-size-slowdown-$env_size.c 19 | 20 | ./benchmarks/pnut-sh.exe $COMP_DIR/memory-size-slowdown-$env_size.c > $COMP_DIR/memory-size-slowdown-$env_size.sh 21 | 22 | TIME_MS=$(( `bash -c "time $1 $COMP_DIR/memory-size-slowdown-$env_size.sh" 2>&1 | fgrep real | sed -e "s/real[^0-9]*//g" -e "s/m/*60000+/g" -e "s/s//g" -e "s/\\+0\\./-1000+1/g" -e "s/\\.//g"` )) 23 | print_time $TIME_MS "for: $1 with $env_size" 24 | } 25 | 26 | sizes="1000 5000 10000 50000 100000 500000 1000000" 27 | shells="ksh dash bash yash zsh" 28 | 29 | # Compile pnut with 30 | gcc -o benchmarks/pnut-sh.exe -Dsh -DRT_NO_INIT_GLOBALS $@ pnut.c 31 | 32 | for shell in $shells; do 33 | for size in $sizes; do 34 | with_size "$shell" $size 35 | done 36 | done 37 | -------------------------------------------------------------------------------- /diff-pnut-sh.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | set -e 4 | 5 | : ${PNUT_OPTIONS:=} # Default to empty options 6 | 7 | TEMP_DIR="build" 8 | PNUT_SH_OPTIONS="$PNUT_OPTIONS -DRT_NO_INIT_GLOBALS -Dsh" 9 | PNUT_SH_OPTIONS_FAST="$PNUT_SH_OPTIONS -DSH_SAVE_VARS_WITH_SET -DOPTIMIZE_CONSTANT_PARAM" 10 | PNUT_SH_FILE_ORIGINAL="$TEMP_DIR/pnut-sh-original.sh" 11 | PNUT_SH_FILE_FRESH="$TEMP_DIR/pnut-sh.sh" 12 | 13 | # Parse the arguments 14 | init=0 15 | 16 | while [ $# -gt 0 ]; do 17 | case $1 in 18 | --fast) PNUT_SH_OPTIONS="$PNUT_SH_OPTIONS_FAST"; shift 1 ;; 19 | --init) init=1; shift 1 ;; 20 | *) echo "Unknown option: $1"; exit 1;; 21 | esac 22 | done 23 | 24 | if [ ! -d "$TEMP_DIR" ]; then mkdir "$TEMP_DIR"; fi 25 | 26 | gcc -o "$TEMP_DIR/pnut.exe" $PNUT_SH_OPTIONS pnut.c 27 | 28 | if [ $init -eq 1 ]; then 29 | ./$TEMP_DIR/pnut.exe $PNUT_SH_OPTIONS "pnut.c" > "$PNUT_SH_FILE_ORIGINAL" 30 | exit 0 31 | fi 32 | 33 | if [ ! -f "$PNUT_SH_FILE_ORIGINAL" ]; then 34 | echo "$PNUT_SH_FILE_ORIGINAL not found. Run this script with --init first." 35 | exit 1 36 | fi 37 | ./$TEMP_DIR/pnut.exe $PNUT_SH_OPTIONS "pnut.c" > "$PNUT_SH_FILE_FRESH" 38 | diff -w "$PNUT_SH_FILE_ORIGINAL" "$PNUT_SH_FILE_FRESH" 39 | -------------------------------------------------------------------------------- /doc/paper-SLE24.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/doc/paper-SLE24.pdf -------------------------------------------------------------------------------- /doc/presentation-SLE24.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/doc/presentation-SLE24.pdf -------------------------------------------------------------------------------- /examples/all-chars.c: -------------------------------------------------------------------------------- 1 | /* 2 | * all-chars.c: Print all non-extended ASCII characters. 3 | * 4 | * Usage: ./all-chars.sh 5 | */ 6 | 7 | void main() { 8 | char c = 0; 9 | while (c < 128) { 10 | putchar(c); 11 | c += 1; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/c4-libs/fcntl.h: -------------------------------------------------------------------------------- 1 | // Empty 2 | -------------------------------------------------------------------------------- /examples/c4-libs/memory.h: -------------------------------------------------------------------------------- 1 | void *memset(void *b, int c, int len) 2 | { 3 | char *p = b; 4 | while (len--) *p++ = c; 5 | return b; 6 | } 7 | 8 | int memcmp(const void *vl, const void *vr, int n) { 9 | 10 | const char *l = vl; 11 | const char *r = vr; 12 | 13 | while (n && *l == *r) { 14 | --n; 15 | ++l; 16 | ++r; 17 | } 18 | 19 | return n ? (*l & 255) - (*r & 255) : 0; 20 | } 21 | -------------------------------------------------------------------------------- /examples/c4-libs/stdio.h: -------------------------------------------------------------------------------- 1 | // Empty 2 | -------------------------------------------------------------------------------- /examples/c4-libs/stdlib.h: -------------------------------------------------------------------------------- 1 | // Empty 2 | -------------------------------------------------------------------------------- /examples/c4-libs/unistd.h: -------------------------------------------------------------------------------- 1 | // Empty 2 | -------------------------------------------------------------------------------- /examples/cat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cat.c: Output the contents of files passed as arguments or stdin 3 | * 4 | * Usage: ./cat.sh 5 | * ./cat.sh < input 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define BUF_SIZE 1024 13 | 14 | char buf[BUF_SIZE]; 15 | 16 | void cat_fd(int fd) { 17 | int n = BUF_SIZE; 18 | while (n == BUF_SIZE) { 19 | n = read(fd, buf, BUF_SIZE); 20 | if (n < 0 || write(1, buf, n) != n) exit(1); 21 | } 22 | } 23 | 24 | void cat_file(char *filename) { 25 | int fd = open(filename, 0); 26 | if (fd < 0) exit(1); 27 | cat_fd(fd); 28 | close(fd); 29 | } 30 | 31 | int main(int argc, char **myargv) { 32 | 33 | int i; 34 | 35 | if (argc >= 2) { 36 | for (i=1; i 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #ifndef O_RDONLY 13 | #define O_RDONLY 0 14 | #endif 15 | 16 | #ifndef O_WRONLY 17 | #define O_WRONLY 1 18 | #endif 19 | 20 | void file_error(char *filename) { 21 | printf("cp: %s: no such file or directory\n", filename); 22 | exit(1); 23 | } 24 | 25 | #define BUFFER_LEN 1024 26 | char* buffer[BUFFER_LEN]; 27 | 28 | int main(int argc, char **args) { 29 | int src, dst; 30 | char c; 31 | int len; 32 | 33 | if (argc != 3) { 34 | printf("Usage: cp \n"); 35 | return 1; 36 | } 37 | 38 | src = open(args[1], O_RDONLY); 39 | dst = open(args[2], O_WRONLY); 40 | 41 | if (src == 0) { file_error(args[1]); } 42 | if (dst == 0) { file_error(args[2]); } 43 | 44 | while ((len = read(src, buffer, BUFFER_LEN)) != 0) { 45 | write(dst, buffer, len); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/echo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * echo.c: Output the arguments passed to it 3 | * 4 | * Usage: ./echo.sh 5 | */ 6 | 7 | void main(int argc, char **argv) { 8 | int i; 9 | for (i=1; i < argc; ++i) { 10 | printf("%s ", argv[i]); 11 | } 12 | printf("\n"); 13 | } 14 | -------------------------------------------------------------------------------- /examples/empty.c: -------------------------------------------------------------------------------- 1 | /* 2 | * empty.c: Do nothing 3 | * 4 | * Usage: ./empty.sh 5 | */ 6 | 7 | void main() {} 8 | -------------------------------------------------------------------------------- /examples/fib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * fib.c: Print the first 20 Fibonacci numbers. 3 | * 4 | * Usage: ./fib.sh 5 | */ 6 | 7 | #include 8 | 9 | int fib(int n) { 10 | if (n < 2) { 11 | return n; 12 | } else { 13 | return fib(n - 1) + fib(n - 2); 14 | } 15 | } 16 | 17 | void main() { 18 | int n; 19 | int i = 0; 20 | while (i < 20) { 21 | n = fib(i); 22 | printf("fib(%d) = %d\n", i, n); 23 | ++i; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/hello.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hello.c: Print "Hello, world" 3 | * 4 | * Usage: ./hello.sh 5 | */ 6 | 7 | #include 8 | 9 | int main() { 10 | printf("Hello, world\n"); 11 | } 12 | -------------------------------------------------------------------------------- /examples/non_zero.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void main() { 4 | int n = 0; 5 | do { 6 | printf("Enter a non-zero single-digit number:\r\n"); 7 | n = getchar(); 8 | while ('\n' != getchar()) 9 | ; 10 | } while( n == '0' || !(n >= '0' && n <= '9')); 11 | 12 | printf("You entered %c: bye bye!\r\n", n); 13 | } 14 | -------------------------------------------------------------------------------- /examples/print-reverse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * print-reverse.c: Print command-line arguments in reverse order 3 | * 4 | * Usage: ./print-reverse.sh 5 | */ 6 | 7 | #include 8 | 9 | void reverse_str(char* str) { 10 | char* end = str; 11 | char tmp; 12 | int len, i = 0; 13 | while (*(end++)); // Compute length of string 14 | len = end - str - 1; 15 | 16 | for (; i < len / 2; ++i) { 17 | tmp = str[i]; 18 | str[i] = str[len - 1 - i]; 19 | str[len - 1 - i] = tmp; 20 | } 21 | } 22 | 23 | void main(int argc, char **argv) { 24 | int i; 25 | for (i = 1; i < argc; ++i) { 26 | reverse_str(argv[i]); 27 | printf("%s\n", i, argv[i]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/reverse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * reverse.c: Reverse the order of command-line arguments 3 | * 4 | * Usage: ./reverse.sh 5 | */ 6 | 7 | #include 8 | 9 | void main(int argc, char **argv) { 10 | int i; 11 | for (i = 1; i < argc; ++i) { 12 | printf("%s ", argv[argc - i]); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/select-file.c: -------------------------------------------------------------------------------- 1 | /* 2 | This example shows how C code can be combined with shell utilities to create 3 | a simple program that lists files in the current directory and prints the 4 | contents of a selected file. 5 | */ 6 | 7 | #include_shell "posix-utils.sh" 8 | 9 | #define NULL 0 10 | 11 | void print_array(char** arr) { 12 | int i = 0; 13 | while (arr[i] != NULL) { 14 | printf("%d: %s\n", i, arr[i]); 15 | i += 1; 16 | } 17 | } 18 | 19 | int array_len(char** arr) { 20 | int i = 0; 21 | while (arr[i] != NULL) { i += 1; } 22 | return i; 23 | } 24 | 25 | int read_int() { 26 | int n = 0; 27 | char c; 28 | while (1) { 29 | c = getchar(); 30 | if (c >= '0' && c <= '9') { 31 | n = 10 * n + c - '0'; 32 | } else { 33 | break; 34 | } 35 | } 36 | return n; 37 | } 38 | 39 | void main() { 40 | char **files; 41 | int ix; 42 | int len; 43 | printf("Files in current directory (%s)\n", pwd()); 44 | files = ls(); 45 | len = array_len(files); 46 | print_array(files); // Print files in current directory 47 | while (1) { 48 | printf("Select a file to print: "); 49 | ix = read_int(); 50 | if (0 <= ix && ix < len) { 51 | break; 52 | } 53 | printf("Invalid index.\n"); 54 | } 55 | cat(files[ix]); 56 | } 57 | -------------------------------------------------------------------------------- /examples/sum-array.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sum-array.c: Compute the sum of an array of integers of size 10000 3 | * 4 | * Usage: ./sum-array.sh 5 | */ 6 | 7 | int sum_array(int* n, int size) { 8 | int i = 0; 9 | int sum = 0; 10 | 11 | for (; i < size; i++) { 12 | sum += n[i]; 13 | } 14 | 15 | return sum; 16 | } 17 | 18 | void main() { 19 | int* n = malloc(10000); 20 | int i = 0; 21 | int sum = 0; 22 | 23 | for (; i < 10000; i++) { 24 | n[i] = i; 25 | } 26 | 27 | for (i = 0; i < 10000; i++) { 28 | sum += n[i]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/wc-stdin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wc-stdin.c: Read from stdin and count lines, words, and characters. 3 | * 4 | * Usage: ./wc-stdin.sh < input 5 | */ 6 | 7 | // is_word_separator can also be defined as a macro to speed up the program. 8 | // #define is_word_separator(c) ((c) == ' ' || (c) == '\n' || (c) == '\t') 9 | 10 | int is_word_separator(char c) { 11 | return c == ' ' || c == '\n' || c == '\t'; 12 | } 13 | 14 | void main() { 15 | int lines = 0, words = 0, chars = 0; 16 | char c; 17 | int sep = 0, last_sep = 0; 18 | 19 | while ((c = getchar()) != -1) { 20 | chars += 1; 21 | if (c == '\n') lines += 1; 22 | 23 | sep = is_word_separator(c); 24 | if (sep && !last_sep) { 25 | words += 1; 26 | } 27 | last_sep = sep; 28 | } 29 | 30 | printf("%d %d %d\n", lines, words, chars); 31 | } 32 | -------------------------------------------------------------------------------- /examples/wc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wc.c: Read from stdin or files and count lines, words, and characters. 3 | * 4 | * Usage: ./wc.sh [file ...] 5 | * ./wc.sh < input 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define BUF_SIZE 1024 14 | 15 | char buf[BUF_SIZE]; 16 | 17 | // is_word_separator can also be defined as a macro to speed up the program. 18 | // #define is_word_separator(c) ((c) == ' ' || (c) == '\n' || (c) == '\t') 19 | 20 | int is_word_separator(char c) { 21 | return c == ' ' || c == '\n' || c == '\t'; 22 | } 23 | 24 | void wc_fd(int fd, char *filename) { 25 | int lines = 0, words = 0, chars = 0; 26 | int sep = 0, last_sep = 0; 27 | int i; 28 | int n = BUF_SIZE; 29 | 30 | while (n == BUF_SIZE) { 31 | n = read(fd, buf, BUF_SIZE); 32 | 33 | i = 0; 34 | while (i < n) { 35 | chars += 1; 36 | if (buf[i] == '\n') lines += 1; 37 | 38 | sep = is_word_separator(buf[i]); 39 | if (sep && !last_sep) { 40 | words += 1; 41 | } 42 | last_sep = sep; 43 | i += 1; 44 | } 45 | } 46 | 47 | if (filename != 0) { 48 | printf("%d %d %d %s\n", lines, words, chars, filename); 49 | } else { 50 | printf("%d %d %d\n", lines, words, chars); 51 | } 52 | } 53 | 54 | void wc_file(char *filename) { 55 | int fd = open(filename, 0); 56 | if (fd < 0) exit(1); 57 | wc_fd(fd, filename); 58 | close(fd); 59 | } 60 | 61 | int main(int argc, char **argv) { 62 | 63 | int i; 64 | 65 | if (argc >= 2) { 66 | for (i=1; i 10 | 11 | int r[2801]; 12 | 13 | int main() { 14 | 15 | int i; 16 | int k; 17 | int b; 18 | int d; 19 | int c = 0; 20 | 21 | i = 0; 22 | 23 | while (i < 2800) { 24 | r[i] = 2000; 25 | i = i+1; 26 | } 27 | 28 | r[i] = 0; 29 | 30 | k = 2800; 31 | 32 | while (k > 0) { 33 | 34 | d = 0; 35 | 36 | i = k; 37 | while (i > 0) { 38 | d = d * i; 39 | d = d + r[i] * 10000; 40 | b = 2 * i - 1; 41 | 42 | r[i] = d % b; 43 | d = d / b; 44 | i = i-1; 45 | } 46 | 47 | putchar('0' + (c + d / 10000) / 1000 % 10); 48 | putchar('0' + (c + d / 10000) / 100 % 10); 49 | putchar('0' + (c + d / 10000) / 10 % 10); 50 | putchar('0' + (c + d / 10000) % 10); 51 | c = d % 10000; 52 | 53 | k = k - 14; 54 | } 55 | 56 | putchar('\n'); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /make-artifact.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Prepare artifact zip archive 4 | # 5 | # It includes 6 | # - artifact.pdf: This file 7 | # - pnut-image.tar.gz: A docker image containing pnut and its dependencies 8 | # - pnut/: pnut's source code 9 | # - pnut.sh/: Accompanying website's source code 10 | 11 | set -e -u 12 | 13 | ZIP_DIR=artifact 14 | ZIP_FILE=artifact.zip 15 | DOCKER_IMAGE_TAG=pnut-artifact 16 | 17 | # Create zip directory 18 | rm -rf "$ZIP_DIR" 19 | mkdir -p "$ZIP_DIR" 20 | 21 | pandoc artifact.md -o "$ZIP_DIR/artifact.pdf" 22 | 23 | # Build docker image 24 | docker build . \ 25 | -t "$DOCKER_IMAGE_TAG" \ 26 | --build-arg PNUT_SOURCE=clone \ 27 | --platform linux/amd64 \ 28 | --no-cache 29 | 30 | # Export it 31 | docker save "$DOCKER_IMAGE_TAG" | gzip > "$ZIP_DIR/$DOCKER_IMAGE_TAG-image.tar.gz" 32 | 33 | # Copy pnut source code 34 | git clone https://github.com/udem-dlteam/pnut.git --depth 1 "./$ZIP_DIR/pnut" 35 | 36 | # Copy website source code 37 | git clone https://github.com/udem-dlteam/pnut.sh --depth 1 "./$ZIP_DIR/pnut-website" 38 | 39 | # Create zip archive 40 | zip -r -q "$ZIP_FILE" "$ZIP_DIR" 41 | 42 | echo "Artifact zip archive created: $ZIP_FILE" 43 | -------------------------------------------------------------------------------- /make-sh-runtime.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef int bool; 4 | #define true 1 5 | #define false 0 6 | 7 | void putstr(char* s) { 8 | while (*s) putchar(*s++); 9 | } 10 | 11 | // Runtime configuration 12 | #define RT_FREE_UNSETS_VARS 13 | #define RT_INIT_GLOBALS 14 | #define RT_COMPACT_not 15 | 16 | #define INCLUDE_ALL_RUNTIME 17 | 18 | #include "sh-runtime.c" 19 | 20 | int main() { 21 | produce_runtime(); 22 | } 23 | -------------------------------------------------------------------------------- /pnut-lib.c: -------------------------------------------------------------------------------- 1 | // Used for the pnut.sh website. 2 | 3 | #define SUPPORT_INCLUDE 4 | 5 | #include "pnut.c" 6 | 7 | void compile(char* file) { 8 | 9 | int i; 10 | ast decl; 11 | 12 | init_ident_table(); 13 | 14 | init_pnut_macros(); 15 | 16 | include_file(file, 0); 17 | 18 | codegen_begin(); 19 | 20 | ch = '\n'; 21 | get_tok(); 22 | 23 | while (tok != EOF) { 24 | decl = parse_definition(0); 25 | codegen_glo_decl(decl); 26 | } 27 | 28 | codegen_end(); 29 | } 30 | -------------------------------------------------------------------------------- /portable_libc/include/crt1.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRT1_H 2 | #define _CRT1_H 3 | 4 | void _exit(int status); 5 | int _read(int fd, void *buf, int count); 6 | int _write(int fd, void *buf, int count); 7 | int _open(const char *pathname, int flags, int mode); 8 | int _close(int fd); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /portable_libc/include/crti.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRTi_H 2 | #define _CRTi_H 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /portable_libc/include/ctype.h: -------------------------------------------------------------------------------- 1 | #ifndef _CTYPE_H 2 | #define _CTYPE_H 3 | 4 | int isdigit(int c); 5 | int isxdigit(int c); 6 | int isnumber(int c, int base); 7 | int islower(int c); 8 | int isupper(int c); 9 | int isalpha(int c); 10 | int isalnum(int c); 11 | int tolower(int c); 12 | int toupper(int c); 13 | int isascii(int c); 14 | int iscntrl(int c); 15 | int isgraph(int c); 16 | int isprint(int c); 17 | int isspace(int c); 18 | int ispunct(int c); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /portable_libc/include/math.h: -------------------------------------------------------------------------------- 1 | #ifndef _MATH_H 2 | #define _MATH_H 3 | 4 | #ifndef PNUT_CC 5 | 6 | double ldexp(double x, int exp); 7 | 8 | #endif 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /portable_libc/include/setjmp.h: -------------------------------------------------------------------------------- 1 | #ifndef _SETJMP_H 2 | #define _SETJMP_H 3 | 4 | #define jmp_buf int 5 | 6 | int setjmp(jmp_buf env); 7 | void longjmp(jmp_buf env, int val); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /portable_libc/include/signal.h: -------------------------------------------------------------------------------- 1 | #ifndef _SIGNAL_H 2 | #define _SIGNAL_H 3 | 4 | struct sigaction { 5 | int dummy; 6 | }; 7 | 8 | typedef int sigset_t; 9 | 10 | int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 11 | int sigemptyset(sigset_t *set); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /portable_libc/include/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDARG_H 2 | #define _STDARG_H 3 | 4 | #ifdef PNUT_CC 5 | 6 | #define VAR_ARGS , VA_LIST 7 | 8 | #define va_list int 9 | 10 | #define va_start(ap,last) ap = VA_LIST 11 | #define va_arg(ap,type) ap 12 | #define va_end(ap) ap=ap 13 | 14 | #else 15 | 16 | #define VAR_ARGS , ... 17 | 18 | #ifdef TCC 19 | 20 | typedef char *va_list; 21 | 22 | #define va_ptr_size (sizeof(void *)) 23 | #define va_word_align(x) (((x)+va_ptr_size-1)&~(va_ptr_size-1)) 24 | 25 | #define va_start(ap,last) ap = ((char *)&(last)) + va_word_align(sizeof(last)) 26 | #define va_arg(ap,type) (ap += va_word_align(sizeof(type)), *(type *)(ap - va_word_align(sizeof(type)))) 27 | #define va_end(ap) 28 | 29 | #else 30 | 31 | #undef _STDARG_H 32 | #include 33 | 34 | #endif 35 | 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /portable_libc/include/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDIO_H 2 | #define _STDIO_H 3 | 4 | #include "sys/types.h" 5 | #include "stdarg.h" 6 | 7 | #ifdef USE_STRUCT 8 | 9 | typedef struct { 10 | int fd; 11 | char buf[1]; 12 | char *string_output_buf; 13 | size_t string_output_buf_size; 14 | size_t string_output_len; 15 | } FILE; 16 | 17 | #else 18 | 19 | typedef int FILE; 20 | 21 | #endif 22 | 23 | #ifdef PNUT_CC 24 | 25 | FILE *stdin; 26 | FILE *stdout; 27 | FILE *stderr; 28 | 29 | #else 30 | 31 | extern FILE *stdin; 32 | extern FILE *stdout; 33 | extern FILE *stderr; 34 | 35 | #endif 36 | 37 | FILE *fopen(const char *pathname, const char *mode); 38 | FILE *fdopen(int fd, const char *mode); 39 | int fclose(FILE *stream); 40 | 41 | int fputc(int c, FILE *stream); 42 | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 43 | int fputs(const char *s, FILE *stream); 44 | int puts(const char *s); 45 | 46 | size_t fread(void *buffer, size_t size, size_t count, FILE *stream); 47 | int fseek( FILE* stream, long offset, int origin ); 48 | long ftell( FILE* stream ); 49 | int remove(const char *_Filename); 50 | 51 | int vfprintf(FILE *stream, const char *format, va_list ap); 52 | int fprintf(FILE *stream, const char *format VAR_ARGS); 53 | int printf(const char *format VAR_ARGS); 54 | 55 | int vsnprintf(char *str, size_t size, const char *format, va_list ap); 56 | int snprintf(char *str, size_t size, const char *format VAR_ARGS); 57 | int sprintf(char *str, const char *format VAR_ARGS); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /portable_libc/include/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDLIB_H 2 | #define _STDLIB_H 3 | 4 | #include "sys/types.h" 5 | 6 | void *malloc(size_t size); 7 | void free(void *ptr); 8 | void *realloc(void *ptr, size_t size); 9 | 10 | #ifndef PNUT_CC 11 | double strtod(const char *str, char **endptr); 12 | float strtof(const char *str, char **endptr); 13 | long double strtold(const char *str, char **endptr); 14 | #endif 15 | 16 | long int strtol(const char *str, char **endptr, int base); 17 | int atoi(const char *str); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /portable_libc/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H 2 | 3 | #include "sys/types.h" 4 | 5 | void *memset(void *dest, int c, size_t n); 6 | void *memcpy(void *dest, const void *src, size_t n); 7 | void *memmove(void *dest, const void *src, size_t n); 8 | int memcmp(const void *vl, const void *vr, size_t n); 9 | 10 | size_t strlen(const char *s); 11 | char *strcpy(char *dest, const char *src); 12 | char *strcat(char *dest, const char *src); 13 | char *strchr(const char *s, int c); 14 | char *strrchr(const char *s, int c); 15 | int strcmp(const char *l, const char *r); 16 | 17 | char *strerror(int errnum); 18 | int strncmp(const char *s1, const char *s2, size_t n); 19 | char *strpbrk(const char *dest, const char *breakset); 20 | char *strstr (char *__haystack, char *__needle); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /portable_libc/include/sys/time.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_TIME_H 2 | #define _SYS_TIME_H 3 | 4 | struct timeval { 5 | int tv_sec; 6 | int tv_usec; 7 | }; 8 | 9 | struct timezone { 10 | int tz_minuteswest; 11 | int tz_dsttime; 12 | }; 13 | 14 | int gettimeofday(struct timeval *tv, struct timezone *tz); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /portable_libc/include/sys/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_TYPES_H 2 | #define _SYS_TYPES_H 3 | 4 | #ifdef PNUT_CC 5 | 6 | typedef int ssize_t; 7 | typedef int size_t; 8 | typedef int off_t; 9 | 10 | #else 11 | 12 | typedef long ssize_t; 13 | typedef unsigned long size_t; 14 | typedef long long off_t; 15 | 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /portable_libc/include/unistd.h: -------------------------------------------------------------------------------- 1 | #ifndef _UNISTD_H 2 | #define _UNISTD_H 3 | 4 | #include "sys/types.h" 5 | 6 | typedef int mode_t; 7 | 8 | void exit(int status); 9 | 10 | ssize_t read(int fd, void *buf, size_t count); 11 | ssize_t write(int fd, void *buf, size_t count); 12 | 13 | int open(const char *pathname, int flags, mode_t mode); 14 | int close(int fd); 15 | 16 | off_t lseek(int fd, off_t offset, int whence); 17 | int unlink(const char *pathname); 18 | 19 | char *getcwd(char *buf, size_t size); 20 | int execvp(const char *__file, char **__argv); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /portable_libc/makefile: -------------------------------------------------------------------------------- 1 | all: test 2 | 3 | .SUFFIXES: 4 | 5 | #CC=clang -Wno-incompatible-pointer-types-discards-qualifiers 6 | CC=gcc-13 -Wno-discarded-qualifiers 7 | TCC=tcc -nostdlib 8 | #TCC_VERSION=08a4c52de39b202f02d1ec525c64336d11ad9ccf 9 | #TCC_VERSION=1b57560502d04cbc2e410a960d965765d7f3d635 10 | #TCC=/part/01/feeley/tcc/builds/${TCC_VERSION}/tinycc/tcc 11 | 12 | #test: test_with_gcc test_with_gcc_using_portable_libc test_with_tcc_using_portable_libc test_with_pnut_using_portable_libc 13 | test: test_with_gcc test_with_gcc_using_portable_libc test_with_pnut_using_portable_libc 14 | 15 | test_with_gcc: 16 | @echo ======================== gcc 17 | ${CC} test.c 18 | ./a.out abcdef ; echo $$? 19 | 20 | test_with_gcc_using_portable_libc: 21 | @echo ======================== gcc with portable_libc 22 | cat src/crt1.c src/crti.c portable_libc.c test.c > test-with-libc.c 23 | ${CC} -DUSE_PORTABLE_LIBC -I. -nostdlib -lSystem test-with-libc.c 24 | ./a.out abcdef ; echo $$? 25 | 26 | test_with_tcc_using_portable_libc: 27 | @echo ======================== tcc with portable_libc 28 | cat src/crt1.c src/crti.c portable_libc.c test.c > test-with-libc.c 29 | ${TCC} -m32 -DUSE_PORTABLE_LIBC -I. -static test-with-libc.c 30 | ./a.out abcdef ; echo $$? 31 | 32 | test_with_pnut_using_portable_libc: 33 | @echo ======================== pnut with portable_libc 34 | cat src/crt1.c src/crti.c portable_libc.c test.c > test-with-libc.c 35 | ksh ../build/pnut-sh.sh -DUSE_PORTABLE_LIBC test-with-libc.c > test.sh 36 | ksh test.sh abcdef ; echo $$? 37 | 38 | clean: 39 | rm -f a.out test.sh test-with-libc.c 40 | -------------------------------------------------------------------------------- /portable_libc/portable_libc.c: -------------------------------------------------------------------------------- 1 | #include "src/ctype.c" 2 | #include "src/string.c" 3 | #include "src/stdlib.c" 4 | #include "src/stdio.c" 5 | #include "src/setjmp.c" 6 | #include "src/signal.c" 7 | #include "src/time.c" 8 | #include "src/math.c" 9 | #include "src/unistd.c" 10 | -------------------------------------------------------------------------------- /portable_libc/src/crti.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/portable_libc/src/crti.c -------------------------------------------------------------------------------- /portable_libc/src/ctype.c: -------------------------------------------------------------------------------- 1 | #include "include/ctype.h" 2 | 3 | int isdigit(int c) { 4 | return c >= '0' && c <= '9'; 5 | } 6 | 7 | int isxdigit(int c) { 8 | return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); 9 | } 10 | 11 | int isnumber(int c, int base) { 12 | if (c >= '0') { 13 | if (base == 2) 14 | return c <= '1'; 15 | if (base == 8) 16 | return c <= '7'; 17 | if (base == 10) 18 | return c <= '9'; 19 | } 20 | return isxdigit(c); 21 | } 22 | 23 | int islower(int c) { 24 | return c >= 'a' && c <= 'z'; 25 | } 26 | 27 | int isupper(int c) { 28 | return c >= 'A' && c <= 'Z'; 29 | } 30 | 31 | int isalpha(int c) { 32 | return islower(c) | isupper(c); 33 | } 34 | 35 | int isalnum(int c) { 36 | return isdigit(c) | isalpha(c); 37 | } 38 | 39 | int tolower(int c) { 40 | if (isupper(c)) 41 | c += 'a' - 'A'; 42 | return c; 43 | } 44 | 45 | int toupper(int c) { 46 | if (islower(c)) 47 | c += 'A' - 'a'; 48 | return c; 49 | } 50 | 51 | int isascii(int c) { 52 | return c >= 0 && c <= 127; 53 | } 54 | 55 | int iscntrl(int c) { 56 | return c >= 0 && c < 32; 57 | } 58 | 59 | int isgraph(int c) { 60 | return c > 32 && c < 127; 61 | } 62 | 63 | int isprint(int c) { 64 | return c >= 32 && c < 127; 65 | } 66 | 67 | int isspace(int c) { 68 | return (c > ' ') ? 0 : (c == ' ' || c == '\n' || c == '\t' || c == '\v' || c == '\f' || c == '\r'); 69 | } 70 | 71 | int ispunct(int c) { 72 | return isprint(c) & !isspace(c) & !isalnum(c); 73 | } 74 | -------------------------------------------------------------------------------- /portable_libc/src/math.c: -------------------------------------------------------------------------------- 1 | #include "include/math.h" 2 | 3 | #ifndef PNUT_CC 4 | 5 | double ldexp(double x, int exp) { 6 | return 0.0; /*TODO*/ 7 | } 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /portable_libc/src/setjmp.c: -------------------------------------------------------------------------------- 1 | #include "include/setjmp.h" 2 | 3 | int setjmp(jmp_buf env) { 4 | return 0; 5 | } 6 | 7 | void longjmp(jmp_buf env, int val) { 8 | } 9 | -------------------------------------------------------------------------------- /portable_libc/src/signal.c: -------------------------------------------------------------------------------- 1 | #include "include/signal.h" 2 | 3 | #ifdef TODO 4 | 5 | int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { 6 | return 0; /*TODO*/ 7 | } 8 | 9 | int sigemptyset(sigset_t *set) { 10 | return 0; /*TODO*/ 11 | } 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /portable_libc/src/time.c: -------------------------------------------------------------------------------- 1 | #include "include/sys/time.h" 2 | 3 | int gettimeofday(struct timeval *tv, struct timezone *tz) { 4 | #ifndef PNUT_CC 5 | tv->tv_sec = 0; 6 | tv->tv_usec = 0; 7 | #endif 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /portable_libc/src/unistd.c: -------------------------------------------------------------------------------- 1 | #include "include/unistd.h" 2 | #include "include/crt1.h" 3 | 4 | /* These are assumed to be builtin 5 | 6 | void exit(int status); 7 | ssize_t read(int fd, void *buf, size_t count); 8 | ssize_t write(int fd, void *buf, size_t count); 9 | int open(const char *pathname, int flags, mode_t mode); 10 | int close(int fd); 11 | off_t lseek(int fd, off_t offset, int whence); 12 | int unlink(const char *pathname); 13 | 14 | */ 15 | 16 | #ifdef PNUT_CC 17 | 18 | char *getcwd(char *buf, size_t size) { 19 | /* 20 | if (buf == 0) 21 | buf = __getcwd_buf; 22 | if (buf == 0) 23 | { 24 | __getcwd_buf = malloc (PATH_MAX); 25 | buf = __getcwd_buf; 26 | } 27 | return _getcwd (buf, size); 28 | */ 29 | return 0; /*TODO*/ 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /run-pnut-variant.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | set -e 4 | 5 | : ${PNUT_OPTIONS:=} # Default to empty options 6 | 7 | TEMP_DIR="build" 8 | PNUT_SH_OPTIONS="$PNUT_OPTIONS -DRT_NO_INIT_GLOBALS -Dsh" 9 | PNUT_SH_OPTIONS_FAST="$PNUT_SH_OPTIONS -DSH_SAVE_VARS_WITH_SET -DOPTIMIZE_CONSTANT_PARAM" 10 | PNUT_VARIANT_OPTIONS="" 11 | 12 | run_with_shell() { 13 | 14 | echo "Running $variant with $1" 15 | 16 | env time $1 "$TEMP_DIR/pnut-$variant.sh" $PNUT_SH_OPTIONS "pnut.c" > "$TEMP_DIR/pnut-$variant.output" 17 | } 18 | 19 | # Parse the arguments 20 | shell="$SHELL" # Use current shell as the default. "all" to test all shells. 21 | variant="" 22 | 23 | while [ $# -gt 0 ]; do 24 | case $1 in 25 | --shell) shell="$2"; shift 2 ;; 26 | --fast) PNUT_SH_OPTIONS="$PNUT_SH_OPTIONS_FAST"; shift 1 ;; 27 | --reader) PNUT_VARIANT_OPTIONS="-DDEBUG_GETCHAR -Ush"; variant=${1#--}; shift 1 ;; 28 | --tokenizer) PNUT_VARIANT_OPTIONS="-DDEBUG_CPP -Ush"; variant=${1#--}; shift 1 ;; 29 | --parser) PNUT_VARIANT_OPTIONS="-DDEBUG_PARSER -Ush"; variant=${1#--}; shift 1 ;; 30 | *) echo "Unknown option: $1"; exit 1;; 31 | esac 32 | done 33 | 34 | pnut_exec="$TEMP_DIR/pnut-$variant" 35 | 36 | if [ ! -d "$TEMP_DIR" ]; then mkdir "$TEMP_DIR"; fi 37 | 38 | gcc -o "$pnut_exec" $PNUT_SH_OPTIONS pnut.c 39 | $pnut_exec $PNUT_SH_OPTIONS $PNUT_VARIANT_OPTIONS "pnut.c" > "$TEMP_DIR/pnut-$variant.sh" 40 | 41 | if [ "$shell" = "all" ]; then 42 | set +e # Don't exit on error because we want to test all shells. 43 | run_with_shell "dash" 44 | run_with_shell "ksh" 45 | run_with_shell "bash" 46 | run_with_shell "yash" 47 | run_with_shell "mksh" 48 | run_with_shell "zsh" 49 | else 50 | run_with_shell "$shell" 51 | fi 52 | -------------------------------------------------------------------------------- /shell-benchmarks/assignment-in-arith.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate the different ways to assign variables using arithmetic expansion. 3 | 4 | if [ $# -lt 1 ]; then 5 | set ksh dash bash zsh 6 | fi 7 | 8 | while [ $# -gt 0 ]; do 9 | echo "\n$1: Assignment outside without arithmetic expansion" 10 | time $1 -c 'acc=""; i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); acc=$acc; done' 11 | 12 | echo "\n$1: Assignment outside without arithmetic expansion with quotes" 13 | time $1 -c 'acc=""; i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); acc="$acc"; done' 14 | 15 | echo "\n$1: Assignment outside of \$(())" 16 | time $1 -c 'acc=""; i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); acc=$((acc + 1)); done' 17 | 18 | echo "\n$1: Assignment outside of \$(()) with quotes" 19 | time $1 -c 'acc=""; i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); acc="$((acc + 1))"; done' 20 | 21 | echo "\n$1: Assignment in \$(())" 22 | time $1 -c 'acc=""; i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); : $((acc = acc + 1)); done' 23 | shift 24 | done 25 | -------------------------------------------------------------------------------- /shell-benchmarks/bench-puts.c: -------------------------------------------------------------------------------- 1 | int atoi(const char* str) { 2 | int res = 0; 3 | for (;*str != '\0'; ++str) { 4 | res = res * 10 + *str - '0'; 5 | } 6 | return res; 7 | } 8 | 9 | char c; 10 | void puts_fast(char *str) { 11 | while (c = *str) { 12 | putchar(c); 13 | str += 1; 14 | } 15 | } 16 | 17 | void puts(char *str) { 18 | while (*str) { 19 | putchar(*str); 20 | str += 1; 21 | } 22 | } 23 | 24 | void main(int argc, char** argv) { 25 | int count = 1; 26 | char *str; 27 | if (argc != 4) { 28 | puts("Usage: bench-puts \n"); 29 | exit(1); 30 | } 31 | str = argv[1]; 32 | count = atoi(argv[2]); 33 | if (argv[3][0] == 'f') { 34 | while (count--) { 35 | puts_fast(str); 36 | } 37 | } else { 38 | while (count--) { 39 | puts(str); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /shell-benchmarks/char-to-int-conversion/subshell.sh: -------------------------------------------------------------------------------- 1 | decode_chars() { 2 | while [ $# -gt 0 ]; do 3 | code=$(LC_CTYPE=C printf "%d" "'$1") 4 | shift 5 | done 6 | } 7 | 8 | 9 | if [ $# -ne 2 ]; then 10 | echo "Usage: $0 " 11 | exit 1 12 | fi 13 | 14 | env_size=$1 15 | iterations=$2 16 | 17 | # Add some variables to the environment so subshells take longer to start 18 | i=0 19 | while [ $i -lt $env_size ]; do 20 | i=$((i+1)) 21 | : $((acc_$i = 1)) 22 | done 23 | 24 | i=0 25 | while [ $i -lt $iterations ]; do 26 | decode_chars 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ' ' '!' '#' '$' '%' '&' '(' ')' '*' '+' ',' '-' '.' '/' ':' ';' '<' '=' '>' '?' '@' '[' ']' '^' '_' '{' '|' '}' '~' 27 | i=$((i+1)) 28 | done 29 | -------------------------------------------------------------------------------- /shell-benchmarks/dynamic-variables-code.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | i=0 4 | 5 | while [ $i -lt $SIZE ]; do 6 | : $(( _$i = i )) 7 | : $(( i += 1 )) 8 | done 9 | 10 | # echo "i: $i, _$i $((_$((i - 1))))" 11 | 12 | sum() { 13 | t0=$(gdate +%s%6N) 14 | j=0 15 | sum=0 16 | 17 | while [ $j -lt 100 ]; do 18 | i=0 19 | while [ $i -lt 100 ]; do 20 | : $(( sum += _$i )) 21 | : $(( _$i = _$i + 1 )) 22 | : $(( i += 1 )) 23 | done 24 | : $(( j += 1 )) 25 | done 26 | t1=$(gdate +%s%6N) 27 | echo "$SIZE:$(( t1 - t0 ))" 28 | } 29 | 30 | sum 31 | sum 32 | sum 33 | sum 34 | sum 35 | sum 36 | sum 37 | sum 38 | sum 39 | sum 40 | -------------------------------------------------------------------------------- /shell-benchmarks/dynamic-variables.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate the time to create dynamic variables. 3 | # Some shells use a hash table to store variables, and others a linked list, this script will help categorize them. 4 | # Shells with hash table will have a NlogN relationship between time and the number of variables (N) 5 | # Shells with linked list will have a N^2 relationship between time and the number of variables (N) 6 | 7 | if [ $# -lt 1 ]; then 8 | set ksh dash bash zsh 9 | fi 10 | 11 | while [ $# -gt 0 ]; do 12 | echo "\n$1: 10000 variables" 13 | time $1 -c 'i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); : $((acc_$i = 1)); done' 14 | 15 | echo "\n$1: 100000 variables" 16 | time $1 -c 'i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); : $((acc_$i = 1)); done' 17 | 18 | echo "\n$1: 500000 variables" 19 | time $1 -c 'i=0 ; while [ $i -lt 500000 ]; do i=$((i+1)); : $((acc_$i = 1)); done' 20 | shift 21 | done 22 | -------------------------------------------------------------------------------- /shell-benchmarks/echo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate the impact of quoting arguments to functions. 3 | 4 | if [ $# -lt 1 ]; then 5 | set ksh dash bash zsh 6 | fi 7 | 8 | while [ $# -gt 0 ]; do 9 | echo "\n$1: echo without quotes" 10 | time $1 -c 'c="abc"; i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); echo $c; done > /dev/null' 11 | 12 | echo "\n$1: echo with quotes" 13 | time $1 -c 'c="abc"; i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); echo "$c"; done > /dev/null' 14 | 15 | echo "\n$1: sum without quotes" 16 | time $1 -c 'fun() { return $#; }; acc=0; c="abc"; i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); fun $acc; done' 17 | 18 | echo "\n$1: sum with quotes" 19 | time $1 -c 'fun() { return $#; }; acc=0; c="abc"; i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); fun "$acc"; done' 20 | shift 21 | done 22 | -------------------------------------------------------------------------------- /shell-benchmarks/get_char.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate impact of fast buffer optimization 3 | 4 | if [ $# -lt 1 ]; then 5 | set ksh dash bash zsh 6 | # Dash cannot read the file for some reason 7 | fi 8 | 9 | while [ $# -gt 0 ]; do 10 | echo "\n$1 fast (empty env):" 11 | $1 -c 'shell-benchmarks/get_char_code_fast.sh 0 24000 ./shell-benchmarks/get_char_data.txt' 12 | 13 | echo "\n$1 fast (10k env):" 14 | $1 -c 'shell-benchmarks/get_char_code_fast.sh 10000 24000 ./shell-benchmarks/get_char_data.txt' 15 | 16 | echo "\n$1 fast (100k env):" 17 | $1 -c 'shell-benchmarks/get_char_code_fast.sh 100000 24000 ./shell-benchmarks/get_char_data.txt' 18 | 19 | echo "\n$1 fast (500k env):" 20 | $1 -c 'shell-benchmarks/get_char_code_fast.sh 500000 24000 ./shell-benchmarks/get_char_data.txt' 21 | 22 | echo "\n$1 slow (empty env):" 23 | $1 -c 'shell-benchmarks/get_char_code_slow.sh 0 24000 ./shell-benchmarks/get_char_data.txt' 24 | 25 | echo "\n$1 slow (10k env):" 26 | $1 -c 'shell-benchmarks/get_char_code_slow.sh 10000 24000 ./shell-benchmarks/get_char_data.txt' 27 | 28 | echo "\n$1 slow (100k env):" 29 | $1 -c 'shell-benchmarks/get_char_code_slow.sh 100000 24000 ./shell-benchmarks/get_char_data.txt' 30 | 31 | echo "\n$1 slow (500k env):" 32 | $1 -c 'shell-benchmarks/get_char_code_slow.sh 500000 24000 ./shell-benchmarks/get_char_data.txt' 33 | shift 34 | done 35 | -------------------------------------------------------------------------------- /shell-benchmarks/long-line-1000.txt: -------------------------------------------------------------------------------- 1 | abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy -------------------------------------------------------------------------------- /shell-benchmarks/num-comparison.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate impact of fast buffer optimization 3 | 4 | if [ $# -lt 1 ]; then 5 | set ksh dash bash zsh 6 | fi 7 | 8 | while [ $# -gt 0 ]; do 9 | echo "\n$1: Without quotes" 10 | time $1 -c 'acc=""; c="abc"; i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); done' 11 | 12 | echo "\n$1: With quotes" 13 | time $1 -c 'acc=""; c="abc"; i=0 ; while [ "$i" -lt 10000 ]; do i=$((i+1)); done' 14 | shift 15 | done 16 | -------------------------------------------------------------------------------- /shell-benchmarks/run-bench-puts.sh: -------------------------------------------------------------------------------- 1 | str="VERY LONG STRING TO REDUCE THE OVERHEAD OF EVERYTHING ELSE. DID YOU KNOW THAT THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG?\n" 2 | 3 | test_with() { 4 | hyperfine "$1 shell-benchmarks/bench-puts.sh '$str' 1000 $2 > /dev/null" 5 | } 6 | 7 | test_with "bash" "slow" 8 | test_with "bash" "fast" 9 | 10 | test_with "dash" "slow" 11 | test_with "dash" "fast" 12 | 13 | test_with "ksh" "slow" 14 | test_with "ksh" "fast" 15 | 16 | test_with "zsh" "slow" 17 | test_with "zsh" "fast" 18 | -------------------------------------------------------------------------------- /shell-benchmarks/string-concat-quoting.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate performance of concatenating strings. 3 | 4 | if [ $# -lt 1 ]; then 5 | set ksh dash bash zsh 6 | fi 7 | 8 | while [ $# -gt 0 ]; do 9 | echo "\n$1: Without quotes" 10 | time $1 -c 'acc=""; c="abc"; i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); acc=$acc$c; done' 11 | 12 | echo "\n$1: With quotes" 13 | time $1 -c 'acc=""; c="abc"; i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); acc="$acc$c"; done' 14 | shift 15 | done 16 | -------------------------------------------------------------------------------- /shell-benchmarks/string-pack-unpack-benchmark.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate the performance of packing and unpacking a Shell string to the heap. 3 | 4 | if [ $# -lt 1 ]; then 5 | set ksh dash bash zsh 6 | fi 7 | 8 | while [ $# -gt 0 ]; do 9 | echo "$1:" 10 | time $1 -c 'source shell-benchmarks/string-pack-unpack-benchmark-code.sh' 11 | shift 12 | done 13 | -------------------------------------------------------------------------------- /shell-benchmarks/variable-assignment.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate the impact of quoting arguments in variable assignment. 3 | 4 | if [ $# -lt 1 ]; then 5 | set ksh dash bash zsh 6 | fi 7 | 8 | while [ $# -gt 0 ]; do 9 | echo "\n$1: Without quotes" 10 | time $1 -c 'acc=""; c="abc"; i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); acc=$c; done' 11 | 12 | echo "\n$1: With quotes" 13 | time $1 -c 'acc=""; c="abc"; i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); acc="$c"; done' 14 | shift 15 | done 16 | -------------------------------------------------------------------------------- /shell-benchmarks/variable_name_length.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Evaluate the impact of name length on performance. 3 | 4 | # if [ $# -lt 1 ]; then 5 | # set ksh dash bash zsh 6 | # fi 7 | 8 | # while [ $# -gt 0 ]; do 9 | # echo "\n$1: 10000 variables" 10 | # time $1 -c 'i=0 ; while [ $i -lt 10000 ]; do i=$((i+1)); : $((acc_$i = 1)); done' 11 | 12 | # echo "\n$1: 100000 variables" 13 | # time $1 -c 'i=0 ; while [ $i -lt 100000 ]; do i=$((i+1)); : $((acc_$i = 1)); done' 14 | 15 | # echo "\n$1: 500000 variables" 16 | # time $1 -c 'i=0 ; while [ $i -lt 500000 ]; do i=$((i+1)); : $((acc_$i = 1)); done' 17 | # shift 18 | # done 19 | 20 | SIZE=100000 21 | HEAP=52233720368547 22 | PREFIX=__________ 23 | 24 | alloc_array() { 25 | i=0 26 | while [ $i -lt $SIZE ]; do 27 | : $((_$((HEAP + i)) = i)) 28 | i=$((i+1)) 29 | done 30 | } 31 | 32 | sum_array() { 33 | i=0 34 | sum=0 35 | while [ $i -lt $SIZE ]; do 36 | i=$((i+1)) 37 | : $((sum += _$((HEAP + i)))) 38 | done 39 | # echo $sum 40 | } 41 | 42 | alloc_array 43 | sum_array 44 | -------------------------------------------------------------------------------- /shell-playground/adding_new_$_variables.sh: -------------------------------------------------------------------------------- 1 | # What happens when you add new $ variables in a function? 2 | local_scope2() { 3 | a=$1 4 | b=$2 5 | c=$3 6 | echo "Local 2: $a $b $c" 7 | set $((a + 1)) $((b + 1)) $((c + 1)) 8 | set 4 5 6 7 8 9 9 | echo "Local 2: $1 $2 $3 $4 $5 $6" 10 | } 11 | 12 | local_scope1() { 13 | a=$1 14 | b=$2 15 | c=$3 16 | local_scope2 1 2 3 17 | a=$1 18 | b=$2 19 | c=$3 20 | d=$4 21 | e=$5 22 | echo "Local 1: $a $b $c $d $e" 23 | } 24 | 25 | local_scope1 7 8 9 26 | -------------------------------------------------------------------------------- /shell-playground/arity.sh: -------------------------------------------------------------------------------- 1 | # Test if empty arguments are counted in #$ when unquoted 2 | abc= 3 | def=123 4 | 5 | arity_test() { 6 | echo "Arity: $#" 7 | } 8 | 9 | echo "Without quotes" 10 | arity_test $abc $def 11 | echo "With quotes" 12 | arity_test "$abc" "$def" 13 | -------------------------------------------------------------------------------- /shell-playground/is_defined.sh: -------------------------------------------------------------------------------- 1 | # Note: Note POSIX compliant and does not work in dash. 2 | # This code is only used in _show_heap to not show undefined memory locations. 3 | 4 | _1000=1 5 | # _1001=1 6 | show_heap_ix=1000 7 | 8 | is_memory_addr_defined() { 9 | location="_$1" 10 | eval "if [[ -z \${$location+x} ]]; then undefined=1; else undefined=0; fi" 11 | echo "is undefined? $undefined" 12 | } 13 | 14 | is_memory_addr_defined $show_heap_ix # Show 1 15 | is_memory_addr_defined $((show_heap_ix + 1)) # Show 0 16 | -------------------------------------------------------------------------------- /shell-playground/local_var_as_param.sh: -------------------------------------------------------------------------------- 1 | # Are $1, $2, $3 local to the function? 2 | fun_1() { 3 | echo "fun_1 before call: $1 $2 $3" 4 | fun_2 4 5 6 5 | echo "fun_1 after call: $1 $2 $3" 6 | } 7 | 8 | fun_2() { 9 | echo "fun_2: $1 $2 $3" 10 | } 11 | 12 | _identity() { 13 | : $(( _x = "$1" )) 14 | : $(( _0result = _x )) 15 | } 16 | 17 | fun_1 1 2 3 18 | -------------------------------------------------------------------------------- /shell-playground/multi-expression-posix.sh: -------------------------------------------------------------------------------- 1 | # Can we put multiple expressions in a $(()) block? Yes! 2 | if : $(( x = 5 )); [ 0 -eq $(( y = 0 )) ]; then 3 | echo "Should execute" 4 | echo "x: $x" 5 | echo "y: $y" 6 | fi 7 | 8 | if : $(( x = 5 )); [ 0 -eq $(( y = 1 )) ]; then 9 | echo "Should not execute" 10 | echo "x: $x" 11 | echo "y: $y" 12 | fi 13 | 14 | x=0 15 | while : $(( x = x + 1 )); [ 3 -ne $(( x - 1 )) ]; do 16 | echo "It even supports post increment" 17 | echo "x: $x" 18 | done 19 | -------------------------------------------------------------------------------- /shell-playground/multi-expression.sh: -------------------------------------------------------------------------------- 1 | # Can we put multiple expressions in a $(()) block? Yes! 2 | if [ 0 -eq $(( x = 5, y = 0 )) ]; then 3 | echo "Should execute" 4 | echo "x: $x" 5 | echo "y: $y" 6 | fi 7 | 8 | if [ 0 -eq $(( x = 5, y = 1 )) ]; then 9 | echo "Should not execute" 10 | echo "x: $x" 11 | echo "y: $y" 12 | fi 13 | 14 | x=0 15 | while [ 3 -ne $(( x = x + 1, x - 1 )) ]; do 16 | echo "It even supports post increment" 17 | echo "x: $x" 18 | done 19 | -------------------------------------------------------------------------------- /shell-playground/print_return.sh: -------------------------------------------------------------------------------- 1 | # Test if empty arguments are counted in #$ when unquoted 2 | a=123 3 | 4 | do_something() { 5 | a=456 6 | echo "$a" 7 | } 8 | 9 | b=$(do_something) 10 | echo "a: $a, b: $b" 11 | 12 | # Subshell 13 | ( 14 | do_something 15 | ) 16 | echo "a: $a, b: $b" 17 | 18 | do_something 19 | echo "a: $a, b: $b" 20 | -------------------------------------------------------------------------------- /shell-playground/while_fun_call.sh: -------------------------------------------------------------------------------- 1 | # Can we call a function in a while condition? Yes! 2 | counter=5 3 | 4 | decrement_counter() { 5 | : $(( counter -= 1 )) 6 | } 7 | 8 | while decrement_counter $counter; [ 0 -ne $counter ]; do 9 | echo "While: $counter" 10 | done 11 | 12 | echo "End" 13 | -------------------------------------------------------------------------------- /test-tokenizer.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | TEMP_DIR="build" 4 | PNUT_SH_OPTIONS="-DRT_NO_INIT_GLOBALS -Dsh" 5 | 6 | if [ ! -d "$TEMP_DIR" ]; then mkdir "$TEMP_DIR"; fi 7 | 8 | gcc -o "$TEMP_DIR/pnut.exe" $PNUT_SH_OPTIONS pnut.c 9 | 10 | # gcc -E -C -P -DPNUT_CC -Dsh pnut.c > "$TEMP_DIR/pnut-after-cpp.c" 11 | 12 | ./$TEMP_DIR/pnut.exe $PNUT_SH_OPTIONS -DDEBUG_GETCHAR -DDEBUG_CPP "pnut.c" > "$TEMP_DIR/pnut-tokenizer.sh" 13 | 14 | bootstrap_with_shell() { 15 | 16 | echo "Tokenizing with $1" 17 | 18 | time $1 "$TEMP_DIR/pnut-tokenizer.sh" $PNUT_SH_OPTIONS "pnut.c" > "$TEMP_DIR/pnut-tokenized.c" 19 | 20 | wc pnut.c "$TEMP_DIR/pnut-tokenizer.sh" "$TEMP_DIR/pnut-tokenized.c" 21 | } 22 | 23 | # Handle runtime options 24 | TEST_ALL_SHELLS=0 25 | 26 | if [ $# -gt 0 ] && [ $1 = "TEST_ALL_SHELLS" ] ; then TEST_ALL_SHELLS=1; shift; fi 27 | 28 | bootstrap_with_shell "ksh" 29 | 30 | if [ $TEST_ALL_SHELLS -ne 0 ]; then 31 | bootstrap_with_shell "dash" 32 | bootstrap_with_shell "bash" 33 | bootstrap_with_shell "zsh" 34 | bootstrap_with_shell "yash" 35 | bootstrap_with_shell "mksh" 36 | fi 37 | -------------------------------------------------------------------------------- /tests/_all/comma.c: -------------------------------------------------------------------------------- 1 | #include 2 | // expect_failure_for: dash 3 | // expect_failure_for: yash 4 | 5 | int a = 1; 6 | int b = 2; 7 | int c = 3; 8 | 9 | int foo(int a) { 10 | return a; 11 | } 12 | 13 | void show_state() { 14 | putchar('0' + a); 15 | putchar('0' + b); 16 | putchar('0' + c); 17 | putchar('\n'); 18 | } 19 | 20 | int main() { 21 | show_state(); 22 | if (foo((a,b))) { 23 | putchar('T'); putchar('\n'); 24 | } 25 | if (foo((a++, b++, ++c)) == 4) { 26 | putchar('T'); putchar('\n'); 27 | } 28 | show_state(); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/_all/comma.golden: -------------------------------------------------------------------------------- 1 | 123 2 | T 3 | T 4 | 234 5 | -------------------------------------------------------------------------------- /tests/_all/compound.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void main() { 4 | if (1) { 5 | // Empty if 6 | } 7 | 8 | if (1) { 9 | { 10 | // Empty compound statement 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/_all/compound.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/compound.golden -------------------------------------------------------------------------------- /tests/_all/do_while.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int factorial(int num) { 4 | int ret = 1; 5 | 6 | do { 7 | ret *= num; 8 | num--; 9 | } while(num > 0); 10 | 11 | return ret; 12 | } 13 | 14 | void main() { 15 | int fac5 = factorial(5); 16 | int fac10 = factorial(10); 17 | 18 | if (fac5 == 120) { 19 | putchar('O'); 20 | } else { 21 | putchar('B'); 22 | } 23 | 24 | if (fac10 == 3628800) { 25 | putchar('O'); 26 | } else { 27 | putchar('B'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/_all/do_while.golden: -------------------------------------------------------------------------------- 1 | OO -------------------------------------------------------------------------------- /tests/_all/enum-tests/enum-suite.golden: -------------------------------------------------------------------------------- 1 | Color: RED 2 | Day: Garfield hates Mondays 3 | Direction: SOUTH 4 | Boolean: TRUE 5 | Large Enum: THIRD 6 | -------------------------------------------------------------------------------- /tests/_all/examples/sha256sum.golden: -------------------------------------------------------------------------------- 1 | 3a40f68bc01b2ae9853ff898b097cfe6b74e558d00d4bb740dbd7b10a171734d tests/_all/examples/sha256sum.c 2 | -------------------------------------------------------------------------------- /tests/_all/for-empty.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int i = 0; 5 | for (;;) { 6 | if (i == 10) { 7 | return 0; 8 | } 9 | putchar('0' + i); 10 | i += 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/_all/for-empty.golden: -------------------------------------------------------------------------------- 1 | 0123456789 -------------------------------------------------------------------------------- /tests/_all/free-malloc-tests/malloc-free-simple-suite.golden: -------------------------------------------------------------------------------- 1 | PASS!:) 2 | -------------------------------------------------------------------------------- /tests/_all/globals.c: -------------------------------------------------------------------------------- 1 | // args: abc def hij 2 | #include 3 | 4 | void putstr(char *str) { 5 | while (*str) { 6 | putchar(*str); 7 | str += 1; 8 | } 9 | } 10 | 11 | void putint_aux(int n) { 12 | if (n <= -10) putint_aux(n / 10); 13 | putchar('0' - (n % 10)); 14 | } 15 | 16 | void putint(int n) { 17 | if (n < 0) { 18 | putchar('-'); 19 | putint_aux(n); 20 | } else { 21 | putint_aux(-n); 22 | } 23 | } 24 | 25 | int arr[10000]; 26 | // Making sure non-word aligned globals are handled correctly. There was a bug 27 | // once where characters were given 1 byte of space, which caused the next 28 | // globals to be misaligned 29 | char c = 0; 30 | 31 | int main(int argc, char **argv) { 32 | int i; 33 | putint(argc); 34 | putstr("\n"); 35 | for (i = 1; i < argc; ++i) { 36 | putstr(argv[i]); 37 | putstr("\n"); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tests/_all/globals.golden: -------------------------------------------------------------------------------- 1 | 4 2 | abc 3 | def 4 | hij 5 | -------------------------------------------------------------------------------- /tests/_all/inline.c: -------------------------------------------------------------------------------- 1 | 2 | // inline keyword is ignored 3 | static inline void foo() { 4 | return; 5 | } 6 | 7 | int main() { 8 | foo(); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /tests/_all/inline.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/inline.golden -------------------------------------------------------------------------------- /tests/_all/input-output/emit-all-chars.c: -------------------------------------------------------------------------------- 1 | // Make sure we can emit all 256 characters. This is to make sure all shells 2 | // can be used to bootstrap the pnut-exe compiler, which requires emitting all 3 | // kind of characters. 4 | 5 | #ifndef PNUT_CC 6 | #include 7 | #endif 8 | 9 | void main() { 10 | int i = 0; 11 | for (; i < 256; i++) { 12 | putchar(i); 13 | } 14 | putchar('\n'); 15 | } 16 | -------------------------------------------------------------------------------- /tests/_all/input-output/emit-all-chars.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/input-output/emit-all-chars.golden -------------------------------------------------------------------------------- /tests/_all/input-output/file-with-newlines.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Skip a few lines 6 | 7 | Line with leading whitespace 8 | 9 | Line with trailing whitespace 10 | 11 | And a line with only whitespace 12 | 13 | 14 | 15 | And leave a few trailing newlines 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/_all/input-output/read-newlines.c: -------------------------------------------------------------------------------- 1 | // Make sure we can read all 256 characters. This is to make sure the utilities 2 | // we compile using pnut-sh can process all kind of files. 3 | // This test is not essential for the bootstrap, but since we'd like to use pnut 4 | // in other contexts, we want to make sure it can handle all characters. 5 | 6 | #ifndef PNUT_CC 7 | #include 8 | #else 9 | typedef int FILE; 10 | #endif 11 | 12 | void main() { 13 | int i = 0; 14 | char c; 15 | FILE *f = fopen("tests/_all/input-output/file-with-newlines.txt", "r"); 16 | while ((c = fgetc(f)) != -1) { 17 | putchar(c); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/_all/input-output/read-newlines.golden: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Skip a few lines 6 | 7 | Line with leading whitespace 8 | 9 | Line with trailing whitespace 10 | 11 | And a line with only whitespace 12 | 13 | 14 | 15 | And leave a few trailing newlines 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/_all/input-output/read-unicode.c: -------------------------------------------------------------------------------- 1 | // Make sure we can read unicode characters. This is to make sure the utilities 2 | // we compile using pnut-sh can process all kind of files. 3 | // This test is not essential for the bootstrap but being able to properly read 4 | // non-ascii characters makes pnut more general. 5 | // 6 | // Yash's IO is a little bit weird and it's not a very popular shell, disabling the test for now. 7 | // expect_failure_for: yash 8 | 9 | #ifndef PNUT_CC 10 | #include 11 | #else 12 | typedef int FILE; 13 | #endif 14 | 15 | void putstr(const char *s) { 16 | while (*s) { 17 | putchar(*s); 18 | s++; 19 | } 20 | } 21 | 22 | void main() { 23 | int i = 0; 24 | char c; 25 | FILE *f = fopen("tests/_all/input-output/unicode.txt", "r"); 26 | putstr("printf? 💣\n"); 27 | while ((c = fgetc(f)) != -1) { 28 | putchar(c); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/_all/input-output/read-unicode.golden: -------------------------------------------------------------------------------- 1 | printf? 💣 2 | accents: éôèà 3 | some emoji: 🥜 4 | -------------------------------------------------------------------------------- /tests/_all/input-output/unicode.txt: -------------------------------------------------------------------------------- 1 | accents: éôèà 2 | some emoji: 🥜 3 | -------------------------------------------------------------------------------- /tests/_all/line_continuation.c: -------------------------------------------------------------------------------- 1 | // comp_pnut_opt: -DSUPPORT_LINE_CONTINUATION 2 | #include 3 | 4 | void putint_aux(int n) { 5 | if (n >= 10) putint_aux(n / 10); 6 | putchar('0' + (n % 10)); 7 | } 8 | 9 | void putint(int n) { 10 | if (n < 0) { 11 | putchar('-'); 12 | putint_aux(-n); 13 | } else { 14 | putint_aux(n); 15 | } 16 | } 17 | 18 | int main() { 19 | 20 | /**/ 21 | int foo = 0; 22 | 23 | /\ 24 | * 25 | */ fo\ 26 | \ 27 | \ 28 | o +\ 29 | = 1\ 30 | \ 31 | 10\ 32 | 200; 33 | 34 | putint(foo); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /tests/_all/line_continuation.golden: -------------------------------------------------------------------------------- 1 | 110200 -------------------------------------------------------------------------------- /tests/_all/logical-negation.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void putstr(char *str) { 4 | while (*str) { 5 | putchar(*str); 6 | str++; 7 | } 8 | } 9 | 10 | void main() { 11 | char *str = "Hello, World!\n"; 12 | if (!str) { // if str is not null 13 | putstr("null\n"); 14 | } else { 15 | putstr(str); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/_all/logical-negation.golden: -------------------------------------------------------------------------------- 1 | Hello, World! 2 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/if/if.golden: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 1 11 | 1 12 | 2 13 | 3 14 | 4 15 | 5 16 | 6 17 | 7 18 | 8 19 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/if/ifdef.c: -------------------------------------------------------------------------------- 1 | // tests for #if* preprocessor directive 2 | 3 | void putdigit(int n) { 4 | putchar('0' + n); 5 | putchar('\n'); 6 | } 7 | 8 | void main() { 9 | #define FOO 10 | #define BAR 11 | 12 | #ifdef FOO 13 | putdigit(1); 14 | #endif 15 | 16 | #ifndef FOO 17 | putdigit(0); 18 | #endif 19 | 20 | #ifdef FOO_not 21 | putdigit(0); 22 | #endif 23 | 24 | #ifndef FOO_not 25 | putdigit(1); 26 | #endif 27 | 28 | #ifdef FOO 29 | putdigit(1); 30 | #ifndef BAR 31 | putdigit(0); 32 | #else 33 | putdigit(1); 34 | #endif 35 | #else 36 | putdigit(0); 37 | #endif 38 | 39 | // ifdef directive 40 | #ifdef FOO 41 | #endif 42 | 43 | #ifdef FOO 44 | #else 45 | #endif 46 | 47 | #ifdef FOO 48 | #ifdef FOO 49 | #ifdef FOO 50 | #ifndef FOO 51 | putdigit(0); 52 | #else 53 | putdigit(1); 54 | #endif 55 | #ifdef FOO 56 | #ifdef FOO 57 | putdigit(1); 58 | #endif 59 | #endif 60 | #endif 61 | #endif 62 | #endif 63 | } 64 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/if/ifdef.golden: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | 1 4 | 1 5 | 1 6 | 1 7 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include-bracket.c: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | // comp_opt: -Iportable_libc/include/ 3 | 4 | #include 5 | 6 | void putint_aux(int n) { 7 | if (n <= -10) putint_aux(n / 10); 8 | putchar('0' - (n % 10)); 9 | } 10 | 11 | void putint(int n) { 12 | if (n < 0) { 13 | putchar('-'); 14 | putint_aux(n); 15 | } else { 16 | putint_aux(-n); 17 | } 18 | 19 | putchar('\n'); 20 | } 21 | 22 | void main() { 23 | putint(stdin); 24 | putint(stdout); 25 | putint(stderr); 26 | } 27 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include-bracket.golden: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include-no-newline.c: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #include // putchar 4 | 5 | #include "include-no-newline.h" 6 | #define INCLUDE 7 | #include "include-no-newline.h" 8 | 9 | void putint_aux(int n) { 10 | if (n <= -10) putint_aux(n / 10); 11 | putchar('0' - (n % 10)); 12 | } 13 | 14 | void putint(int n) { 15 | if (n < 0) { 16 | putchar('-'); 17 | putint_aux(n); 18 | } else { 19 | putint_aux(-n); 20 | } 21 | 22 | putchar('\n'); 23 | } 24 | 25 | void main() { 26 | putint(CONSTANT); 27 | } 28 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include-no-newline.golden: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include-no-newline.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives without trailing newline 2 | 3 | #ifdef INCLUDE 4 | int CONSTANT = 0; 5 | #endif -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include.c: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | // putchar 4 | #include 5 | 6 | #define INCLUDE 7 | #include "include1.h" 8 | 9 | void putint_aux(int n) { 10 | if (n <= -10) putint_aux(n / 10); 11 | putchar('0' - (n % 10)); 12 | } 13 | 14 | void putint(int n) { 15 | if (n < 0) { 16 | putchar('-'); 17 | putint_aux(n); 18 | } else { 19 | putint_aux(-n); 20 | } 21 | 22 | putchar('\n'); 23 | } 24 | 25 | void main() { 26 | putint(CONSTANT1); 27 | putint(CONSTANT2); 28 | putint(CONSTANT3); 29 | putint(CONSTANT4); 30 | putint(CONSTANT5); 31 | putint(CONSTANT6); 32 | } 33 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include.golden: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include1.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "include2.h" 5 | #endif 6 | 7 | int CONSTANT1 = 1; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include2.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "include3.h" 5 | #endif 6 | 7 | int CONSTANT2 = 2; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include3.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "include4.h" 5 | #endif 6 | 7 | int CONSTANT3 = 3; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include4.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "include5.h" 5 | #endif 6 | 7 | int CONSTANT4 = 4; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include5.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "include6.h" 5 | #endif 6 | 7 | int CONSTANT5 = 5; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/include6.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | // No more includes because shells only supports 7 open file descriptors 4 | // #ifdef INCLUDE 5 | // #include "include7.h" 6 | // #endif 7 | 8 | int CONSTANT6 = 6; 9 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/multiple-include.c: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | // putchar 4 | #include 5 | 6 | #include "multiple-include.h" 7 | #include "multiple-include.h" 8 | #include "multiple-include.h" 9 | #include "multiple-include.h" 10 | #include "multiple-include.h" 11 | #include "multiple-include.h" 12 | #include "multiple-include.h" 13 | #include "multiple-include.h" 14 | #include "multiple-include.h" 15 | #include "multiple-include.h" 16 | #include "multiple-include.h" 17 | #include "multiple-include.h" 18 | 19 | void putint_aux(int n) { 20 | if (n <= -10) putint_aux(n / 10); 21 | putchar('0' - (n % 10)); 22 | } 23 | 24 | void putint(int n) { 25 | if (n < 0) { 26 | putchar('-'); 27 | putint_aux(n); 28 | } else { 29 | putint_aux(-n); 30 | } 31 | 32 | putchar('\n'); 33 | } 34 | 35 | void main() { 36 | putint(CONSTANT1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/multiple-include.golden: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/multiple-include.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifndef MULTI_INCLUDE 4 | #define MULTI_INCLUDE 5 | 6 | int CONSTANT1 = 1; 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/relative-include.c: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | // putchar 4 | #include 5 | 6 | #define INCLUDE 7 | #include "relative/include1.h" 8 | 9 | void putint_aux(int n) { 10 | if (n <= -10) putint_aux(n / 10); 11 | putchar('0' - (n % 10)); 12 | } 13 | 14 | void putint(int n) { 15 | if (n < 0) { 16 | putchar('-'); 17 | putint_aux(n); 18 | } else { 19 | putint_aux(-n); 20 | } 21 | 22 | putchar('\n'); 23 | } 24 | 25 | void main() { 26 | putint(CONSTANT1); 27 | putint(CONSTANT2); 28 | putint(CONSTANT3); 29 | putint(CONSTANT4); 30 | } 31 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/relative-include.golden: -------------------------------------------------------------------------------- 1 | 21 2 | 22 3 | 23 4 | 24 5 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/relative/include1.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "include2.h" 5 | #endif 6 | 7 | int CONSTANT1 = 21; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/relative/include2.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "nested/include3.h" 5 | #endif 6 | 7 | int CONSTANT2 = 22; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/relative/include4.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | int CONSTANT4 = 24; 4 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/include/relative/nested/include3.h: -------------------------------------------------------------------------------- 1 | // tests for #include "" directives 2 | 3 | #ifdef INCLUDE 4 | #include "../include4.h" 5 | #endif 6 | 7 | int CONSTANT3 = 23; 8 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/builtin-stubbed.c: -------------------------------------------------------------------------------- 1 | // tests for __FILE__, __LINE__, __DATE__, __TIME__, __TIMESTAMP__ built-in macros 2 | // comp_pnut_opt: -USAFE_MODE 3 | #include 4 | 5 | #ifndef __FILE__ 6 | #error "__FILE__ is not defined" 7 | #endif 8 | #ifndef __LINE__ 9 | #error "__LINE__ is not defined" 10 | #endif 11 | #ifndef __DATE__ 12 | #error "__DATE__ is not defined" 13 | #endif 14 | #ifndef __TIME__ 15 | #error "__TIME__ is not defined" 16 | #endif 17 | #ifndef __TIMESTAMP__ 18 | #error "__TIMESTAMP__ is not defined" 19 | #endif 20 | 21 | void putint(int n) { 22 | if (n < 0) { 23 | putchar('-'); 24 | putint(-n); 25 | } else if (n > 9) { 26 | putint(n / 10); 27 | putchar('0' + n % 10); 28 | } else { 29 | putchar('0' + n); 30 | } 31 | } 32 | 33 | void putstr(char *str) { 34 | while (*str) { 35 | putchar(*str); 36 | str += 1; 37 | } 38 | } 39 | 40 | int main() { 41 | putstr(__FILE__); putchar('\n'); 42 | putint(__LINE__); putchar('\n'); 43 | putstr(__DATE__); putchar('\n'); 44 | putstr(__TIME__); putchar('\n'); 45 | putstr(__TIMESTAMP__); putchar('\n'); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/builtin-stubbed.golden: -------------------------------------------------------------------------------- 1 | tests/_all/preprocessor/macro/builtin-stubbed.c 2 | 0 3 | Jan 1 1970 4 | 00:00:00 5 | Jan 1 1970 00:00:00 6 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/builtin.c: -------------------------------------------------------------------------------- 1 | // tests for __FILE__, __LINE__, __DATE__, __TIME__, __TIMESTAMP__ built-in macros 2 | // comp_pnut_opt: -DINCLUDE_LINE_NUMBER_ON_ERROR 3 | #include "builtin-stubbed.c" 4 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/builtin.golden: -------------------------------------------------------------------------------- 1 | tests/_all/preprocessor/macro/builtin-stubbed.c 2 | 42 3 | Jan 1 1970 4 | 00:00:00 5 | Jan 1 1970 00:00:00 6 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/fun-like.golden: -------------------------------------------------------------------------------- 1 | 3 2 | 3 3 | 1 4 | 6 5 | 5 6 | 3 7 | 7 8 | 1 9 | 8 10 | 5 11 | 3 12 | 3 13 | 4 14 | 5 15 | 1 16 | 2 17 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/object-like.c: -------------------------------------------------------------------------------- 1 | // tests for object-like macro 2 | 3 | // putchar 4 | #include 5 | 6 | #define EMPTY 7 | #define FOO 1 8 | 9 | // Nested macros 10 | #define BAR FOO 11 | #define BAZ BAR 12 | #define QUX BAZ 13 | #define QUUX QUX 14 | #define CORGE QUUX 15 | #define GRULT CORGE 16 | #define GARPLY GRULT 17 | 18 | #define ADD (1 + 1) 19 | #define MUL (ADD * ADD) 20 | #define DIV (MUL / ADD) 21 | #define SUB (DIV - ADD) 22 | 23 | // An object-like macro that looks like a function-like macro. 24 | // The syntactical difference between PARENS_PARENS_EXPR2 being a function-like 25 | // macro and an object-like macro is the space between the macro name and the 26 | // opening parenthesis. 27 | // We define the macros in reverse order so that the nature of PARENS_EXPR is 28 | // not known when PARENS_PARENS_EXPR2 is defined. 29 | #define PARENS_PARENS_EXPR2 (PARENS_EXPR + PARENS_EXPR) 30 | #define PARENS_PARENS_EXPR (PARENS_EXPR) 31 | #define PARENS_EXPR (1 + 1) 32 | 33 | #define float int // We can redefine keywords 34 | 35 | void putdigit(int n) { 36 | putchar('0' + n); 37 | putchar('\n'); 38 | } 39 | 40 | void main() { 41 | float foo_val; // not a float, but an int 42 | 43 | putdigit(EMPTY + 8); // Will expand to + 8 44 | putdigit(FOO); 45 | putdigit(GARPLY); 46 | // Changing the value of FOO will change the expansion of any macros using it 47 | #define FOO 2 48 | putdigit(FOO); 49 | putdigit(GARPLY); 50 | 51 | putdigit(ADD); 52 | putdigit(MUL); 53 | putdigit(DIV); 54 | putdigit(SUB); 55 | 56 | putdigit(PARENS_EXPR); 57 | putdigit(PARENS_PARENS_EXPR); 58 | putdigit(PARENS_PARENS_EXPR2); 59 | foo_val = FOO 60 | #define FOO 3 // This will not change the value of foo_val 61 | ; 62 | 63 | putdigit(foo_val); 64 | } 65 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/object-like.golden: -------------------------------------------------------------------------------- 1 | 8 2 | 1 3 | 1 4 | 2 5 | 2 6 | 2 7 | 4 8 | 2 9 | 0 10 | 2 11 | 2 12 | 4 13 | 2 14 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/recursion-limit-error.golden: -------------------------------------------------------------------------------- 1 | tests/_all/preprocessor/macro/recursion-limit-error.c:215:11 Macro recursion depth exceeded. 2 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/recursion-limit.golden: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/self-reference.c: -------------------------------------------------------------------------------- 1 | // tests for recursion depth of macros 2 | 3 | // putchar 4 | #include 5 | 6 | int test1 = 1; 7 | int test2 = 2; 8 | int test3 = 3; 9 | int x = 4; 10 | int y = 5; 11 | 12 | void putdigit(int n) { 13 | putchar('0' + n); 14 | putchar('\n'); 15 | } 16 | 17 | void A(int a, int b) { 18 | putdigit(a); 19 | putdigit(b); 20 | } 21 | 22 | void B(int a, int b) { 23 | putdigit(a); 24 | putdigit(b); 25 | } 26 | 27 | #define test1 test1 28 | #define test2 test3 29 | #define test3 test2 30 | #define x 1 + y 31 | #define y 1 + x 32 | #define A(a1, a2) A(a1, a2) 33 | #define B(a1, a2) C(a1, a2) 34 | #define C(a1, a2) B(a1, a2) 35 | 36 | void main() { 37 | putdigit(test1); 38 | putdigit(test2); 39 | putdigit(test3); 40 | putdigit(x); 41 | putdigit(y); 42 | A(test1, test2); 43 | A(test3, x); 44 | // B(x, y); 45 | } 46 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/self-reference.golden: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 6 5 | 7 6 | 1 7 | 2 8 | 3 9 | 6 10 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/stringification.c: -------------------------------------------------------------------------------- 1 | // tests for macro stringification operator 2 | 3 | // putchar 4 | #include 5 | 6 | #define STR(x) #x 7 | 8 | void putstring(char * s) { 9 | while (*s) { 10 | putchar(*s); 11 | s = s + 1; 12 | } 13 | putchar('\n'); 14 | } 15 | 16 | void main() { 17 | putstring(STR(abc)); 18 | putstring(STR(5)); // This should be "5", but integers are not supported so it returns NOT_SUPPORTED 19 | } 20 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/stringification.golden: -------------------------------------------------------------------------------- 1 | abc 2 | NOT_SUPPORTED 3 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/token-pasting.c: -------------------------------------------------------------------------------- 1 | // tests for macro token pasting operator 2 | 3 | // putchar 4 | #include 5 | 6 | // Token pasting 7 | 8 | int number1234 = 5678; 9 | 10 | #define VAR number 11 | #define CONST_PASTED 1234 ## 5678 12 | #define VAR_PASTED number ## 1234 13 | 14 | #define PASTE(A, B) A ## B 15 | 16 | #define PASTED2(X) 1234 ## X 17 | #define PASTED3(X) X ## 1234 18 | 19 | void putint_aux(int n) { 20 | if (n <= -10) putint_aux(n / 10); 21 | putchar('0' - (n % 10)); 22 | } 23 | 24 | void putint(int n) { 25 | if (n < 0) { 26 | putchar('-'); 27 | putint_aux(n); 28 | } else { 29 | putint_aux(-n); 30 | } 31 | putchar('\n'); 32 | } 33 | 34 | void main() { 35 | putint(CONST_PASTED); // 12345678 36 | putint(VAR_PASTED); // number1234 37 | putint(PASTE(number, 1234)); // number1234 38 | putint(PASTED2(5678 + 1)); // 12345678 + 1 39 | putint(PASTED3(5678 + 1)); // 5678 + 11234 40 | } 41 | -------------------------------------------------------------------------------- /tests/_all/preprocessor/macro/token-pasting.golden: -------------------------------------------------------------------------------- 1 | 12345678 2 | 5678 3 | 5678 4 | 12345679 5 | 16912 6 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/ack.c: -------------------------------------------------------------------------------- 1 | void putstring(char *s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | int ack(int m, int n) 9 | { 10 | int a; /* Local variable so that the function is not simple */ 11 | if (m == 0) return n + 1; 12 | if(m > 0 && n == 0) return ack(m - 1, 1); 13 | return ack(m - 1, ack(m, n - 1)); 14 | } 15 | 16 | int main() { 17 | int m = 3; 18 | int n = 3; 19 | int acked = ack(m, n); 20 | putstring("ack("); 21 | putchar(48 + m); 22 | putstring(", "); 23 | putchar(48 + n); 24 | putstring(") = "); 25 | putchar(acked); //'=' == 61 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/ack.golden: -------------------------------------------------------------------------------- 1 | ack(3, 3) = = -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/argc.c: -------------------------------------------------------------------------------- 1 | // args: abc def hij 2 | void putstring(char * s) { 3 | while (*s) { 4 | putchar(*s); 5 | s = s + 1; 6 | } 7 | } 8 | 9 | int main(int argc, char ** args) { 10 | int i = 0; 11 | putstring("Number of arguments: "); 12 | putchar(48 + argc); 13 | putchar('\n'); 14 | putstring("Arguments:\n"); 15 | while (i < argc) { 16 | putstring("argv["); 17 | putchar(48 + i); 18 | putstring("] = "); 19 | putstring(args[i]); 20 | putchar('\n'); 21 | i = i + 1; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/argc.golden: -------------------------------------------------------------------------------- 1 | Number of arguments: 4 2 | Arguments: 3 | argv[0] = ./tests/_all/six-cc-tests/argc.exe 4 | argv[1] = abc 5 | argv[2] = def 6 | argv[3] = hij 7 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/arith-indirect.c: -------------------------------------------------------------------------------- 1 | void putstring(char * s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | int main() { 9 | int * arr; 10 | int acc; 11 | int i = 0; 12 | 13 | arr = malloc(100); 14 | 15 | i = 0; 16 | while(i < 100) { 17 | arr[i] = i; 18 | i = i + 1; 19 | } 20 | 21 | acc = 0; 22 | i = 0; 23 | while(i < 100) { 24 | acc += arr[i] * 13; 25 | i = i + 1; 26 | } 27 | 28 | putstring("acc: "); 29 | if(acc == 64350) { 30 | putstring("64350"); 31 | } else { 32 | putstring("not 64350"); 33 | } 34 | putchar(10); 35 | 36 | acc = 0; 37 | i = 0; 38 | while (i < 100) { 39 | acc += (*(arr + i)) * 13; 40 | i = i + 1; 41 | } 42 | putstring("acc: "); 43 | if(acc == 64350) { 44 | putstring("64350"); 45 | } else { 46 | putstring("not 64350"); 47 | } 48 | putchar(10); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/arith-indirect.golden: -------------------------------------------------------------------------------- 1 | acc: 64350 2 | acc: 64350 3 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/arith.golden: -------------------------------------------------------------------------------- 1 | x: 43, y: 128, z: 43 2 | x: 42, y: 128, z: 42 3 | x: 43, y: 128, z: 42 4 | x: 42, y: 128, z: 43 5 | x: 170, y: 128, z: 170 6 | x: 42, y: 128, z: 42 7 | x: 5376, y: 128, z: 5376 8 | x: 42, y: 128, z: 42 9 | x: 42, y: 128, z: 42 10 | x: 0, y: 128, z: 0 11 | x: 128, y: 128, z: 128 12 | x: 0, y: 128, z: 0 13 | x: 0, y: 128, z: 0 14 | x: 0, y: 128, z: 0 15 | x: 0, y: 128, z: -1 16 | x: 0, y: 128, z: -1 17 | x: 0, y: 128, z: 0 18 | x: 0, y: 128, z: 128 19 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/conditions.c: -------------------------------------------------------------------------------- 1 | void putstring(char* s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | void main() { 9 | int i = 0; 10 | int j = 5; 11 | int k = 12; 12 | char * p = "_hello"; 13 | 14 | if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '_') 15 | { 16 | putstring("p: "); 17 | putchar(*p); 18 | putchar('\n'); 19 | } 20 | if ((*p >= 'a' || *p <= 'z') && (*p >= 'A' || *p <= 'Z') && !(*p >= '0' || *p <= '9') && *p == '_') 21 | { 22 | putstring("p: "); 23 | putchar(*p); 24 | putchar('\n'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/conditions.golden: -------------------------------------------------------------------------------- 1 | p: _ 2 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/empty.c: -------------------------------------------------------------------------------- 1 | void test() { 2 | while(1) 3 | return 1; 4 | } 5 | 6 | int main() { 7 | int x = 1; 8 | test(); 9 | while(0); 10 | 11 | while(x == 0){ 12 | x = 1; 13 | } 14 | 15 | if (0); 16 | } 17 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/six-cc-tests/empty.golden -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/six-cc-tests/empty.txt -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/enums.c: -------------------------------------------------------------------------------- 1 | /* Test that enum variables can be shadowed by local bindings */ 2 | 3 | void putstring(const char *s) { 4 | while (*s) { 5 | putchar(*s); 6 | s++; 7 | } 8 | } 9 | 10 | void putnumber(int n) { 11 | int acc = 0; 12 | int i = 0; 13 | int *digits = malloc(10 * sizeof(int)); // Dynamically allocate memory for digits 14 | 15 | if (digits == 0) { 16 | putstring("Memory allocation failed\n"); 17 | return; 18 | } 19 | 20 | if (n == 0) { 21 | putchar(48); 22 | free(digits); // Free allocated memory 23 | return; 24 | } 25 | 26 | while (n > 0) { 27 | digits[i] = n % 10; 28 | n = n / 10; 29 | i++; 30 | } 31 | i--; 32 | while (i >= 0) { 33 | putchar(digits[i] + 48); 34 | i--; 35 | } 36 | 37 | free(digits); // Free allocated memory 38 | } 39 | 40 | enum ChildEnum { VAL, NEXT, LL_SIZE }; 41 | 42 | enum ParentEnum { VAL2, NEXT2, LL_SIZE2 }; 43 | 44 | struct TestStruct { 45 | int VAL; 46 | int NEXT; 47 | int LL_SIZE; 48 | }; 49 | 50 | void shadow(int NEXT) { 51 | int VAL; 52 | VAL = 123; 53 | NEXT = 456; 54 | putstring("VAL: "); 55 | putnumber(VAL); 56 | putstring(", NEXT: "); 57 | putnumber(NEXT); 58 | putchar(10); 59 | } 60 | 61 | int main() { 62 | putstring("VAL: "); 63 | putnumber(VAL); // Note: This refers to the global enum 'VAL' 64 | putstring(", NEXT: "); 65 | putnumber(NEXT); // Note: This refers to the global enum 'NEXT' 66 | putchar(10); 67 | shadow(789); 68 | putstring("VAL: "); 69 | putnumber(VAL); // Note: This refers to the global enum 'VAL' 70 | putstring(", NEXT: "); 71 | putnumber(NEXT); // Note: This refers to the global enum 'NEXT' 72 | putchar(10); 73 | return 0; 74 | } -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/enums.golden: -------------------------------------------------------------------------------- 1 | VAL: 0, NEXT: 1 2 | VAL: 123, NEXT: 456 3 | VAL: 0, NEXT: 1 4 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/even-odd.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void putstr(char *str) { 4 | while (*str) { 5 | putchar(*str); 6 | str += 1; 7 | } 8 | } 9 | 10 | void putint_aux(int n) { 11 | if (n <= -10) putint_aux(n / 10); 12 | putchar('0' - (n % 10)); 13 | } 14 | 15 | void putint(int n) { 16 | if (n < 0) { 17 | putchar('-'); 18 | putint_aux(n); 19 | } else { 20 | putint_aux(-n); 21 | } 22 | } 23 | 24 | int abs(int number); 25 | int even(int number); 26 | int odd(int number); 27 | 28 | int abs(int number) { 29 | if(number < 0) return -number; 30 | return number; 31 | } 32 | 33 | int even(int number) { 34 | int a; /* Local variable so that the function is not simple */ 35 | if(number == 0) return 1; 36 | return odd(abs(number)-1); 37 | } 38 | 39 | int odd(int number) { 40 | int a; /* Local variable so that the function is not simple */ 41 | if( number == 0 ) return 0; 42 | return even(abs(number)-1); 43 | } 44 | 45 | int main() { 46 | int n1; 47 | int n2; 48 | n1 = even(10); 49 | n2 = odd(10); 50 | putstr("n1 = "); 51 | putint(n1); 52 | putchar('\n'); 53 | putstr("n2 = "); 54 | putint(n2); 55 | putchar('\n'); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/even-odd.golden: -------------------------------------------------------------------------------- 1 | n1 = 1 2 | n2 = 0 3 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fgetc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef PNUT_CC 4 | typedef int FILE; 5 | #endif 6 | 7 | int main() { 8 | FILE *f; 9 | char c; 10 | f = fopen("tests/_all/six-cc-tests/fgetc.c", "r"); 11 | while ((c = fgetc(f)) != -1) { 12 | putchar(c); 13 | } 14 | fclose(f); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fgetc.golden: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef PNUT_CC 4 | typedef int FILE; 5 | #endif 6 | 7 | int main() { 8 | FILE *f; 9 | char c; 10 | f = fopen("tests/_all/six-cc-tests/fgetc.c", "r"); 11 | while ((c = fgetc(f)) != -1) { 12 | putchar(c); 13 | } 14 | fclose(f); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fib.c: -------------------------------------------------------------------------------- 1 | void putint_aux(int n) { 2 | if (n >= 10) putint_aux(n / 10); 3 | putchar('0' + (n % 10)); 4 | } 5 | 6 | void putint(int n) { 7 | if (n < 0) { 8 | putchar('-'); 9 | putint_aux(-n); 10 | } else { 11 | putint_aux(n); 12 | } 13 | } 14 | 15 | int fib(int n) { 16 | if (n <= 1) return n; 17 | 18 | return fib(n - 1) + fib(n - 2); 19 | } 20 | 21 | int main() { 22 | putint(fib(15)); 23 | putchar(10); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fib.golden: -------------------------------------------------------------------------------- 1 | 610 2 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fopen-empty.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef PNUT_CC 4 | typedef int FILE; 5 | #endif 6 | 7 | int main() { 8 | FILE *f; 9 | char c; 10 | f = fopen("tests/_all/six-cc-tests/empty.txt", "r"); 11 | while ((c = fgetc(f)) != -1) { 12 | putchar(c); 13 | } 14 | fclose(f); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fopen-empty.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/six-cc-tests/fopen-empty.golden -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fopen-many.c: -------------------------------------------------------------------------------- 1 | // On mksh, this test takes more than 30s. Adjusting the timeout to make it pass. 2 | // timeout: 120 3 | 4 | #include 5 | 6 | #ifdef PNUT_CC 7 | typedef int FILE; 8 | #endif 9 | 10 | int main() { 11 | FILE *f; 12 | char c; 13 | int i = 0; 14 | while (i < 100) { 15 | f = fopen("tests/_all/six-cc-tests/fgetc.c", "r"); 16 | while ((c = fgetc(f)) != -1) { 17 | putchar(c); 18 | } 19 | putchar('\n'); 20 | fclose(f); 21 | i = i + 1; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fopen-trailing.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int f; 3 | char c; 4 | f = fopen("tests/_all/six-cc-tests/no-trailing.txt", "r"); 5 | while ((c = fgetc(f)) != -1) { 6 | putchar(c); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/fopen-trailing.golden: -------------------------------------------------------------------------------- 1 | abcdefghijklmnopqrstuvwxyz -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/getchar-interlaced.c-deactivated: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | /* Compare stdin with file, output matching prefix */ 3 | int main() { 4 | char c1; 5 | char c2; 6 | int f; 7 | f = fopen("tests/six-cc-tests/getchar-interlaced.c", 0); 8 | while ((c1 = getchar()) && (c2 = fgetc(f)) && c1 == c2 && c1 != -1) { 9 | putchar(c1); 10 | } 11 | fclose(f); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/getchar-interlaced.golden: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | /* Compare stdin with file, output matching prefix */ 3 | int main() { 4 | char c1; 5 | char c2; 6 | int f; 7 | f = fopen("tests/six-cc-tests/getchar-interlaced.c", 0); 8 | while ((c1 = getchar()) && (c2 = fgetc(f)) && c1 == c2 && c1 != EOF) { 9 | putchar(c1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/getchar.c-deactivated: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | int main() { 3 | char c; 4 | while ((c = getchar()) != -1) { 5 | c = getchar(); 6 | putchar(c); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/getchar.golden: -------------------------------------------------------------------------------- 1 | /* input:six-cc-tests/getchar-interlaced.c */ 2 | /* Compare stdin with file, output matching prefix */ 3 | int main() { 4 | char c1; 5 | char c2; 6 | FILE_ptr f; 7 | f = fopen("six-cc-tests/getchar-interlaced.c", 0); 8 | while ((c1 = getchar()) && (c2 = fgetc(f)) && c1 == c2 && c1 != EOF) { 9 | putchar(c1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/if.c: -------------------------------------------------------------------------------- 1 | void putstring(char *s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | int main() { 9 | int x; 10 | int y; 11 | 12 | x = 42; 13 | y = 128; 14 | 15 | if (x < y) { 16 | //printf("if (x < y)\n"); 17 | putstring("if (x < y)\n"); 18 | } else { 19 | //printf("else (x >= y)\n"); 20 | putstring("else (x >= y)\n"); 21 | } 22 | 23 | if (x > y) { 24 | //printf("x > y\n"); 25 | putstring("x > y\n"); 26 | } else if (x == y) { 27 | //printf("else if (x == y)\n"); 28 | putstring("else if (x == y)\n"); 29 | } 30 | 31 | if (x > y) { 32 | //printf("if (x > y)\n"); 33 | putstring("if (x > y)\n"); 34 | } else if (x == y) { 35 | //printf("else if (x == y)\n"); 36 | putstring("else if (x == y)\n"); 37 | } else { 38 | //printf("else (x < y)\n"); 39 | putstring("else (x < y)\n"); 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/if.golden: -------------------------------------------------------------------------------- 1 | if (x < y) 2 | else (x < y) 3 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/increment.c: -------------------------------------------------------------------------------- 1 | void putstring(char *s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | void putnumber(int n) { 9 | int acc = 0; 10 | int i = 0; 11 | int *digits = malloc(10 * sizeof(int)); // Dynamically allocate memory for digits 12 | 13 | if (digits == 0) { 14 | putstring("Memory allocation failed\n"); 15 | return; 16 | } 17 | 18 | if (n == 0) { 19 | putchar(48); 20 | free(digits); // Free allocated memory 21 | return; 22 | } 23 | 24 | while (n > 0) { 25 | digits[i] = n % 10; 26 | n = n / 10; 27 | i++; 28 | } 29 | i--; 30 | while (i >= 0) { 31 | putchar(digits[i] + 48); 32 | i--; 33 | } 34 | 35 | free(digits); // Free allocated memory 36 | } 37 | 38 | int main() { 39 | int a; 40 | int b; 41 | int x; 42 | int y; 43 | int z; 44 | 45 | x = 3; 46 | y = x++; 47 | x = 3; 48 | z = ++x; 49 | 50 | a = 0; 51 | b = 0; 52 | while (a < 10) { 53 | b += a++; 54 | } 55 | //printf("a: %d, b: %d, x: %d, y: %d, z: %d\n", a, b, x, y, z); 56 | putstring("a: "); 57 | putnumber(a); 58 | putchar(','); 59 | putchar(' '); 60 | putstring("b: "); 61 | putnumber(b); 62 | putchar(','); 63 | putchar(' '); 64 | putstring("x: "); 65 | putnumber(x); 66 | putchar(','); 67 | putchar(' '); 68 | putstring("y: "); 69 | putnumber(y); 70 | putchar(','); 71 | putchar(' '); 72 | putstring("z: "); 73 | putnumber(z); 74 | putchar(10); 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/increment.golden: -------------------------------------------------------------------------------- 1 | a: 10, b: 45, x: 4, y: 3, z: 4 2 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/init.c: -------------------------------------------------------------------------------- 1 | void putstring(char *s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | void main() { 9 | int i = 0; 10 | int j = 5; 11 | int k; 12 | char * s; 13 | char * t = "Hello, world!"; 14 | k = 42; 15 | putstring("i: "); 16 | putchar(i + 48); 17 | putstring(", j: "); 18 | putchar(j + 48); 19 | putstring(", k: "); 20 | if(k == 42) { 21 | putstring("42"); 22 | } else { 23 | putstring("not 42"); 24 | } 25 | putchar('\n'); 26 | putstring("t: "); 27 | putstring(t); 28 | putchar('\n'); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/init.golden: -------------------------------------------------------------------------------- 1 | i: 0, j: 5, k: 42 2 | t: Hello, world! 3 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/initialization.c: -------------------------------------------------------------------------------- 1 | void putstring(char *s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | void putnumber(int n) { 9 | int acc = 0; 10 | int i = 0; 11 | int *digits = malloc(10 * sizeof(int)); // Dynamically allocate memory for digits 12 | 13 | if (digits == 0) { 14 | putstring("Memory allocation failed\n"); 15 | return; 16 | } 17 | 18 | if (n == 0) { 19 | putchar(48); 20 | free(digits); // Free allocated memory 21 | return; 22 | } 23 | 24 | while (n > 0) { 25 | digits[i] = n % 10; 26 | n = n / 10; 27 | i++; 28 | } 29 | i--; 30 | while (i >= 0) { 31 | putchar(digits[i] + 48); 32 | i--; 33 | } 34 | 35 | free(digits); // Free allocated memory 36 | } 37 | 38 | void main() { 39 | int i = 28; 40 | int j = 14; 41 | int k = i + j; 42 | putstring("i: "); 43 | putnumber(i); 44 | putstring(", j: "); 45 | putnumber(j); 46 | putstring(", k: "); 47 | putnumber(k); 48 | putchar('\n'); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/initialization.golden: -------------------------------------------------------------------------------- 1 | i: 28, j: 14, k: 42 2 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/no-trailing.txt: -------------------------------------------------------------------------------- 1 | abcdefghijklmnopqrstuvwxyz -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/print.c-deactivated: -------------------------------------------------------------------------------- 1 | int chr = 65; 2 | 3 | int next_char() { 4 | return chr++; 5 | } 6 | 7 | void main() 8 | { 9 | char * str; 10 | str = "ABCDEFHIJKLMNOPQRSTUVWXYZ"; 11 | printf("%d\n", 42); 12 | printf("Beau %s\n", "velo"); 13 | printf("Beau %s %s\n", "velo (%s)", "bleu"); 14 | 15 | printf("Beau %s %s %s\n", "velo (%s)", "bleu", "rouge"); 16 | 17 | printf("%c", 'A'); 18 | printf("%c", 'L'); 19 | printf("%c", 'L'); 20 | printf("%c\n", 'O'); 21 | 22 | printf("Allo in hex: 0x%x 0x%x 0x%x 0x%x\n", 'A', 'L', 'L', 'O'); 23 | 24 | printf("_\n"); 25 | 26 | printf("alphabet:\n%s\n", str); 27 | printf("4 first letters of the alphabet with next_char:\n%c%c%c%c\n", next_char(), next_char(), next_char(), next_char()); 28 | 29 | printf("4 first letters of the alphabet with .*s:\n%.*s\n", 4, str); 30 | printf("4 first letters of the alphabet with 0.4s:\n%0.4s\n", str); 31 | printf("Last 4 letters of the alphabet with padding:\n%26.s\n", "ABCDEFHIJKLMNOPQRSTUVWXYZ" + 20); 32 | printf("The alphabet twice: %s %s\n", "ABCDEFHIJKLMNOPQRSTUVWXYZ", "ABCDEFHIJKLMNOPQRSTUVWXYZ"); 33 | } 34 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/print.golden: -------------------------------------------------------------------------------- 1 | 42 2 | Beau velo 3 | Beau velo (%s) bleu 4 | Beau velo (%s) bleu rouge 5 | ALLO 6 | Allo in hex: 0x41 0x4c 0x4c 0x4f 7 | _ 8 | alphabet: 9 | ABCDEFHIJKLMNOPQRSTUVWXYZ 10 | 4 first letters of the alphabet with next_char: 11 | ABCD 12 | 4 first letters of the alphabet with .*s: 13 | ABCD 14 | 4 first letters of the alphabet with 0.4s: 15 | ABCD 16 | Last 4 letters of the alphabet with padding: 17 | VWXYZ 18 | The alphabet twice: ABCDEFHIJKLMNOPQRSTUVWXYZ ABCDEFHIJKLMNOPQRSTUVWXYZ 19 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/return.c-deactivated: -------------------------------------------------------------------------------- 1 | int test() { 2 | int i; 3 | if (1) { 4 | return; 5 | } 6 | } 7 | 8 | 9 | int main() { 10 | test(); 11 | } 12 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/return.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/six-cc-tests/return.golden -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/short-circuit.c: -------------------------------------------------------------------------------- 1 | /* Test that the lazy evaluation properties of || and && are respected */ 2 | 3 | void putstr(char *s) { 4 | while (*s) { 5 | putchar(*s); 6 | s = s + 1; 7 | } 8 | } 9 | 10 | void DO_NOT_CALL(int x) { 11 | int a; /* Local variable so that the function is not simple */ 12 | putstr("Boom!"); 13 | exit(1); 14 | return x; 15 | } 16 | 17 | void SHOULD_BE_CALLED(int x) { 18 | int a; /* Local variable so that the function is not simple */ 19 | if (x) { 20 | putstr("Ah!\n"); 21 | } 22 | else { 23 | putstr("Oh!\n"); 24 | } 25 | return x; 26 | } 27 | 28 | int main() { 29 | if (1 || DO_NOT_CALL(1)) { 30 | putstr("This should print 1\n"); 31 | } 32 | if (0 || SHOULD_BE_CALLED(1)) { 33 | putstr("This should print 2\n"); 34 | } 35 | if (0 || SHOULD_BE_CALLED(0)) { 36 | putstr("This should not print\n"); 37 | } 38 | if (1 && SHOULD_BE_CALLED(1)) { 39 | putstr("This should print 3\n"); 40 | } 41 | if (1 && SHOULD_BE_CALLED(0)) { 42 | putstr("This should not print\n"); 43 | } 44 | if (0 && DO_NOT_CALL(1)) { 45 | putstr("This should not print\n"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/short-circuit.golden: -------------------------------------------------------------------------------- 1 | This should print 1 2 | Ah! 3 | This should print 2 4 | Oh! 5 | Ah! 6 | This should print 3 7 | Oh! 8 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/string.c: -------------------------------------------------------------------------------- 1 | void putstring(char *s, int length) { 2 | int i = 0; 3 | while (i < length && s[i]) { 4 | putchar(s[i]); 5 | i++; 6 | } 7 | } 8 | 9 | int main() { 10 | char * str = "LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,EXIT,"; 11 | int i = 0; 12 | while (i < 39) { 13 | putstring(str + i * 5, 4); 14 | putchar('\n'); 15 | i++; 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/string.golden: -------------------------------------------------------------------------------- 1 | LEA 2 | IMM 3 | JMP 4 | JSR 5 | BZ 6 | BNZ 7 | ENT 8 | ADJ 9 | LEV 10 | LI 11 | LC 12 | SI 13 | SC 14 | PSH 15 | OR 16 | XOR 17 | AND 18 | EQ 19 | NE 20 | LT 21 | GT 22 | LE 23 | GE 24 | SHL 25 | SHR 26 | ADD 27 | SUB 28 | MUL 29 | DIV 30 | MOD 31 | OPEN 32 | READ 33 | CLOS 34 | PRTF 35 | MALC 36 | FREE 37 | MSET 38 | MCMP 39 | EXIT 40 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/strlen.c: -------------------------------------------------------------------------------- 1 | /* typedef char *char_ptr; */ 2 | 3 | void putstring(char * s) { 4 | while (*s) { 5 | putchar(*s); 6 | s = s + 1; 7 | } 8 | } 9 | 10 | int string_len(char * s) { 11 | int ix; 12 | ix = 0; 13 | while (s[ix] != 0) { 14 | ix = ix + 1; 15 | } 16 | return ix; 17 | } 18 | 19 | int string_sum(char * s) { 20 | int sum = 0; 21 | while (*s != '\0') { 22 | sum += *s; 23 | s = s + 1; 24 | } 25 | 26 | return sum; 27 | } 28 | 29 | int *iota_array(int start, int max) { 30 | int i = 0; 31 | int *arr = malloc(max - start); 32 | while (i + start < max) { 33 | arr[i] = i + start; 34 | i = i + 1; 35 | } 36 | return arr; 37 | } 38 | 39 | int array_sum(int * arr, int len) { 40 | int sum; 41 | int i; 42 | sum = 0; 43 | i = 0; 44 | while (i < len) { 45 | sum += arr[i]; 46 | i = i + 1; 47 | } 48 | return sum; 49 | } 50 | 51 | int main() { 52 | int *arr = iota_array(0, 50); 53 | int n1 = string_len("12345"); 54 | int n2 = string_sum("Hello, world!"); 55 | int n3 = array_sum(arr, 50); 56 | putstring("n1 = "); 57 | putchar(n1 + 48); 58 | putchar('\n'); 59 | putstring("n2 = "); 60 | if(n2 == 1161) { 61 | putstring("1161"); 62 | } else { 63 | putstring("not 1161"); 64 | } 65 | putchar('\n'); 66 | putstring("n3 = "); 67 | if(n3 == 1225) { 68 | putstring("1225"); 69 | } else { 70 | putstring("not 1225"); 71 | } 72 | putchar('\n'); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/strlen.golden: -------------------------------------------------------------------------------- 1 | n1 = 5 2 | n2 = 1161 3 | n3 = 1225 4 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/struct-enum.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // for intptr_t 4 | 5 | #ifdef PNUT_CC 6 | // When bootstrapping pnut, intptr_t is not defined. 7 | // On 64 bit platforms, intptr_t is a long long int. 8 | // On 32 bit (including shells) platforms, intptr_t is an int. 9 | #if defined(PNUT_EXE_64) 10 | typedef long long int intptr_t; 11 | #else 12 | typedef int intptr_t; 13 | #endif 14 | #endif 15 | 16 | void putstr(const char *s) { 17 | while (*s) { 18 | putchar(*s); 19 | s++; 20 | } 21 | } 22 | 23 | void putint(int n) { 24 | if (n < 0) { 25 | putchar('-'); 26 | n = -n; 27 | } 28 | if (n >= 10) { 29 | putint(n / 10); 30 | } 31 | putchar('0' + n % 10); 32 | } 33 | 34 | enum LinkedList { 35 | VAL, 36 | NEXT, 37 | LL_SIZE 38 | }; 39 | 40 | intptr_t *iota_linked_list(int max) { 41 | intptr_t *head, *last, *node; 42 | int i = 1; 43 | 44 | head = (intptr_t *) malloc(LL_SIZE * sizeof(intptr_t)); 45 | head[VAL] = 0; 46 | head[NEXT] = 0; 47 | last = head; 48 | 49 | while (i < max) { 50 | node = (intptr_t *) malloc(LL_SIZE * sizeof(intptr_t)); 51 | node[VAL] = i; 52 | node[NEXT] = 0; 53 | last[NEXT] = (intptr_t) node; 54 | last = node; 55 | i = i + 1; 56 | } 57 | 58 | return head; 59 | } 60 | 61 | int linked_list_sum(intptr_t *head) { 62 | int sum = 0; 63 | while (head != 0) { 64 | sum += head[VAL]; 65 | head = (intptr_t *) head[NEXT]; 66 | } 67 | return sum; 68 | } 69 | 70 | int main() { 71 | intptr_t *ll = iota_linked_list(1000); 72 | int sum = linked_list_sum(ll); 73 | putstr("Sum: "); 74 | putint(sum); 75 | putchar('\n'); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/struct-enum.golden: -------------------------------------------------------------------------------- 1 | Sum: 499500 2 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/struct.golden: -------------------------------------------------------------------------------- 1 | Sum: 499500 2 | Sum: 498501 3 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/test.c: -------------------------------------------------------------------------------- 1 | void putstring(char *s) { 2 | while (*s) { 3 | putchar(*s); 4 | s = s + 1; 5 | } 6 | } 7 | 8 | void main() { 9 | /* print a number to stdout */ 10 | int NL; 11 | int ZERO; 12 | int n; 13 | int p; 14 | int digit; 15 | NL = 10; 16 | ZERO = 48; 17 | n = 31416; 18 | p = 1; 19 | 20 | while (p * 10 <= n) p = p * 10; 21 | 22 | while (p > 0) { 23 | digit = n / p; 24 | putchar(ZERO + digit); 25 | n = n % p; 26 | p = p / 10; 27 | } 28 | 29 | if (NL == 31416){ 30 | putstring("31416"); 31 | } 32 | putchar(10); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/test.golden: -------------------------------------------------------------------------------- 1 | 31416 2 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/test2.c: -------------------------------------------------------------------------------- 1 | int square(int x) { 2 | int y = x*x; 3 | return y; 4 | } 5 | 6 | void main() 7 | { 8 | int n; 9 | int p; 10 | int digit; 11 | 12 | n = square(10); 13 | p = 1; 14 | 15 | while (p * 10 <= n){ 16 | p = p * 10; 17 | } 18 | 19 | while (p > 0) { 20 | digit = n / p; 21 | putchar(48 + digit); 22 | n = n % p; 23 | p = p / 10; 24 | } 25 | 26 | putchar(10); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/test2.golden: -------------------------------------------------------------------------------- 1 | 100 2 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/while-continue.c: -------------------------------------------------------------------------------- 1 | //putstring function 2 | void putstring(char *s) { 3 | while (*s) { 4 | putchar(*s); 5 | s = s + 1; 6 | } 7 | } 8 | 9 | void putnumber(int n) { 10 | int acc = 0; 11 | int i = 0; 12 | int *digits = malloc(10 * sizeof(int)); // Dynamically allocate memory for digits 13 | 14 | if (digits == 0) { 15 | putstring("Memory allocation failed\n"); 16 | return; 17 | } 18 | 19 | if (n == 0) { 20 | putchar(48); 21 | free(digits); // Free allocated memory 22 | return; 23 | } 24 | 25 | while (n > 0) { 26 | digits[i] = n % 10; 27 | n = n / 10; 28 | i++; 29 | } 30 | i--; 31 | while (i >= 0) { 32 | putchar(digits[i] + 48); 33 | i--; 34 | } 35 | 36 | free(digits); // Free allocated memory 37 | } 38 | 39 | int main() { 40 | int i = 0; 41 | while (i < 35) { 42 | /* Skip over even numbers*/ 43 | if (i % 2 == 0) { 44 | i = i + 1; 45 | continue; 46 | } 47 | putnumber(i); 48 | putstring(": "); 49 | if (i % 3 == 0) { 50 | putstring("fizz"); 51 | } 52 | if (i % 5 == 0) { 53 | putstring("buzz"); 54 | } 55 | putstring(".\n"); 56 | if (i == 12){ 57 | break; 58 | } 59 | i = i + 1; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/while-continue.golden: -------------------------------------------------------------------------------- 1 | 1: . 2 | 3: fizz. 3 | 5: buzz. 4 | 7: . 5 | 9: fizz. 6 | 11: . 7 | 13: . 8 | 15: fizzbuzz. 9 | 17: . 10 | 19: . 11 | 21: fizz. 12 | 23: . 13 | 25: buzz. 14 | 27: fizz. 15 | 29: . 16 | 31: . 17 | 33: fizz. 18 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/while-fun-call.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef PNUT_CC 4 | typedef int FILE; 5 | #endif 6 | 7 | int emit_line(int line, FILE *f) { 8 | char c; 9 | putchar(line+ 48); 10 | putchar(':'); 11 | putchar(' '); 12 | while ((c = fgetc(f)) && c != -1 && c != '\n') { 13 | putchar(c); 14 | } 15 | if (c != -1) { 16 | putchar('\n'); 17 | } 18 | return c; 19 | } 20 | 21 | int main() { 22 | char c1; 23 | char c2; 24 | int i = 0; 25 | FILE *f1 = fopen("tests/_all/six-cc-tests/fgetc.c", "r"); 26 | FILE *f2 = fopen("tests/_all/six-cc-tests/while-fun-call.c", "r"); 27 | while (1) { 28 | c1 = emit_line(i, f1); 29 | c2 = emit_line(i, f2); 30 | if (c1 == -1 || c2 == -1){ 31 | break; 32 | } 33 | i += 1; 34 | } 35 | 36 | fclose(f1); 37 | fclose(f2); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/while-fun-call.golden: -------------------------------------------------------------------------------- 1 | 0: #include 2 | 0: #include 3 | 1: 4 | 1: 5 | 2: #ifdef PNUT_CC 6 | 2: #ifdef PNUT_CC 7 | 3: typedef int FILE; 8 | 3: typedef int FILE; 9 | 4: #endif 10 | 4: #endif 11 | 5: 12 | 5: 13 | 6: int main() { 14 | 6: int emit_line(int line, FILE *f) { 15 | 7: FILE *f; 16 | 7: char c; 17 | 8: char c; 18 | 8: putchar(line+ 48); 19 | 9: f = fopen("tests/_all/six-cc-tests/fgetc.c", "r"); 20 | 9: putchar(':'); 21 | :: while ((c = fgetc(f)) != -1) { 22 | :: putchar(' '); 23 | ;: putchar(c); 24 | ;: while ((c = fgetc(f)) && c != -1 && c != '\n') { 25 | <: } 26 | <: putchar(c); 27 | =: fclose(f); 28 | =: } 29 | >: 30 | >: if (c != -1) { 31 | ?: return 0; 32 | ?: putchar('\n'); 33 | @: } 34 | @: } 35 | A: A: return c; 36 | -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/winter-pi2.c: -------------------------------------------------------------------------------- 1 | /* #include */ 2 | 3 | /* https://cs.uwaterloo.ca/~alopez-o/math-faq/mathtext/node12.html */ 4 | 5 | void putstring(char *s) { 6 | while (*s) { 7 | putchar(*s); 8 | s = s + 1; 9 | } 10 | } 11 | 12 | 13 | int r[2801]; 14 | int i; 15 | int k = 280; 16 | int b; 17 | int d; 18 | int c = 0; 19 | 20 | int main() { 21 | int i = 0; 22 | 23 | while (i < 2800) { 24 | r[i] = 2000; 25 | i = i + 1; 26 | } 27 | r[i] = 0; 28 | 29 | while (k > 0) { 30 | 31 | d = 0; 32 | i = k; 33 | 34 | while (1) { 35 | d = d + r[i] * 10000; 36 | b = 2 * i - 1; 37 | 38 | r[i] = d % b; 39 | d = d / b; 40 | i = i - 1; 41 | if (i == 0){ 42 | break; 43 | } 44 | d = d * i; 45 | } 46 | putchar(48 + (c + d / 10000) / 1000 % 10); 47 | putchar(48 + (c + d / 10000) / 100 % 10); 48 | putchar(48 + (c + d / 10000) / 10 % 10); 49 | putchar(48 + (c + d / 10000) % 10); 50 | c = d % 10000; 51 | k = k - 14; 52 | } 53 | 54 | putchar('\n'); 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /tests/_all/six-cc-tests/winter-pi2.golden: -------------------------------------------------------------------------------- 1 | 31415926535897932384626433832795028841971693993751058209749445923078164062862089 2 | -------------------------------------------------------------------------------- /tests/_all/strings-with-nul.c: -------------------------------------------------------------------------------- 1 | // comp_pnut_opt: -DOPTIMIZE_LONG_LINES 2 | 3 | #include 4 | 5 | char* str1 = "WOWOWOWOWOWO\0HAHAHAHA"; 6 | // Make sure escape sequences spanning 16 characters boundary are handled correctly. 7 | char *str2 = "012345678901235\0 6789"; 8 | 9 | // 32 NUL characters, followed by 4 non-NUL characters 10 | char *str3 = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0test"; 11 | 12 | // String concatenation and stringizing works with NUL characters 13 | char *str4 = "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "\0" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"; 14 | 15 | void putstrl(char* str, int len) { 16 | int i = 0; 17 | while (i < len) { 18 | if (str[i] == '\0') { 19 | putchar('_'); 20 | } else { 21 | putchar(str[i]); 22 | } 23 | i += 1; 24 | } 25 | putchar('\n'); 26 | } 27 | 28 | int main() { 29 | putstrl(str1, 20); 30 | putstrl(str2, 20); 31 | putstrl(str3 + 32, 4); 32 | putstrl(str4, 27); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /tests/_all/strings-with-nul.golden: -------------------------------------------------------------------------------- 1 | WOWOWOWOWOWO_HAHAHAH 2 | 012345678901235_ 678 3 | test 4 | abcdefghij_klmnopqrstuvwxyz 5 | -------------------------------------------------------------------------------- /tests/_all/switch.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() { 3 | int i = 0; 4 | switch (i) { 5 | case 0: { 6 | putchar('H'); 7 | break; 8 | } 9 | case 1: { 10 | putchar('B'); 11 | break; 12 | } 13 | default: { 14 | printf("Bad too!\n"); 15 | break; 16 | } 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /tests/_all/switch.golden: -------------------------------------------------------------------------------- 1 | H -------------------------------------------------------------------------------- /tests/_all/switch_double_break.c: -------------------------------------------------------------------------------- 1 | #include 2 | void main() { 3 | int i = 5; 4 | switch (i) { 5 | case 0: { 6 | putchar('0'); 7 | break; 8 | } 9 | case 1: { 10 | putchar('1'); 11 | break; 12 | } 13 | case 5: { 14 | putchar('>'); 15 | { 16 | putchar('4'); 17 | break; 18 | } 19 | putchar('='); 20 | putchar('5'); 21 | break; 22 | } 23 | default: { 24 | putchar('D'); 25 | break; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/_all/switch_double_break.golden: -------------------------------------------------------------------------------- 1 | >4 -------------------------------------------------------------------------------- /tests/_all/switch_if.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() { 3 | int i = 0; 4 | 5 | switch (i) { 6 | case 0: { 7 | if (i == 0) { 8 | break; 9 | } else if (i >= 0) { 10 | printf("First statement"); 11 | break; 12 | printf("Second statement"); 13 | } else { 14 | printf("Third statement"); 15 | break; 16 | } 17 | } 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /tests/_all/switch_if.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/switch_if.golden -------------------------------------------------------------------------------- /tests/_all/tcc-expansion.golden: -------------------------------------------------------------------------------- 1 | jo jno jb jc jnae jnb jnc jae je jz jne jnz jbe jna jnbe ja js jns jp jpe jnp jpo jl jnge jnl jge jle jng jnle jg 2 | abcdef 3 | abcdef 4 | -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/global-simple.c: -------------------------------------------------------------------------------- 1 | int x, y, z; 2 | 3 | void putstring(char *s) { 4 | while (*s) { 5 | putchar(*s); 6 | s = s + 1; 7 | } 8 | } 9 | 10 | void testGlobalMultipleVariableDeclaration() { 11 | x = 4; 12 | y = 5; 13 | z = 6; 14 | 15 | putstring("Global Variables:\n"); 16 | putchar(x+48); 17 | putchar(10); 18 | putchar(y+48); 19 | putchar(10); 20 | putchar(z+48); 21 | putchar(10); 22 | } 23 | 24 | int a = 4, b = 5, c = 6; 25 | 26 | void testGlobalMultipleVariableDeclarationInitialization() { 27 | putstring("Global Variables Initialized:\n"); 28 | putchar(a+48); 29 | putchar(10); 30 | putchar(b+48); 31 | putchar(10); 32 | putchar(c+48); 33 | putchar(10); 34 | } 35 | 36 | int main() { 37 | testGlobalMultipleVariableDeclaration(); 38 | testGlobalMultipleVariableDeclarationInitialization(); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/global-simple.golden: -------------------------------------------------------------------------------- 1 | Global Variables: 2 | 4 3 | 5 4 | 6 5 | Global Variables Initialized: 6 | 4 7 | 5 8 | 6 9 | -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/local-global-interaction-simple.c: -------------------------------------------------------------------------------- 1 | 2 | int global1, global2; 3 | 4 | void putstring(char *s) { 5 | while (*s) { 6 | putchar(*s); 7 | s = s + 1; 8 | } 9 | } 10 | 11 | void testLocalAndGlobalInteraction() { 12 | int local1, local2; 13 | global1 = 1; 14 | global2 = 2; 15 | local1 = 3; 16 | local2 = 4; 17 | putstring("Global Variables:\n"); 18 | putchar(global1+48); 19 | putchar(10); 20 | putchar(global2+48); 21 | putchar(10); 22 | putstring("Local Variables:\n"); 23 | putchar(local1+48); 24 | putchar(10); 25 | putchar(local2+48); 26 | putchar(10); 27 | } 28 | 29 | int global3 = 1, global4 = 2; 30 | 31 | void testLocalAndGlobalInteractionInitialization() { 32 | int local3 = 3, local4 = 4; 33 | putstring("Global Variables Initialized:\n"); 34 | putchar(global3+48); 35 | putchar(10); 36 | putchar(global4+48); 37 | putchar(10); 38 | putstring("Local Variables Initialized:\n"); 39 | putchar(local3+48); 40 | putchar(10); 41 | putchar(local4+48); 42 | } 43 | 44 | int main() { 45 | testLocalAndGlobalInteraction(); 46 | testLocalAndGlobalInteractionInitialization(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/local-global-interaction-simple.golden: -------------------------------------------------------------------------------- 1 | Global Variables: 2 | 1 3 | 2 4 | Local Variables: 5 | 3 6 | 4 7 | Global Variables Initialized: 8 | 1 9 | 2 10 | Local Variables Initialized: 11 | 3 12 | 4 -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/local-simple.c: -------------------------------------------------------------------------------- 1 | 2 | void testLocalMultipleVariableDeclaration() { 3 | int a; 4 | int b, c; 5 | a = 1; 6 | b = 2; 7 | c = 3; 8 | 9 | putchar(a+48); 10 | putchar(10); 11 | putchar(b+48); 12 | putchar(10); 13 | putchar(c+48); 14 | putchar(10); 15 | } 16 | 17 | void testLocalMultipleVariableDeclarationInitialization() { 18 | int a = 1, b = 2, c = 3; 19 | 20 | putchar(a+48); 21 | putchar(10); 22 | putchar(b+48); 23 | putchar(10); 24 | putchar(c+48); 25 | putchar(10); 26 | } 27 | 28 | int main() { 29 | testLocalMultipleVariableDeclaration(); 30 | testLocalMultipleVariableDeclarationInitialization(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/local-simple.golden: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 1 5 | 2 6 | 3 7 | -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/shadowing-globals.c: -------------------------------------------------------------------------------- 1 | int x = 1, y, z = 2; 2 | 3 | void putstring(char *s) { 4 | while (*s) { 5 | putchar(*s); 6 | s = s + 1; 7 | } 8 | } 9 | 10 | void testShadowingGlobals() { 11 | int x = 0, z = 3; 12 | y = 4; 13 | putchar(x + 48); 14 | putchar(10); 15 | putchar(y + 48); 16 | putchar(10); 17 | putchar(z + 48); 18 | putchar(10); 19 | } 20 | 21 | int main() { 22 | putstring("Test Shadowing Globals:\n"); 23 | testShadowingGlobals(); 24 | putstring("Global Variables:\n"); 25 | putchar(x + 48); 26 | putchar(10); 27 | putchar(y + 48); 28 | putchar(10); 29 | putchar(z + 48); 30 | putchar(10); 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /tests/_all/variable-declaration-tests/shadowing-globals.golden: -------------------------------------------------------------------------------- 1 | Test Shadowing Globals: 2 | 0 3 | 4 4 | 3 5 | Global Variables: 6 | 1 7 | 4 8 | 2 9 | -------------------------------------------------------------------------------- /tests/_all/void_cast.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char** argv) { 2 | (void) argc; 3 | (void) argc; 4 | 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /tests/_all/void_cast.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_all/void_cast.golden -------------------------------------------------------------------------------- /tests/_all/void_functions.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int test(void); // Forward declaration 4 | 5 | int test(void) { 6 | putchar('T'); putchar('\n'); 7 | return 0; 8 | } 9 | 10 | int main(void) { 11 | return test(); 12 | } 13 | -------------------------------------------------------------------------------- /tests/_all/void_functions.golden: -------------------------------------------------------------------------------- 1 | T 2 | -------------------------------------------------------------------------------- /tests/_bug/negative-zero.c: -------------------------------------------------------------------------------- 1 | // On ksh, when assigning the negative value of a variable containing 0 (i.e. 2 | // -0) to a variable using arithmetic expansion, the variable is assigned the 3 | // string `-0` instead of 0. Other shells assign 0 as expected. 4 | 5 | // expect_failure_for: ksh 6 | int return0() { 7 | int a = 0; 8 | return -a; 9 | } 10 | 11 | void putstring(char *s) { 12 | while (*s) { 13 | putchar(*s); 14 | s = s + 1; 15 | } 16 | } 17 | 18 | void main() { 19 | // Workaround: use `return0() + 0 == 0`. 20 | // This forces the result of return0 to be in an arithmetic expansion which removes the `-` from `-0`. 21 | if (return0() == 0) { 22 | putstring("zero\n"); 23 | } else { 24 | putstring("non-zero\n"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/_bug/negative-zero.golden: -------------------------------------------------------------------------------- 1 | zero 2 | -------------------------------------------------------------------------------- /tests/_bug/self-reference-macro-with-macro-args.c: -------------------------------------------------------------------------------- 1 | // When a macro argument is expanded, tokens that are themselves macros are 2 | // expanded. This is problematic when the macro argument contains a 3 | // self-referencial macro, since each time the macro is passed as argument, it 4 | // is expanded for one step, even when the macro should not be expanded because 5 | // it was expanded previously. 6 | 7 | // expect_failure 8 | 9 | #include 10 | 11 | int x = 4; 12 | int y = 5; 13 | 14 | void putdigit(int n) { 15 | putchar('0' + n); 16 | putchar('\n'); 17 | } 18 | 19 | void B(int a) { 20 | putdigit(a); 21 | } 22 | 23 | #define x 1 + y 24 | #define y 1 + x 25 | #define A(a1) B(a1) 26 | #define B(a1) A(a1) 27 | 28 | void main() { 29 | B(x); 30 | B(y); 31 | } 32 | -------------------------------------------------------------------------------- /tests/_bug/self-reference-macro-with-macro-args.golden: -------------------------------------------------------------------------------- 1 | 6 2 | 7 3 | -------------------------------------------------------------------------------- /tests/_exe/anonymous-struct.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void putstr(char* s) { 4 | while (*s) { 5 | putchar(*s); 6 | s += 1; 7 | } 8 | } 9 | 10 | void putint_aux(int n) { 11 | if (n <= -10) putint_aux(n / 10); 12 | putchar('0' - (n % 10)); 13 | } 14 | 15 | void putint(int n) { 16 | if (n < 0) { 17 | putchar('-'); 18 | putint_aux(n); 19 | } else { 20 | putint_aux(-n); 21 | } 22 | } 23 | 24 | struct Point { 25 | int a; 26 | struct { // Anonymous struct 27 | int b; 28 | int c; 29 | }; 30 | }; 31 | 32 | int main() { 33 | struct Point p; 34 | p.a = 5; 35 | p.b = 6; 36 | p.c = 7; 37 | putint(p.a); putchar('\n'); 38 | putint(p.b); putchar('\n'); 39 | putint(p.c); putchar('\n'); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /tests/_exe/anonymous-struct.golden: -------------------------------------------------------------------------------- 1 | 5 2 | 6 3 | 7 4 | -------------------------------------------------------------------------------- /tests/_exe/array-function-param.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined (PNUT_I386) 4 | #define MUL 1 5 | #elif defined (PNUT_X86_64) 6 | #define MUL 2 7 | #else 8 | #define MUL 2 9 | #endif 10 | 11 | void putint_aux(int n) { 12 | if (n <= -10) putint_aux(n / 10); 13 | putchar('0' - (n % 10)); 14 | } 15 | 16 | void putint(int n) { 17 | if (n < 0) { 18 | putchar('-'); 19 | putint_aux(n); 20 | } else { 21 | putint_aux(-n); 22 | } 23 | } 24 | 25 | void f(int a[10]) { 26 | int b[10]; 27 | putint(sizeof(a) / MUL); putchar('\n'); // Should be a pointer 28 | putint(sizeof(b)); putchar('\n'); // Should be 10 * sizeof(int) 29 | int i = 0; 30 | while (i < 10) { 31 | putchar('\''); putint(a[i]); putchar('\''); putchar(' '); 32 | i++; 33 | } 34 | } 35 | 36 | int main() { 37 | int a[10] = { 0, 1, 2, 3 }; 38 | f(a); putchar('\n'); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tests/_exe/array-function-param.golden: -------------------------------------------------------------------------------- 1 | 4 2 | 40 3 | '0' '1' '2' '3' '0' '0' '0' '0' '0' '0' 4 | -------------------------------------------------------------------------------- /tests/_exe/fixed-width/literals.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void putstr(char* s) { 4 | while (*s) { 5 | putchar(*s); 6 | s++; 7 | } 8 | } 9 | 10 | void main() { 11 | int a = 0x12345678; 12 | 13 | // Tests that casts properly truncate the value 14 | if (a == (char) a) { 15 | putstr("!!! a == (char) a\n"); 16 | } else { 17 | putstr("a != (char) a\n"); 18 | } 19 | 20 | // Again 21 | if (a == (short) a) { 22 | putstr("!!! a == (short) a\n"); 23 | } else { 24 | putstr("a != (short) a\n"); 25 | } 26 | 27 | // Again, but this time the cast is to int so it should be equal 28 | if (a == (int) a) { 29 | putstr("a == (int) a\n"); 30 | } else { 31 | putstr("!!! a != (int) a\n"); 32 | } 33 | 34 | // Again, but with a cast to a wider type 35 | if (a == (long) a) { 36 | putstr("a == (long) a\n"); 37 | } else { 38 | putstr("!!! a != (long) a\n"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/_exe/fixed-width/literals.golden: -------------------------------------------------------------------------------- 1 | a != (char) a 2 | a != (short) a 3 | a == (int) a 4 | a == (long) a 5 | -------------------------------------------------------------------------------- /tests/_exe/goto.c: -------------------------------------------------------------------------------- 1 | void simpleGoto() { 2 | putchar('A'); 3 | goto label; 4 | putchar('B'); 5 | label: 6 | putchar('C'); 7 | putchar(10); 8 | } 9 | 10 | void complexGoto() { 11 | putchar('A'); 12 | goto label; 13 | putchar('B'); 14 | label: 15 | putchar('C'); 16 | putchar('D'); 17 | goto label2; 18 | putchar('E'); 19 | label2: 20 | putchar('F'); 21 | putchar(10); 22 | } 23 | 24 | void loopGoto() { 25 | int i = 0; 26 | putchar('A'); 27 | label: 28 | putchar('B'); 29 | i++; 30 | if (i < 3) { 31 | goto label; 32 | } 33 | putchar('C'); 34 | putchar(10); 35 | } 36 | 37 | void loop2Goto(){ 38 | int i = 0; 39 | 40 | loop: 41 | if (i >= 3) goto end; 42 | putchar('X'); 43 | i++; 44 | goto loop; 45 | 46 | end: 47 | putchar('Y'); 48 | } 49 | 50 | void breakGoto() { 51 | int i = 0; 52 | putchar('A'); 53 | label: 54 | putchar('B'); 55 | i++; 56 | if (i < 3) { 57 | goto end; 58 | } 59 | putchar('C'); 60 | putchar(10); 61 | end: 62 | putchar('D'); 63 | putchar(10); 64 | } 65 | 66 | int main() { 67 | simpleGoto(); 68 | complexGoto(); 69 | loopGoto(); 70 | loop2Goto(); 71 | breakGoto(); 72 | return 0; 73 | } -------------------------------------------------------------------------------- /tests/_exe/goto.golden: -------------------------------------------------------------------------------- 1 | AC 2 | ACDF 3 | ABBBC 4 | XXXYABD 5 | -------------------------------------------------------------------------------- /tests/_exe/indirect-calls.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void putstr(char *s) { 4 | while (*s) { 5 | putchar(*s); 6 | s += 1; 7 | } 8 | } 9 | 10 | void f(int direct) { 11 | if (direct) { 12 | putstr("direct\n"); 13 | } else { 14 | putstr("indirect\n"); 15 | } 16 | } 17 | 18 | void fun1() { 19 | putstr("fun1\n"); 20 | } 21 | 22 | void fun2() { 23 | putstr("fun2\n"); 24 | } 25 | 26 | void fun3() { 27 | putstr("fun3\n"); 28 | } 29 | 30 | void fun4() { 31 | putstr("fun4\n"); 32 | } 33 | 34 | void (*funs[4])() = {&fun1, &fun2, *fun3, **fun4}; 35 | 36 | void calls_funs(void (*funs[])(), int n) { 37 | int i; 38 | for (i = 0; i < n; i++) { 39 | funs[i](); 40 | } 41 | } 42 | 43 | void call_fun(void (fun)(), char *msg) { 44 | void (fun2)(); 45 | fun(msg); 46 | (*fun)(msg); 47 | (**fun)(msg); 48 | } 49 | 50 | int main() { 51 | calls_funs(funs, 4); 52 | void (*f_ptr1)() = f; 53 | void (*f_ptr2)() = &f; 54 | void (*f_ptr3)() = *f; 55 | void (*f_ptr4)() = *****f; 56 | f(1); 57 | f_ptr1(0); 58 | (*f_ptr1)(0); 59 | (*f_ptr1)(0); 60 | (***f_ptr1)(0); 61 | f_ptr2(0); 62 | f_ptr3(0); 63 | f_ptr4(0); 64 | call_fun(putstr, "hello\n"); 65 | call_fun(*putstr, "hello\n"); 66 | call_fun(&putstr, "hello\n"); 67 | call_fun(**putstr, "hello\n"); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /tests/_exe/indirect-calls.golden: -------------------------------------------------------------------------------- 1 | fun1 2 | fun2 3 | fun3 4 | fun4 5 | direct 6 | indirect 7 | indirect 8 | indirect 9 | indirect 10 | indirect 11 | indirect 12 | indirect 13 | hello 14 | hello 15 | hello 16 | hello 17 | hello 18 | hello 19 | hello 20 | hello 21 | hello 22 | hello 23 | hello 24 | hello 25 | -------------------------------------------------------------------------------- /tests/_exe/initializers-global.golden: -------------------------------------------------------------------------------- 1 | '60' '61' '158' '62' '61' '157' '33' '61' '149' '38' '38' '144' '124' '124' '145' '43' '43' '130' '45' '45' '128' '61' '61' '148' '60' '60' '60' '62' '62' '62' '43' '61' '176' '45' '61' '177' '42' '61' '178' '47' '61' '179' '37' '61' '180' '38' '61' '181' '94' '61' '183' '124' '61' '182' '45' '62' '160' '46' '46' '162' '35' '35' '163' '0' 2 | '72' '101' '108' '108' '111' '44' '32' '119' '111' '114' '108' '100' 3 | 1 2 3 4 4 | 1 204 0 0 5 | 1 2 3 4 6 | 42 7 | '1' '101' '3' '4' '33' 8 | '97' '98' '99' '100' '101' '0' 9 | 1 2 10 | 1 0 11 | 1 2 12 | 4321 123 13 | 12000 110 14 | 42 39 15 | 32 23 16 | 0 0 17 | 123 432131 18 | 4311 53141 19 | 5311 421313 20 | 2131321 21 | 12321 21321 22 | 0 0 23 | 0 0 24 | 421321431 25 | 231321 4531321 26 | 0 0 27 | 0 0 28 | 0 29 | -------------------------------------------------------------------------------- /tests/_exe/initializers-local.golden: -------------------------------------------------------------------------------- 1 | 13 29 2 | 13 29 3 | 1 2 3 4 4 | 1 204 0 0 5 | 1 2 3 4 6 | 42 7 | '1' '101' '3' '4' '33' 8 | '97' '98' '99' '100' '101' '0' 9 | 1 2 10 | 1 0 11 | 1 2 12 | 4321 123 13 | 12000 110 14 | 42 39 15 | 32 23 16 | 0 0 17 | 123 432131 18 | 4311 53141 19 | 5311 421313 20 | 2131321 21 | 12321 21321 22 | 0 0 23 | 0 0 24 | 421321431 25 | 231321 4531321 26 | 0 0 27 | 0 0 28 | 0 29 | -------------------------------------------------------------------------------- /tests/_exe/input-output/all-chars.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_exe/input-output/all-chars.txt -------------------------------------------------------------------------------- /tests/_exe/input-output/printf.golden: -------------------------------------------------------------------------------- 1 | Hello world! 42 A ff 2 | -------------------------------------------------------------------------------- /tests/_exe/input-output/read-all-chars.c: -------------------------------------------------------------------------------- 1 | // Make sure we can read all 256 characters. This is to make sure the utilities 2 | // we compile using pnut-sh can process all kind of files. 3 | // This test is not essential for the bootstrap, but since we'd like to use pnut 4 | // in other contexts, we want to make sure it can handle all characters. 5 | 6 | #ifndef PNUT_CC 7 | #include 8 | #else 9 | typedef int FILE; 10 | #endif 11 | 12 | void main() { 13 | int i = 0; 14 | char c; 15 | FILE *f = fopen("tests/_exe/input-output/all-chars.txt", "r"); 16 | while ((c = fgetc(f)) != -1) { 17 | putchar(c); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/_exe/input-output/read-all-chars.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_exe/input-output/read-all-chars.golden -------------------------------------------------------------------------------- /tests/_exe/pointer-comparisons.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void putint(int n) { 4 | if (n < 0) { 5 | putchar('-'); 6 | n = -n; 7 | } 8 | if (n >= 10) { 9 | putint(n / 10); 10 | } 11 | putchar('0' + n % 10); 12 | } 13 | 14 | int *fun() { 15 | return 0; 16 | } 17 | 18 | void main() { 19 | char c = 15; 20 | c = (fun() != 0) ^ c; 21 | putint(c); putchar('\n'); 22 | c = (fun() != 1) ^ c; 23 | putint(c); putchar('\n'); 24 | } 25 | -------------------------------------------------------------------------------- /tests/_exe/pointer-comparisons.golden: -------------------------------------------------------------------------------- 1 | 15 2 | 14 3 | -------------------------------------------------------------------------------- /tests/_exe/record-of-functions.golden: -------------------------------------------------------------------------------- 1 | hello 2 | WEEE WOOO 3 | WOOO WEEE 4 | -------------------------------------------------------------------------------- /tests/_exe/sizeof.golden: -------------------------------------------------------------------------------- 1 | 1 2 | 4 3 | 40 4 | 80 5 | 40 6 | 40 7 | 16 8 | 16 9 | 1 10 | 1 11 | 8 12 | 12 13 | 8 14 | 4 15 | 4 16 | 8 17 | 5 18 | 5 19 | 10 20 | 25 21 | 8 22 | 5 23 | 8 24 | 9 25 | 6 26 | 8 27 | 8 28 | 60 29 | -------------------------------------------------------------------------------- /tests/_exe/static_vars.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void putint(int n) { 4 | if (n < 0) { 5 | putchar('-'); 6 | n = -n; 7 | } 8 | if (n > 9) { 9 | putint(n / 10); 10 | } 11 | putchar('0' + n % 10); 12 | } 13 | 14 | static int n_calls = 0; // Global static variable 15 | 16 | int f() { 17 | int i = 0; // Some local varaible 18 | static int n_calls = 0; // Local static variable shadowing the global one 19 | int j = 10; 20 | return n_calls++ + i + j; 21 | } 22 | 23 | struct S { 24 | int a[10]; 25 | }; 26 | 27 | void g() { 28 | static struct S s_g = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; 29 | 30 | int i = 0; 31 | while (i < 10) { 32 | putchar('\''); putint(s_g.a[i]); putchar('\''); putchar(' '); 33 | i++; 34 | } 35 | } 36 | 37 | void h() { 38 | static struct S s_h = { { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 } }; 39 | 40 | int i = 0; 41 | while (i < 10) { 42 | putchar('\''); putint(s_h.a[i]); putchar('\''); putchar(' '); 43 | i++; 44 | } 45 | putchar('\n'); 46 | } 47 | 48 | int main() { 49 | putint(n_calls); putchar('\n'); 50 | putint(f()); putchar('\n'); 51 | putint(f()); putchar('\n'); // Check that the local static variable is incremented 52 | n_calls = 5; // Modifying the global static variable, not the local one 53 | putint(n_calls); putchar('\n'); 54 | putint(f()); putchar('\n'); // Check that the local static variable wasn't modified by `n_calls = 5` 55 | putint(n_calls); putchar('\n'); 56 | putint(f()); putchar('\n'); 57 | 58 | g(); 59 | h(); 60 | g(); 61 | h(); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /tests/_exe/static_vars.golden: -------------------------------------------------------------------------------- 1 | 0 2 | 10 3 | 11 4 | 5 5 | 12 6 | 5 7 | 13 8 | '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '11' '12' '13' '14' '15' '16' '17' '18' '19' '20' 9 | '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '11' '12' '13' '14' '15' '16' '17' '18' '19' '20' 10 | -------------------------------------------------------------------------------- /tests/_exe/struct-flexible-array.golden: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /tests/_exe/struct.golden: -------------------------------------------------------------------------------- 1 | # test_enums 2 | Direction: 0 1 3 | Direction: 2 3 4 | # test_stack_structs 5 | pt2: 15 16 6 | 0 0 7 | 1 1 8 | 2 4 9 | # test_heap_structs 10 | r1: 6 5 11 | r2: 8 7 12 | # test_static_structs 13 | point_static1: 5 12 14 | point_static2: 0 0 15 | point_static1: 5 12 16 | point_static2: 5 12 17 | points_static[0]: 1 2 18 | points_static[1]: 3 4 19 | points_static[2]: 1 2 20 | # test_struct_assignment 21 | pt1: 5 6 22 | pt2: 5 6 23 | 0 0 24 | 1 1 25 | 2 4 26 | # test_ptr_arith 27 | # test_nested_structs 28 | 2 4 0 0 29 | 3 9 1 1 30 | 4 16 2 4 31 | ns1: 1 2 3 4 5 6 32 | ns2 before: 1 2 3 4 5 6 33 | # test_passing_as_value 34 | pt: 5 6 35 | pass_as_value: Point: 5 6 36 | pass_as_value: Point: 123 456 37 | pt: 5 6 38 | pass_as_ref: Point: 5 6 39 | pass_as_ref: Point: 123 456 40 | pt after pass_as_ref: 123 456 41 | shape_stack: 5 6 42 | pass_as_value: Point: 5 6 43 | pass_as_value: Point: 123 456 44 | shape_stack: 5 6 45 | pass_as_ref: Point: 5 6 46 | pass_as_ref: Point: 123 456 47 | shape_stack after pass_as_ref: 123 456 48 | # test_casts 49 | 0 0 0 0 50 | 13 17 19 23 51 | 26 34 38 46 52 | 39 51 57 69 53 | 52 68 76 92 54 | -------------------------------------------------------------------------------- /tests/_exe/switch.golden: -------------------------------------------------------------------------------- 1 | 2 | 3 | DABCD 4 | DABCD 5 | ABC 6 | AABCA 7 | -D-AB-D-C-D- 8 | -D-CAB-D-CC-D-C 9 | A 10 | CE 11 | ABCE 12 | ABCDE 13 | DT 14 | BCDEFGHABCDEFGH 15 | ABA 16 | EE 17 | -------------------------------------------------------------------------------- /tests/_exe/tagged-union.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void putstr(char* s) { 5 | while (*s) { 6 | putchar(*s); 7 | s += 1; 8 | } 9 | } 10 | 11 | void putint(int n) { 12 | if (n < 0) { 13 | putchar('-'); 14 | n = -n; 15 | } 16 | if (n >= 10) { 17 | putint(n / 10); 18 | } 19 | putchar('0' + n % 10); 20 | } 21 | 22 | enum OP { 23 | IMM, 24 | ADD, 25 | }; 26 | 27 | struct Instruction { 28 | enum OP code; 29 | union { 30 | int imm; 31 | struct { 32 | struct Instruction* r1; 33 | struct Instruction* r2; 34 | }; 35 | }; 36 | }; 37 | 38 | int eval(struct Instruction *instr) { 39 | switch (instr->code) { 40 | case IMM: return instr->imm; 41 | case ADD: return eval(instr->r1) + eval(instr->r2); 42 | default: return 0; 43 | } 44 | } 45 | 46 | struct Instruction* imm(int val) { 47 | struct Instruction* instr = (struct Instruction*) malloc(sizeof(struct Instruction)); 48 | instr->code = IMM; 49 | instr->imm = val; 50 | return instr; 51 | } 52 | 53 | struct Instruction* add(struct Instruction* r1, struct Instruction* r2) { 54 | struct Instruction* instr = (struct Instruction*) malloc(sizeof(struct Instruction)); 55 | instr->code = ADD; 56 | instr->r1 = r1; 57 | instr->r2 = r2; 58 | return instr; 59 | } 60 | 61 | int main() { 62 | struct Instruction instr; 63 | struct Instruction imm1; 64 | imm1.code = IMM; 65 | imm1.imm = 5; 66 | 67 | instr.code = ADD; 68 | instr.r1 = &imm1; 69 | instr.r2 = &imm1; 70 | putstr("(stack allocated) 5 + 5 = "); 71 | putint(eval(&instr)); 72 | putchar('\n'); 73 | 74 | putstr("(heap allocated) 5 + 10 = "); 75 | putint(eval(add(imm(5), imm(10)))); 76 | putchar('\n'); 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /tests/_exe/tagged-union.golden: -------------------------------------------------------------------------------- 1 | (stack allocated) 5 + 5 = 10 2 | (heap allocated) 5 + 10 = 15 3 | -------------------------------------------------------------------------------- /tests/_exe/typedef.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void putstr(char* s) { 5 | while (*s) { 6 | putchar(*s); 7 | s += 1; 8 | } 9 | } 10 | 11 | void putint_aux(int n) { 12 | if (n <= -10) putint_aux(n / 10); 13 | putchar('0' - (n % 10)); 14 | } 15 | 16 | void putint(int n) { 17 | if (n < 0) { 18 | putchar('-'); 19 | putint_aux(n); 20 | } else { 21 | putint_aux(-n); 22 | } 23 | } 24 | 25 | struct Point { 26 | int a; 27 | int b; 28 | }; 29 | 30 | typedef struct Point3 { 31 | int x; 32 | int y; 33 | int z; 34 | } Point; // Voluntarily redefine Point 35 | 36 | void main() { 37 | struct Point p; 38 | p.a = 5; 39 | p.b = 6; 40 | putstr("Point: "); putint(p.a); putstr(" "); putint(p.b); putchar('\n'); 41 | Point p3; 42 | p3.x = 7; 43 | p3.y = 8; 44 | p3.z = 9; 45 | putstr("Point: "); putint(p3.x); putstr(" "); putint(p3.y); putstr(" "); putint(p3.z); putchar('\n'); 46 | } 47 | -------------------------------------------------------------------------------- /tests/_exe/typedef.golden: -------------------------------------------------------------------------------- 1 | Point: 5 6 2 | Point: 7 8 9 3 | -------------------------------------------------------------------------------- /tests/_sh/checks/address_of_global.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | int a; 3 | 4 | void main() { 5 | int* b = &a; 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/address_of_global.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/address_of_global.c:7:0 comp_rvalue_go: can't take the address of a local variable 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/address_of_local.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int a; 4 | int* b = &a; 5 | } 6 | -------------------------------------------------------------------------------- /tests/_sh/checks/address_of_local.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/address_of_local.c:6:0 comp_rvalue_go: can't take the address of a local variable 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/break_outside_loop.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | break; 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/break_outside_loop.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/break_outside_loop.c:5:0 comp_statement: break not in loop or switch 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/continue_outside_loop.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | continue; 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/continue_outside_loop.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/continue_outside_loop.c:5:0 comp_statement: continue not in loop 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/extern_vars.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | extern int some_var; 3 | 4 | void main() { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/extern_vars.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/extern_vars.c:3:0 Extern storage class specifier not supported 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/global_var_underscore.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | int _IFS; 3 | 4 | void main() { 5 | return; 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/global_var_underscore.golden: -------------------------------------------------------------------------------- 1 | _IFS tests/_sh/checks/global_var_underscore.c:3:0 variable name is invalid. It can't start or end with '_'. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/initializer_nested.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | int arr[] = { {1, 2, 3}, {4, 5, 6} }; 3 | 4 | void main() { 5 | return; 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/initializer_nested.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/initializer_nested.c:2:14 nested initializer lists not supported 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/initializer_too_large.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | int arr[2] = {1, 2, 3}; 3 | 4 | void main() { 5 | return; 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/initializer_too_large.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/initializer_too_large.c:3:0 Array type is too small for initializer 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/initializer_too_large_str.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | char arr[2] = "ab"; 3 | 4 | void main() { 5 | return; 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/initializer_too_large_str.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/initializer_too_large_str.c:3:0 Array type is too small for initializer 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/invalid_printf.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | printf("%d %d %d", 1, 2); // Too few arguments 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/invalid_printf.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/invalid_printf.c:5:0 Not enough parameters for printf 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_array_arg.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int a[10]; 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_array_arg.golden: -------------------------------------------------------------------------------- 1 | "a" variable: tests/_sh/checks/local_array_arg.c:5:0 array/struct value type is not supported for shell backend. Use a reference type instead. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_array_param.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | struct Pair { 3 | int a; 4 | int b; 5 | }; 6 | 7 | void main(struct Pair a) { 8 | return; 9 | } 10 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_array_param.golden: -------------------------------------------------------------------------------- 1 | "a" variable: tests/_sh/checks/local_array_param.c:10:0 array/struct value type is not supported for shell backend. Use a reference type instead. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_struct_arg.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | struct Pair { 3 | int a; 4 | int b; 5 | }; 6 | 7 | void main() { 8 | struct Pair a; 9 | } 10 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_struct_arg.golden: -------------------------------------------------------------------------------- 1 | "a" variable: tests/_sh/checks/local_struct_arg.c:10:0 array/struct value type is not supported for shell backend. Use a reference type instead. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_struct_param.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | struct Pair { 3 | int a; 4 | int b; 5 | }; 6 | 7 | void main(struct Pair a) { 8 | return; 9 | } 10 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_struct_param.golden: -------------------------------------------------------------------------------- 1 | "a" variable: tests/_sh/checks/local_struct_param.c:10:0 array/struct value type is not supported for shell backend. Use a reference type instead. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_var_shadowing.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int a; 4 | int a; 5 | } 6 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_var_shadowing.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/local_var_shadowing.c:6:0 Variable is already in local environment 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_var_underscore.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int _a; 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/local_var_underscore.golden: -------------------------------------------------------------------------------- 1 | _a tests/_sh/checks/local_var_underscore.c:5:0 variable name is invalid. It can't start or end with '_'. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/shortcut_eval_outside_condition.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int a = f() && g(); 4 | int b = 1 && g(); 5 | int c = f() && 1; 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/shortcut_eval_outside_condition.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/shortcut_eval_outside_condition.c:7:0 comp_rvalue_go: && and || with function calls can only be used in tests 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/sizeof_array.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | typedef int arr[1000000]; 3 | 4 | void main() { 5 | int a = sizeof(arr); 6 | } 7 | -------------------------------------------------------------------------------- /tests/_sh/checks/sizeof_array.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/sizeof_array.c:7:0 comp_rvalue_go: sizeof is not supported for this type or expression 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/sizeof_expr.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int a = sizeof a; 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/sizeof_expr.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/sizeof_expr.c:5:0 comp_rvalue_go: sizeof is not supported for this type or expression 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/static_vars.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | 3 | static int some_var; // Allowed 4 | 5 | void main() { 6 | static int some_other_var; // Static local vars are not supported 7 | } 8 | -------------------------------------------------------------------------------- /tests/_sh/checks/static_vars.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/static_vars.c:8:0 Extern and static storage class specifier not supported on local variables 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/struct_no_nested_array.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | 3 | struct A { 4 | int a[3]; 5 | int a; 6 | }; 7 | 8 | void main() { 9 | return; 10 | } 11 | -------------------------------------------------------------------------------- /tests/_sh/checks/struct_no_nested_array.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/struct_no_nested_array.c:7:0 Nested structures not supported by shell backend. Use a reference type instead. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/struct_no_nested_struct.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | 3 | struct A { 4 | struct B { 5 | int a; 6 | int b; 7 | } b; 8 | }; 9 | 10 | void main() { 11 | return; 12 | } 13 | -------------------------------------------------------------------------------- /tests/_sh/checks/struct_no_nested_struct.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/struct_no_nested_struct.c:9:0 Nested structures not supported by shell backend. Use a reference type instead. 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/switch_early_exit.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | switch (1) { 4 | case 1: 5 | if (0) { 6 | break; 7 | } else { 8 | // This should not be allowed 9 | } 10 | case 2: 11 | return; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/_sh/checks/switch_early_exit.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/switch_early_exit.c:14:0 Early break out of a switch case is unsupported 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/switch_fallthrough.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | switch (1) { 4 | case 1: 5 | putchar('a'); 6 | case 2: 7 | putchar('b'); 8 | break; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/_sh/checks/switch_fallthrough.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/switch_fallthrough.c:11:0 case/default must be at the beginning of a switch conditional block 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/switch_no_body.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | switch (1) putchar('a'); 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/switch_no_body.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/switch_no_body.c:5:0 comp_statement: switch without body 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/ternary_with_fun_call.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int a = f() ? 1 : 2; // Valid 4 | int b = f() ? 1 : f(); // Invalid 5 | } 6 | -------------------------------------------------------------------------------- /tests/_sh/checks/ternary_with_fun_call.golden: -------------------------------------------------------------------------------- 1 | tests/_sh/checks/ternary_with_fun_call.c:6:0 Conditional function calls in ternary operator not allowed 2 | -------------------------------------------------------------------------------- /tests/_sh/checks/var_IFS.c: -------------------------------------------------------------------------------- 1 | // expect_comp_failure 2 | void main() { 3 | int IFS; 4 | } 5 | -------------------------------------------------------------------------------- /tests/_sh/checks/var_IFS.golden: -------------------------------------------------------------------------------- 1 | "IFS" tests/_sh/checks/var_IFS.c:5:0 variable name is invalid. It can't be 'IFS' or 'argv_'. 2 | -------------------------------------------------------------------------------- /tests/_sh/goto.c: -------------------------------------------------------------------------------- 1 | void main() { 2 | labelled_statement: 3 | putchar('a'); 4 | 5 | putchar('b'); 6 | another_labelled_statement: 7 | putchar('c'); 8 | putchar('d'); 9 | } 10 | -------------------------------------------------------------------------------- /tests/_sh/goto.golden: -------------------------------------------------------------------------------- 1 | abcd -------------------------------------------------------------------------------- /tests/_sh/initializer.c: -------------------------------------------------------------------------------- 1 | char str1[6] = "abcde"; 2 | char str2[12] = "abcdef"; 3 | char str3[] = "abcdef\t\t\t\t\t\t"; 4 | 5 | int arr1[5] = { 1, 2, 3, 'a', 'b' }; 6 | int arr2[15] = { 1, 2, 3, 'a', 'b' }; 7 | 8 | void main() { 9 | int i; 10 | 11 | for (i = 0; i < 6; i++) { 12 | printf("%c\n", str1[i]); 13 | } 14 | 15 | for (i = 0; i < 12; i++) { 16 | printf("%c\n", str2[i]); 17 | } 18 | 19 | for (i = 0; i < 13; i++) { 20 | printf("%c\n", str3[i]); 21 | } 22 | 23 | for (i = 0; i < 5; i++) { 24 | printf("%d\n", arr1[i]); 25 | } 26 | 27 | for (i = 0; i < 15; i++) { 28 | printf("%d\n", arr2[i]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/_sh/initializer.golden: -------------------------------------------------------------------------------- 1 | a 2 | b 3 | c 4 | d 5 | e 6 | 7 | a 8 | b 9 | c 10 | d 11 | e 12 | f 13 | 14 | 15 | 16 | 17 | 18 | 19 | a 20 | b 21 | c 22 | d 23 | e 24 | f 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 1 33 | 2 34 | 3 35 | 97 36 | 98 37 | 1 38 | 2 39 | 3 40 | 97 41 | 98 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | -------------------------------------------------------------------------------- /tests/_sh/input-output/all-chars.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_sh/input-output/all-chars.txt -------------------------------------------------------------------------------- /tests/_sh/input-output/printf.golden: -------------------------------------------------------------------------------- 1 | - - 2 | Hello, world! 3 | 42 4 | a 5 | Hello C-3PO 6 | Hello, world! 7 | Hello, world! R2-D2 8 | Hello, world! < ROBOT> 9 | Hello, world! < ROBOT> 10 | '42 ' 11 | 'a' 12 | '2a ' 13 | 'world ' 14 | ' +42' 15 | 'a' 16 | ' 2a' 17 | ' world' 18 | ' 42' 19 | '-42' 20 | '2a' 21 | 'world' 22 | ' 0x2a' 23 | '0x2a ' 24 | '052 ' 25 | '052 ' 26 | '42' 27 | '0042' 28 | '002a' 29 | ' 42' 30 | ' 42' 31 | ' Wooooooo' 32 | ' Wooooooo' 33 | '0042' 34 | '002a' 35 | '002A' 36 | 'Wooo' 37 | 'Wooo' 38 | 'a' 39 | '*' 40 | '' 41 | '42 a 2a world' 42 | ' 42 a 2a worl' 43 | -------------------------------------------------------------------------------- /tests/_sh/input-output/printf_runtime.c: -------------------------------------------------------------------------------- 1 | // comp_pnut_opt: -DSH_AVOID_PRINTF_USE_NOT 2 | 3 | #include "printf.c" 4 | -------------------------------------------------------------------------------- /tests/_sh/input-output/printf_runtime.golden: -------------------------------------------------------------------------------- 1 | - - 2 | Hello, world! 3 | 42 4 | a 5 | Hello C-3PO 6 | Hello, world! 7 | Hello, world! R2-D2 8 | Hello, world! < ROBOT> 9 | Hello, world! < ROBOT> 10 | '42 ' 11 | 'a' 12 | '2a ' 13 | 'world ' 14 | ' +42' 15 | 'a' 16 | ' 2a' 17 | ' world' 18 | ' 42' 19 | '-42' 20 | '2a' 21 | 'world' 22 | ' 0x2a' 23 | '0x2a ' 24 | '052 ' 25 | '052 ' 26 | '42' 27 | '0042' 28 | '002a' 29 | ' 42' 30 | ' 42' 31 | ' Wooooooo' 32 | ' Wooooooo' 33 | '0042' 34 | '002a' 35 | '002A' 36 | 'Wooo' 37 | 'Wooo' 38 | 'a' 39 | '*' 40 | '' 41 | '42 a 2a world' 42 | ' 42 a 2a worl' 43 | -------------------------------------------------------------------------------- /tests/_sh/input-output/read-all-chars.c: -------------------------------------------------------------------------------- 1 | // Make sure we can read all 256 characters. This is to make sure the utilities 2 | // we compile using pnut-sh can process all kind of files. 3 | // This test is not essential for the bootstrap, but since we'd like to use pnut 4 | // in other contexts, we want to make sure it can handle all characters. 5 | // For bash 2.05a, the character 1 is not read properly. Assuming all version 2.0* of bash are affected. 6 | // expect_failure_for: bash-2.0.* 7 | // Yash's IO is a little bit weird and it's not a very popular shell, disabling the test for now. 8 | // expect_failure_for: yash 9 | 10 | #ifndef PNUT_CC 11 | #include 12 | #else 13 | typedef int FILE; 14 | #endif 15 | 16 | void main() { 17 | int i = 0; 18 | char c; 19 | FILE *f = fopen("tests/_sh/input-output/all-chars.txt", "r"); 20 | while ((c = fgetc(f)) != -1) { 21 | putchar(c); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/_sh/input-output/read-all-chars.golden: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udem-dlteam/pnut/602954e06bdc7433173bbf2896ba3f24de3ec296/tests/_sh/input-output/read-all-chars.golden -------------------------------------------------------------------------------- /tests/_sh/nested_loops.c: -------------------------------------------------------------------------------- 1 | int foo() { 2 | int i, j; 3 | for (i = 0; i < 10; i++) { 4 | for (j = 0; j < 10; j++) { 5 | if (i == j && i == 5) { 6 | return i + j; 7 | } 8 | } 9 | } 10 | } 11 | 12 | void main() { 13 | printf("%d\n", foo()); 14 | } 15 | -------------------------------------------------------------------------------- /tests/_sh/nested_loops.golden: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /tests/_sh/scoping.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int glo1 = 12; 4 | 5 | void main() { 6 | printf("%d\n", glo1); 7 | { 8 | int glo1 = 13; 9 | printf("%d\n", glo1); 10 | } 11 | printf("%d\n", glo1); 12 | } 13 | -------------------------------------------------------------------------------- /tests/_sh/scoping.golden: -------------------------------------------------------------------------------- 1 | 12 2 | 13 3 | 12 4 | -------------------------------------------------------------------------------- /tests/_sh/struct.golden: -------------------------------------------------------------------------------- 1 | Shape 0: 0 0 0 0 2 | Shape 1: 1 1 1 1 3 | Shape 2: 2 4 2 4 4 | Rectangle 1: 1 2 5 | Point: 5 6 6 | Shape: 5 6 1 2 7 | pass_as_ref: Point: 5 6 8 | pass_as_ref: Point: 123 456 9 | Point: 123 456 10 | pass_as_ref_int: 123 11 | pass_as_ref_int: 42 12 | Point: 42 456 13 | arr[12]: 12 14 | pass_as_ref_int: 12 15 | pass_as_ref_int: 42 16 | arr[12]: 42 17 | -------------------------------------------------------------------------------- /tests/_sh/switch.golden: -------------------------------------------------------------------------------- 1 | BCCBABCDEFE -------------------------------------------------------------------------------- /utils/keywords.txt: -------------------------------------------------------------------------------- 1 | auto 2 | break 3 | case 4 | char 5 | const 6 | continue 7 | default 8 | do 9 | double 10 | else 11 | enum 12 | extern 13 | float 14 | for 15 | goto 16 | if 17 | int 18 | long 19 | register 20 | return 21 | short 22 | signed 23 | sizeof 24 | static 25 | struct 26 | switch 27 | typedef 28 | union 29 | unsigned 30 | void 31 | volatile 32 | while 33 | -------------------------------------------------------------------------------- /woody.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | if [ $# -eq 0 ]; then 5 | chroot woody /bin/bash -c "cd /pnut; bash" 6 | else 7 | chroot woody /bin/bash -c "cd /pnut; $@" 8 | fi 9 | --------------------------------------------------------------------------------