python-cc 0.0.5__tar.gz → 0.0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. python_cc-0.0.6/AGENTS.md +258 -0
  2. {python_cc-0.0.5 → python_cc-0.0.6}/PKG-INFO +74 -59
  3. python_cc-0.0.6/README.md +187 -0
  4. python_cc-0.0.6/docs/investigations/lua-sort-random-pivot-signedness.md +436 -0
  5. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/codegen/c_codegen.py +482 -120
  6. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/evaluater/c_evaluator.py +194 -12
  7. python_cc-0.0.6/pcc/pcc.py +88 -0
  8. python_cc-0.0.6/pcc/project.py +219 -0
  9. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lparser.c +1 -0
  10. {python_cc-0.0.5 → python_cc-0.0.6}/pyproject.toml +1 -1
  11. python_cc-0.0.6/tests/test_cli.py +20 -0
  12. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_lua.py +2 -0
  13. python_cc-0.0.6/tests/test_project.py +100 -0
  14. python_cc-0.0.6/tests/test_redefinitions.py +41 -0
  15. python_cc-0.0.6/tests/test_separate_tus.py +102 -0
  16. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_unsigned_loads.py +82 -0
  17. python_cc-0.0.5/README.md +0 -172
  18. python_cc-0.0.5/pcc/pcc.py +0 -38
  19. python_cc-0.0.5/pcc/project.py +0 -78
  20. {python_cc-0.0.5 → python_cc-0.0.6}/.github/workflows/workflow.yml +0 -0
  21. {python_cc-0.0.5 → python_cc-0.0.6}/.gitignore +0 -0
  22. {python_cc-0.0.5 → python_cc-0.0.6}/LICENSE +0 -0
  23. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/ackermann.c +0 -0
  24. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/basic_arithmetic.c +0 -0
  25. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/calculator_project/main.c +0 -0
  26. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/calculator_project/ops.c +0 -0
  27. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/calculator_project/stack.h +0 -0
  28. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/collatz.c +0 -0
  29. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/conditional.c +0 -0
  30. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/fibonacci.c +0 -0
  31. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/game_of_life.c +0 -0
  32. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/hanoi.c +0 -0
  33. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/mathutil.h +0 -0
  34. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/quicksort.c +0 -0
  35. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/search.h +0 -0
  36. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/sieve.c +0 -0
  37. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/sort_project/main.c +0 -0
  38. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/sort_project/sort.c +0 -0
  39. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/sort_project/sort.h +0 -0
  40. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/stack.h +0 -0
  41. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/standard_c.c +0 -0
  42. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/string_project/main.c +0 -0
  43. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/string_project/mystring.c +0 -0
  44. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/string_project/mystring.h +0 -0
  45. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/struct_layout.c +0 -0
  46. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/unsigned_cmp.c +0 -0
  47. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/use_mathutil.c +0 -0
  48. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/use_search.c +0 -0
  49. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/use_stack.c +0 -0
  50. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/use_vec.c +0 -0
  51. {python_cc-0.0.5 → python_cc-0.0.6}/c_tests/vec.h +0 -0
  52. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/.gitignore +0 -0
  53. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/README.md +0 -0
  54. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/and.c +0 -0
  55. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/cast.c +0 -0
  56. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/if.c +0 -0
  57. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/malloc.c +0 -0
  58. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/simple_func.c +0 -0
  59. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/simple_int.c +0 -0
  60. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/simple_pointer.c +0 -0
  61. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/simple_printf.c +0 -0
  62. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/simple_recurse.c +0 -0
  63. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/struct.c +0 -0
  64. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/test_arrary.c +0 -0
  65. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/test_double_array.c +0 -0
  66. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/test_if_else.c +0 -0
  67. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/test_int.c +0 -0
  68. {python_cc-0.0.5 → python_cc-0.0.6}/clang_study/test_puts.c +0 -0
  69. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/__init__.py +0 -0
  70. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/__main__.py +0 -0
  71. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ast/__init__.py +0 -0
  72. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ast/ast.py +0 -0
  73. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ast/ast_transforms.py +0 -0
  74. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ast/c_ast.py +0 -0
  75. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/codegen/__init__.py +0 -0
  76. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/evaluater/__init__.py +0 -0
  77. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/generator/__init__.py +0 -0
  78. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/generator/c_generator.py +0 -0
  79. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/lex/__init__.py +0 -0
  80. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/lex/c_lexer.py +0 -0
  81. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/lex/lexer.py +0 -0
  82. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/lex/token.py +0 -0
  83. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/parse/__init__.py +0 -0
  84. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/parse/c_parser.py +0 -0
  85. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/parse/file_parser.py +0 -0
  86. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/parse/parser.py +0 -0
  87. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/parse/plyparser.py +0 -0
  88. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ply/__init__.py +0 -0
  89. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ply/cpp.py +0 -0
  90. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ply/ctokens.py +0 -0
  91. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ply/lex.py +0 -0
  92. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ply/yacc.py +0 -0
  93. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/ply/ygen.py +0 -0
  94. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/preprocessor.py +0 -0
  95. {python_cc-0.0.5 → python_cc-0.0.6}/pcc/util.py +0 -0
  96. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/.gitignore +0 -0
  97. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/README.md +0 -0
  98. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/all +0 -0
  99. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lapi.c +0 -0
  100. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lapi.h +0 -0
  101. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lauxlib.c +0 -0
  102. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lauxlib.h +0 -0
  103. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lbaselib.c +0 -0
  104. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lcode.c +0 -0
  105. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lcode.h +0 -0
  106. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lcorolib.c +0 -0
  107. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lctype.c +0 -0
  108. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lctype.h +0 -0
  109. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ldblib.c +0 -0
  110. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ldebug.c +0 -0
  111. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ldebug.h +0 -0
  112. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ldo.c +0 -0
  113. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ldo.h +0 -0
  114. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ldump.c +0 -0
  115. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lfunc.c +0 -0
  116. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lfunc.h +0 -0
  117. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lgc.c +0 -0
  118. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lgc.h +0 -0
  119. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/linit.c +0 -0
  120. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/liolib.c +0 -0
  121. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ljumptab.h +0 -0
  122. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/llex.c +0 -0
  123. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/llex.h +0 -0
  124. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/llimits.h +0 -0
  125. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lmathlib.c +0 -0
  126. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lmem.c +0 -0
  127. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lmem.h +0 -0
  128. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/loadlib.c +0 -0
  129. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lobject.c +0 -0
  130. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lobject.h +0 -0
  131. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lopcodes.c +0 -0
  132. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lopcodes.h +0 -0
  133. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lopnames.h +0 -0
  134. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/loslib.c +0 -0
  135. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lparser.h +0 -0
  136. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lprefix.h +0 -0
  137. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lstate.c +0 -0
  138. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lstate.h +0 -0
  139. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lstring.c +0 -0
  140. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lstring.h +0 -0
  141. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lstrlib.c +0 -0
  142. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ltable.c +0 -0
  143. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ltable.h +0 -0
  144. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ltablib.c +0 -0
  145. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ltests.c +0 -0
  146. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ltests.h +0 -0
  147. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ltm.c +0 -0
  148. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/ltm.h +0 -0
  149. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lua.c +0 -0
  150. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lua.h +0 -0
  151. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/luaconf.h +0 -0
  152. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lualib.h +0 -0
  153. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lundump.c +0 -0
  154. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lundump.h +0 -0
  155. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lutf8lib.c +0 -0
  156. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lvm.c +0 -0
  157. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lvm.h +0 -0
  158. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lzio.c +0 -0
  159. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/lzio.h +0 -0
  160. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/makefile +0 -0
  161. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/manual/2html +0 -0
  162. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/manual/manual.of +0 -0
  163. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/onelua.c +0 -0
  164. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/all.lua +0 -0
  165. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/api.lua +0 -0
  166. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/attrib.lua +0 -0
  167. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/big.lua +0 -0
  168. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/bitwise.lua +0 -0
  169. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/bwcoercion.lua +0 -0
  170. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/calls.lua +0 -0
  171. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/closure.lua +0 -0
  172. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/code.lua +0 -0
  173. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/constructs.lua +0 -0
  174. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/coroutine.lua +0 -0
  175. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/cstack.lua +0 -0
  176. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/db.lua +0 -0
  177. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/errors.lua +0 -0
  178. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/events.lua +0 -0
  179. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/files.lua +0 -0
  180. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/gc.lua +0 -0
  181. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/gengc.lua +0 -0
  182. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/goto.lua +0 -0
  183. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/heavy.lua +0 -0
  184. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/libs/P1/dummy +0 -0
  185. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/libs/lib1.c +0 -0
  186. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/libs/lib11.c +0 -0
  187. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/libs/lib2.c +0 -0
  188. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/libs/lib21.c +0 -0
  189. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/libs/lib22.c +0 -0
  190. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/libs/makefile +0 -0
  191. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/literals.lua +0 -0
  192. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/locals.lua +0 -0
  193. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/main.lua +0 -0
  194. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/math.lua +0 -0
  195. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/memerr.lua +0 -0
  196. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/nextvar.lua +0 -0
  197. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/packtests +0 -0
  198. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/pm.lua +0 -0
  199. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/sort.lua +0 -0
  200. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/strings.lua +0 -0
  201. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/tpack.lua +0 -0
  202. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/tracegc.lua +0 -0
  203. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/utf8.lua +0 -0
  204. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/vararg.lua +0 -0
  205. {python_cc-0.0.5 → python_cc-0.0.6}/projects/lua-5.5.0/testes/verybig.lua +0 -0
  206. {python_cc-0.0.5 → python_cc-0.0.6}/tests/README.txt +0 -0
  207. {python_cc-0.0.5 → python_cc-0.0.6}/tests/__init__.py +0 -0
  208. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/cppd_with_stdio_h.c +0 -0
  209. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/empty.h +0 -0
  210. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/example_c_file.c +0 -0
  211. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/hdir/9/inc.h +0 -0
  212. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/memmgr.c +0 -0
  213. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/memmgr.h +0 -0
  214. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/memmgr_with_h.c +0 -0
  215. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/simplemain.c +0 -0
  216. {python_cc-0.0.5 → python_cc-0.0.6}/tests/c_files/year.c +0 -0
  217. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_advanced.py +0 -0
  218. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_algorithms.py +0 -0
  219. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_and.py +0 -0
  220. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_array.py +0 -0
  221. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_array_init.py +0 -0
  222. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_arrow.py +0 -0
  223. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_assign.py +0 -0
  224. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_bitwise.py +0 -0
  225. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_c_ast.py +0 -0
  226. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_c_evluater.py +0 -0
  227. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_c_files.py +0 -0
  228. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_c_generator.py +0 -0
  229. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_c_lexer.py +0 -0
  230. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_c_parser.py +0 -0
  231. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_cast.py +0 -0
  232. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_cast_int_to_double.py +0 -0
  233. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_char.py +0 -0
  234. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_comments.py +0 -0
  235. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_compound_assign.py +0 -0
  236. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_contract.py +0 -0
  237. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_div_mod.py +0 -0
  238. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_do_while.py +0 -0
  239. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_double.py +0 -0
  240. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_double_array.py +0 -0
  241. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_edge_cases.py +0 -0
  242. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_else_if.py +0 -0
  243. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_enum.py +0 -0
  244. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_expr_list.py +0 -0
  245. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_final.py +0 -0
  246. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_float_semantics.py +0 -0
  247. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_for.py +0 -0
  248. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_for_break.py +0 -0
  249. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_for_infinite.py +0 -0
  250. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_forward_decl.py +0 -0
  251. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_func_ptr.py +0 -0
  252. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_func_return_ptr.py +0 -0
  253. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_general.py +0 -0
  254. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_global.py +0 -0
  255. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_goto.py +0 -0
  256. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_hex_octal.py +0 -0
  257. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_if.py +0 -0
  258. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_if_else.py +0 -0
  259. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_int.py +0 -0
  260. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_integration.py +0 -0
  261. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_libc.py +0 -0
  262. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_libc_extra.py +0 -0
  263. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_libc_math.py +0 -0
  264. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_llvmliite_array.py +0 -0
  265. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_local.py +0 -0
  266. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_lua_features.py +0 -0
  267. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_main_arg.py +0 -0
  268. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_main_return_ptr.py +0 -0
  269. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_malloc.py +0 -0
  270. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_memset_free.py +0 -0
  271. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_mixed_types.py +0 -0
  272. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_named_struct.py +0 -0
  273. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_nest_loop.py +0 -0
  274. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_nest_loop1.py +0 -0
  275. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_param_array_decay.py +0 -0
  276. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_pointer.py +0 -0
  277. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_pre_inc_dec.py +0 -0
  278. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_preprocessor.py +0 -0
  279. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_printf.py +0 -0
  280. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_ptr_arith.py +0 -0
  281. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_real_programs.py +0 -0
  282. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_return_list.py +0 -0
  283. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_short_circuit.py +0 -0
  284. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_showcase.py +0 -0
  285. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_simple_func.py +0 -0
  286. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_simple_init_func_assign.py +0 -0
  287. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_simple_no_args.py +0 -0
  288. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_sizeof.py +0 -0
  289. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_static.py +0 -0
  290. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_string_escape.py +0 -0
  291. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_string_ptr.py +0 -0
  292. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_strlen_strcmp.py +0 -0
  293. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_struct.py +0 -0
  294. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_struct_array_member.py +0 -0
  295. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_switch.py +0 -0
  296. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_ternary.py +0 -0
  297. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_type_convert.py +0 -0
  298. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_type_modifiers.py +0 -0
  299. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_typedef.py +0 -0
  300. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_unary.py +0 -0
  301. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_union_const_init.py +0 -0
  302. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_union_ptrarray.py +0 -0
  303. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_varargs.py +0 -0
  304. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_void.py +0 -0
  305. {python_cc-0.0.5 → python_cc-0.0.6}/tests/test_while.py +0 -0
  306. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/_ansi.h +0 -0
  307. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/_fake_defines.h +0 -0
  308. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/_fake_typedefs.h +0 -0
  309. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/_syslist.h +0 -0
  310. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/alloca.h +0 -0
  311. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/ar.h +0 -0
  312. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/argz.h +0 -0
  313. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/arpa/inet.h +0 -0
  314. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/assert.h +0 -0
  315. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/complex.h +0 -0
  316. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/ctype.h +0 -0
  317. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/dirent.h +0 -0
  318. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/dlfcn.h +0 -0
  319. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/endian.h +0 -0
  320. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/envz.h +0 -0
  321. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/errno.h +0 -0
  322. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/fastmath.h +0 -0
  323. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/fcntl.h +0 -0
  324. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/features.h +0 -0
  325. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/fenv.h +0 -0
  326. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/float.h +0 -0
  327. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/getopt.h +0 -0
  328. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/grp.h +0 -0
  329. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/iconv.h +0 -0
  330. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/ieeefp.h +0 -0
  331. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/inttypes.h +0 -0
  332. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/iso646.h +0 -0
  333. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/langinfo.h +0 -0
  334. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/libgen.h +0 -0
  335. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/libintl.h +0 -0
  336. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/limits.h +0 -0
  337. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/linux/version.h +0 -0
  338. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/locale.h +0 -0
  339. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/malloc.h +0 -0
  340. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/math.h +0 -0
  341. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/netdb.h +0 -0
  342. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/netinet/in.h +0 -0
  343. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/netinet/tcp.h +0 -0
  344. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/newlib.h +0 -0
  345. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/openssl/err.h +0 -0
  346. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/openssl/evp.h +0 -0
  347. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/openssl/hmac.h +0 -0
  348. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/openssl/ssl.h +0 -0
  349. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/openssl/x509v3.h +0 -0
  350. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/paths.h +0 -0
  351. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/process.h +0 -0
  352. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/pthread.h +0 -0
  353. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/pwd.h +0 -0
  354. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/reent.h +0 -0
  355. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/regdef.h +0 -0
  356. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/regex.h +0 -0
  357. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sched.h +0 -0
  358. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/search.h +0 -0
  359. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/semaphore.h +0 -0
  360. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/setjmp.h +0 -0
  361. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/signal.h +0 -0
  362. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/stdarg.h +0 -0
  363. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/stdbool.h +0 -0
  364. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/stddef.h +0 -0
  365. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/stdint.h +0 -0
  366. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/stdio.h +0 -0
  367. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/stdlib.h +0 -0
  368. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/string.h +0 -0
  369. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/ioctl.h +0 -0
  370. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/mman.h +0 -0
  371. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/poll.h +0 -0
  372. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/resource.h +0 -0
  373. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/select.h +0 -0
  374. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/socket.h +0 -0
  375. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/stat.h +0 -0
  376. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/sysctl.h +0 -0
  377. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/time.h +0 -0
  378. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/types.h +0 -0
  379. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/uio.h +0 -0
  380. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/un.h +0 -0
  381. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/utsname.h +0 -0
  382. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/sys/wait.h +0 -0
  383. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/syslog.h +0 -0
  384. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/tar.h +0 -0
  385. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/termios.h +0 -0
  386. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/tgmath.h +0 -0
  387. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/time.h +0 -0
  388. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/unctrl.h +0 -0
  389. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/unistd.h +0 -0
  390. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/utime.h +0 -0
  391. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/utmp.h +0 -0
  392. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/wchar.h +0 -0
  393. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/wctype.h +0 -0
  394. {python_cc-0.0.5 → python_cc-0.0.6}/utils/fake_libc_include/zlib.h +0 -0
  395. {python_cc-0.0.5 → python_cc-0.0.6}/utils/internal/constptr.c +0 -0
  396. {python_cc-0.0.5 → python_cc-0.0.6}/utils/internal/example_c_file.c +0 -0
  397. {python_cc-0.0.5 → python_cc-0.0.6}/utils/internal/fake_includes.py +0 -0
  398. {python_cc-0.0.5 → python_cc-0.0.6}/utils/internal/make_fake_typedefs.py +0 -0
  399. {python_cc-0.0.5 → python_cc-0.0.6}/utils/internal/memprofiling.py +0 -0
  400. {python_cc-0.0.5 → python_cc-0.0.6}/utils/internal/zc.c +0 -0
  401. {python_cc-0.0.5 → python_cc-0.0.6}/utils/internal/zz_parse.py +0 -0
@@ -0,0 +1,258 @@
1
+ # AGENTS.md
2
+
3
+ This file is for humans and AI agents working in this repository.
4
+
5
+ ## Project Summary
6
+
7
+ `pcc` is a C compiler implemented in Python on top of `pycparser`, `llvmlite`, and a lightweight fake-libc layer. Most fixes in this repository are not parser bugs; they are semantic bugs that only show up when expressions are combined, lowered to LLVM IR, and then exercised by real programs.
8
+
9
+ The fastest way to get useful results is:
10
+
11
+ 1. Reproduce with a tiny C program when possible.
12
+ 2. Compare against a native compiler built from the same source.
13
+ 3. Add one small regression test and one realistic integration confirmation.
14
+
15
+
16
+ ## Environment Rules
17
+
18
+ - Use `uv run ...` for Python entrypoints. Do not rely on bare `python`; local `pyenv` state may not match the repository.
19
+ - For reproducible runs, prefer unsetting `LC_ALL`:
20
+
21
+ ```bash
22
+ env -u LC_ALL uv run pytest -q
23
+ env -u LC_ALL uv run python - <<'PY'
24
+ print("ok")
25
+ PY
26
+ env -u LC_ALL uv run pcc hello.c
27
+ ```
28
+
29
+ - While debugging one failure, prefer `-n0` so xdist does not hide ordering or temp-file problems.
30
+ - Use `rg` / `rg --files` for source discovery.
31
+ - Do not leave temporary `.c` files inside real project directories. Directory-based source collection can accidentally compile them.
32
+
33
+
34
+ ## Repository Map
35
+
36
+ - `pcc/pcc.py`
37
+ Command-line entrypoint.
38
+ - `pcc/project.py`
39
+ Directory collection, `--sources-from-make`, and translation-unit selection.
40
+ - `pcc/evaluater/c_evaluator.py`
41
+ Preprocessing, parsing, IR generation, LLVM parsing, optimization, and execution.
42
+ - `pcc/codegen/c_codegen.py`
43
+ Main semantic lowering logic. Most tricky C correctness bugs land here.
44
+ - `utils/fake_libc_include/`
45
+ Fake libc headers. Bugs here usually look like host ABI or declaration mismatches.
46
+ - `tests/`
47
+ Fast regression coverage. Add small tests here for every semantic fix.
48
+ - `projects/lua-5.5.0/`
49
+ Real-program stress target. Very effective for catching interactions missed by unit tests.
50
+
51
+
52
+ ## Source Collection Modes
53
+
54
+ The repository has multiple ways to compile projects. Be explicit about which one you are debugging.
55
+
56
+ - Single-file mode:
57
+ Compile exactly one `.c` file.
58
+ - Merged directory mode:
59
+ The default directory path behavior. It concatenates selected `.c` files into one large translation unit.
60
+ - `--separate-tus`:
61
+ Compile each `.c` as its own translation unit, then link at the LLVM/module layer.
62
+ - `--sources-from-make GOAL`:
63
+ Use `make -nB GOAL` to discover which `.c` files belong to a target.
64
+
65
+ For Lua, these are the most useful entrypoints:
66
+
67
+ ```bash
68
+ env -u LC_ALL uv run pcc projects/lua-5.5.0/onelua.c -- projects/lua-5.5.0/testes/math.lua
69
+ env -u LC_ALL uv run pcc --sources-from-make lua projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
70
+ env -u LC_ALL uv run pcc --separate-tus --sources-from-make lua projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
71
+ ```
72
+
73
+
74
+ ## Debugging Playbook
75
+
76
+ ### 1. Make the failure deterministic
77
+
78
+ Do not start by reading all of `c_codegen.py`. First make the failure repeatable.
79
+
80
+ Examples:
81
+
82
+ - fix the random seed
83
+ - replace filesystem/time input with constants
84
+ - run with `-n0`
85
+ - isolate one test file instead of a whole suite
86
+
87
+ If the failure is random, your first job is to remove randomness from the reproduction, not to guess the cause.
88
+
89
+
90
+ ### 2. Compare `pcc` against native from the same source
91
+
92
+ When the bug appears in a real program:
93
+
94
+ 1. Compile the same source with `pcc`
95
+ 2. Compile the same source with the system C compiler
96
+ 3. Compare behavior, not assumptions
97
+
98
+ This separates "the program is odd" from "the compiler lowered it incorrectly".
99
+
100
+
101
+ ### 3. Shrink the reproducer in stages
102
+
103
+ A productive sequence is:
104
+
105
+ 1. failing integration test
106
+ 2. smaller script or input
107
+ 3. small C harness that calls the same internal code path
108
+ 4. pure C expression or arithmetic reproducer
109
+
110
+ Do not stop at step 1 if the failure is deep in semantics. The time you spend shrinking the reproducer is usually returned many times over during diagnosis.
111
+
112
+
113
+ ### 4. Test hypotheses by substitution, not only by inspection
114
+
115
+ If a large function is suspect:
116
+
117
+ - copy it into a temporary harness
118
+ - replace one helper at a time with the real implementation
119
+ - reintroduce branches incrementally
120
+
121
+ This is often faster than staring at 500 lines of codegen or IR.
122
+
123
+
124
+ ### 5. Separate data-layout bugs from expression-semantics bugs
125
+
126
+ When a real program fails, two common classes are:
127
+
128
+ - ABI/layout bugs
129
+ `sizeof`, `offsetof`, fake libc declarations, struct or union layout
130
+ - expression-semantics bugs
131
+ signedness, promotions, comparisons, shifts, division/remainder, aggregate copy, control flow
132
+
133
+ If layout is suspicious, build a dedicated probe with `sizeof` and `offsetof` and compare native vs `pcc`. Once layout matches, move on.
134
+
135
+
136
+ ### 6. Prefer downstream-sensitive regression tests
137
+
138
+ A good regression test does not just check "the bits look right right now". It checks an expression in a context where the next operation would be wrong if semantic metadata were lost.
139
+
140
+ Good examples:
141
+
142
+ - unsigned expression followed by `%` with a signed constant
143
+ - unsigned expression followed by `>>`
144
+ - unsigned expression used in `<`, `>`, `/`, `%`
145
+
146
+ This matters because LLVM uses the same integer types for signed and unsigned values. The compiler must preserve signedness intent itself.
147
+
148
+
149
+ ## Signedness Model
150
+
151
+ This repository lowers both `int` and `unsigned int` to LLVM `i32`. Therefore signedness is tracked separately in `pcc/codegen/c_codegen.py`.
152
+
153
+ Important helpers:
154
+
155
+ - `_tag_unsigned`
156
+ - `_clear_unsigned`
157
+ - `_is_unsigned_val`
158
+ - `_convert_int_value`
159
+ - `_usual_arithmetic_conversion`
160
+ - `_shift_operand_conversion`
161
+
162
+ When you add or change an expression form, ask:
163
+
164
+ 1. Does this produce an integer result?
165
+ 2. If yes, should the result remain unsigned?
166
+ 3. Will that result later feed `%`, `/`, `>>`, comparisons, or another arithmetic conversion?
167
+
168
+ The classic failure mode in this repository is:
169
+
170
+ - the immediate value bits are correct
171
+ - but the returned IR value is no longer marked unsigned
172
+ - so a later operator uses `sdiv`, `srem`, `ashr`, or signed comparison
173
+
174
+ This class of bug is easy to miss with toy tests and shows up quickly in Lua, libc-heavy code, and control-flow-heavy programs.
175
+
176
+
177
+ ## Common Pitfalls
178
+
179
+ - Prefix operators on unsigned values:
180
+ `++x` / `--x` must preserve unsignedness on the expression result.
181
+ - Bitwise operators on unsigned values:
182
+ `&`, `|`, `^`, `~`, shifts, and compound assignments must preserve unsignedness where C requires it.
183
+ - Assignment expressions:
184
+ The stored value and the expression result are both semantically meaningful.
185
+ - Temporary probe files:
186
+ Putting `foo_tmp.c` inside a project directory can accidentally change project collection behavior.
187
+ - Fake libc changes:
188
+ These can fix or break real programs without touching parser or codegen.
189
+
190
+
191
+ ## Testing Policy
192
+
193
+ For every semantic bug fix:
194
+
195
+ 1. Add a focused regression test in `tests/`.
196
+ 2. Confirm the original realistic reproducer is fixed.
197
+ 3. Run the full suite before finishing.
198
+
199
+ Useful commands:
200
+
201
+ ```bash
202
+ env -u LC_ALL uv run pytest tests/test_unsigned_loads.py -q -n0
203
+ env -u LC_ALL uv run pytest tests/test_lua.py -q -n0
204
+ env -u LC_ALL uv run pytest -q
205
+ ```
206
+
207
+
208
+ ## Definition of Done
209
+
210
+ Before you stop, confirm all of the following:
211
+
212
+ - the smallest reproducer passes
213
+ - the original integration scenario passes
214
+ - any temporary debug edits and probe files are removed
215
+ - a regression test exists
216
+ - the full suite is green
217
+
218
+
219
+ ## Platform-Specific Gotchas (macOS)
220
+
221
+ - No `/dev/full` — Lua's `files.lua` tests `/dev/full` for write failure. On macOS this device doesn't exist. The test harness patches it out in a temporary copy.
222
+ - Makefile flags — Lua's Makefile uses `-DLUA_USE_LINUX` and `-Wl,-E`. On macOS, override with `MYCFLAGS=-std=c99 -DLUA_USE_MACOSX`, `MYLDFLAGS=`, `MYLIBS=`.
223
+ - `-ldl` — Not needed on macOS (dlopen is in libc), but harmless. The linker warns but still works.
224
+
225
+
226
+ ## LLVM Version Mismatch
227
+
228
+ `llvmlite` bundles its own LLVM version, which may be newer than the system `clang`. This matters when pcc writes IR to a file and compiles with `cc -c`:
229
+
230
+ - LLVM O2 optimizer can emit attributes the system clang doesn't understand: `nuw`, `nneg`, `range()`, `initializes()`, `dead_on_unwind`.
231
+ - For this reason, the test path currently does **not** run LLVM optimization passes. The JIT path (via `evaluate()`) does run O2 and works fine because llvmlite's own LLVM parses its own output.
232
+ - If you need to compile optimized IR with the system compiler, strip these attributes with regex post-processing.
233
+
234
+
235
+ ## IR Fix Centralization
236
+
237
+ All IR text-level fixes belong in `postprocess_ir_text()` in `pcc/codegen/c_codegen.py`, **not** in test helpers. This function is used by both the JIT path (`evaluate()`) and the test compilation path. Fixes that only exist in test code will not help `uv run pcc`.
238
+
239
+ Current fixes in `postprocess_ir_text`:
240
+ - `bitcast int → ptr` → `inttoptr`
241
+ - Python `<ir.Constant>` repr leak → `zeroinitializer`
242
+ - `alloca/load/store void` → removed
243
+ - duplicate switch case values → deduplicated
244
+ - dead code after terminators → removed
245
+ - consecutive empty labels → `br`/`unreachable` inserted
246
+
247
+
248
+ ## Packaging
249
+
250
+ - The wheel must include `utils/fake_libc_include/`. Without it, preprocessing fails on install.
251
+ - PyPI package name is `python-cc` (not `pcc`, which is taken).
252
+ - GitHub Actions uses Trusted Publisher (OIDC). The PyPI project name must match `pyproject.toml`'s `name` field exactly.
253
+
254
+
255
+ ## Additional Reading
256
+
257
+ - `docs/investigations/lua-sort-random-pivot-signedness.md`
258
+ Detailed report for a representative real-world debugging session that started as a flaky Lua `sort.lua` failure and ended as an unsigned-expression codegen fix.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-cc
3
- Version: 0.0.5
3
+ Version: 0.0.6
4
4
  Summary: Pcc is a c compiler built on python and llvm.
5
5
  Project-URL: Homepage, https://github.com/jiamo/pcc
6
6
  License-Expression: MIT
@@ -16,9 +16,10 @@ Pcc
16
16
 
17
17
  What is this?
18
18
  --------------------
19
- Pcc is a C compiler based on ply + pycparser + llvmlite + llvm.
20
- We can run C programs like Python: `pcc test.c` to run C code.
21
- Pcc was inspired by: https://github.com/eliben/pykaleidoscope.
19
+ Pcc is a C compiler written in Python, built on cpp + ply + pycparser + llvmlite + llvm.
20
+ Run C programs like Python scripts: `pcc test.c`. Powerful enough to compile and run the full [Lua 5.5.0](https://github.com/lua/lua) interpreter (~30k lines of C).
21
+
22
+ Inspired by: https://github.com/eliben/pykaleidoscope.
22
23
 
23
24
  Notice
24
25
  --------------------
@@ -41,6 +42,26 @@ pcc --llvmdump test.c # dump LLVM IR
41
42
  pcc myproject/ -- arg1 arg2 # pass args to compiled program
42
43
  ```
43
44
 
45
+ Use as a Python library:
46
+
47
+ ```python
48
+ from pcc.evaluater.c_evaluator import CEvaluator
49
+
50
+ pcc = CEvaluator()
51
+
52
+ # Run main()
53
+ pcc.evaluate(r'''
54
+ #include <stdio.h>
55
+ int main() { printf("Hello from pcc!\n"); return 0; }
56
+ ''')
57
+
58
+ # Call any C function directly
59
+ ret = pcc.evaluate(r'''
60
+ int add(int a, int b) { return a + b; }
61
+ ''', entry="add", args=[3, 7])
62
+ print(ret) # 10
63
+ ```
64
+
44
65
  Development
45
66
  --------------------
46
67
 
@@ -53,16 +74,61 @@ uv run pytest # run all 500+ tests
53
74
 
54
75
  Multi-file projects: put `.c` and `.h` files in a directory, one `.c` must contain `main()`. Pcc auto-discovers all `.c` files, merges them, and compiles.
55
76
 
56
- Lua Compilation Goal
77
+ Compiling Lua 5.5.0
57
78
  --------------------
58
79
 
59
- The target is to compile and run [Lua 5.5.0](https://github.com/lua/lua) using pcc.
80
+ Pcc can compile the entire [Lua 5.5.0](https://github.com/lua/lua) interpreter (~30k lines of C) and run Lua scripts directly.
81
+
82
+ For one representative script (`math.lua`), these are the important cases:
83
+
84
+ ```bash
85
+ git clone https://github.com/jiamo/pcc && cd pcc
86
+ uv sync
87
+
88
+ # 1) Canonical Lua tree in default directory mode: fails
89
+ # Reason: directory mode merges every .c into one TU, and projects/lua-5.5.0
90
+ # contains both onelua.c and the individual source files.
91
+ uv run pcc projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
60
92
 
93
+ # 2) Explicit amalgamation mode: works
94
+ uv run pcc projects/lua-5.5.0/onelua.c -- projects/lua-5.5.0/testes/math.lua
95
+
96
+ # 3) Canonical Lua tree, but collect only the sources used by `make -nB lua`: works
97
+ uv run pcc --sources-from-make lua projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
98
+
99
+ # 4) Same make-derived source list, but compile as separate translation units: works
100
+ uv run pcc --separate-tus --sources-from-make lua projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
101
+
102
+ # 5) Same separate-TU path, but compile translation units in parallel: works
103
+ uv run pcc --separate-tus --sources-from-make lua --jobs 2 projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
104
+
105
+ # 6) Canonical Lua tree with raw --separate-tus: fails
106
+ # Reason: onelua.c and the individual source files become separate TUs with
107
+ # duplicate external definitions at link semantics.
108
+ uv run pcc --separate-tus projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
109
+
110
+ # Run all 130+ Lua tests (pcc vs native, pcc vs makefile, makefile baseline)
111
+ uv run pytest tests/test_lua.py -v
61
112
  ```
62
- projects/lua-5.5.0/ - Lua 5.5.0 source code + Makefile
113
+
114
+ ```
115
+ projects/lua-5.5.0/ - canonical Lua 5.5.0 source tree, includes onelua.c and the standard multi-file sources
63
116
  projects/lua-5.5.0/testes/ - Lua test suite
64
117
  ```
65
118
 
119
+ Use `projects/lua-5.5.0/onelua.c` when you want Lua's official amalgamation build.
120
+ Use `--sources-from-make lua` when you want `pcc` to follow the same source list
121
+ that Lua's makefile uses for the `lua` target.
122
+ Use `--separate-tus` when you want normal multi-file C semantics: each `.c`
123
+ file is compiled as its own translation unit instead of being merged into one
124
+ big source string first.
125
+
126
+ In other words:
127
+
128
+ - default directory mode: merge all selected `.c` files into one TU
129
+ - `--sources-from-make lua`: keep directory mode, but let `make -nB lua` choose which `.c` files participate
130
+ - `--separate-tus`: compile each selected `.c` as a separate TU, then link them together
131
+
66
132
  ### Test Structure
67
133
 
68
134
  Tests in `tests/test_lua.py` compare three builds:
@@ -131,55 +197,4 @@ Built-in typedefs: `size_t`, `ssize_t`, `ptrdiff_t`, `va_list`, `FILE`, `time_t`
131
197
  Supported C Features
132
198
  --------------------
133
199
 
134
- ### Types
135
- `int`, `double`, `float`, `char`, `void`, `unsigned`/`signed`/`long`/`short` (all combinations),
136
- `size_t`, `int8_t`..`uint64_t`,
137
- pointers (multi-level), arrays (multi-dim),
138
- structs (named, anonymous, nested, with array/pointer/function-pointer members, pointer-to-struct),
139
- unions, enums (with constant expressions), typedef (scalar, struct, pointer, function pointer),
140
- `static` local variables, `const`/`volatile` qualifiers
141
-
142
- ### Operators
143
- - Arithmetic: `+` `-` `*` `/` `%`
144
- - Bitwise: `&` `|` `^` `<<` `>>`
145
- - Comparison: `<` `>` `<=` `>=` `==` `!=` (including pointer comparison)
146
- - Logical: `&&` `||` (short-circuit evaluation)
147
- - Unary: `-x` `+x` `!x` `~x` `sizeof` `&x` `*p`
148
- - Increment/Decrement: `++x` `x++` `--x` `x--` (int and pointer, including struct members)
149
- - Assignment: `=` `+=` `-=` `*=` `/=` `%=` `<<=` `>>=` `&=` `|=` `^=` (including pointer `+=`/`-=`)
150
- - Ternary: `a ? b : c`
151
- - Pointer: `p + n`, `p - n`, `p - q`, `p++`, `p[i]`
152
- - Struct access: `.` and `->` (including nested `a.b.c` and `s->fn(args)`)
153
- - Chained: `a = b = c = 5`
154
-
155
- ### Control Flow
156
- `if` / `else` / `else if`, `while`, `do-while`, `for` (all variants including `for(;;)`),
157
- `switch` / `case` / `default`, `goto` / `label`, `break`, `continue`, `return`
158
-
159
- ### Functions
160
- Definitions, forward declarations, mutual recursion, void functions, variadic (`...`),
161
- pointer/array arguments, `static` local variables, function pointers (declaration, assignment,
162
- calling, as parameters, in structs, typedef'd), callback patterns
163
-
164
- ### Libc Functions (133 total, auto-declared on first use)
165
-
166
- | Header | Functions |
167
- |--------|-----------|
168
- | stdio.h | printf, fprintf, sprintf, snprintf, puts, putchar, getchar, fopen, fclose, fread, fwrite, fseek, ftell, fgets, fputs, scanf, sscanf, ... |
169
- | stdlib.h | malloc, calloc, realloc, free, abs, labs, atoi, atol, atof, strtol, strtod, rand, srand, exit, abort, qsort, bsearch, getenv, system, ... |
170
- | string.h | strlen, strcmp, strncmp, strcpy, strncpy, strcat, strncat, strchr, strrchr, strstr, memset, memcpy, memmove, memcmp, memchr, strtok, ... |
171
- | ctype.h | isalpha, isdigit, isalnum, isspace, isupper, islower, isprint, ispunct, isxdigit, toupper, tolower, ... |
172
- | math.h | sin, cos, tan, asin, acos, atan, atan2, exp, log, log2, log10, pow, sqrt, cbrt, hypot, ceil, floor, round, trunc, fmod, fabs, ... |
173
- | time.h | time, clock, difftime |
174
- | unistd.h | sleep, usleep, read, write, open, close, getpid, getppid |
175
- | setjmp.h | setjmp, longjmp |
176
- | signal.h | signal, raise |
177
-
178
- ### Literals
179
- Decimal, hex (`0xFF`), octal (`077`), char (`'a'`, `'\n'`), string (`"hello\n"`), double (`3.14`)
180
-
181
- ### Other
182
- C comments (`/* */`, `//`), array initializer lists (1D and multi-dim),
183
- string escape sequences (`\n \t \\ \0 \r`), implicit type promotion (int/char/double/pointer),
184
- array-to-pointer decay, `NULL` pointer support, opaque/forward-declared structs,
185
- two-pass codegen (types first, functions second)
200
+ Supports all C99 features needed to compile real-world projects like Lua 5.5.0: all types (int, float, double, char, void, structs, unions, enums, typedefs, pointers, arrays, function pointers), all operators, all control flow (if/else, for, while, do-while, switch, goto), variadic functions, preprocessor directives, and 133 libc functions auto-declared from stdio.h, stdlib.h, string.h, math.h, etc.
@@ -0,0 +1,187 @@
1
+ Pcc
2
+ ====================
3
+
4
+ What is this?
5
+ --------------------
6
+ Pcc is a C compiler written in Python, built on cpp + ply + pycparser + llvmlite + llvm.
7
+ Run C programs like Python scripts: `pcc test.c`. Powerful enough to compile and run the full [Lua 5.5.0](https://github.com/lua/lua) interpreter (~30k lines of C).
8
+
9
+ Inspired by: https://github.com/eliben/pykaleidoscope.
10
+
11
+ Notice
12
+ --------------------
13
+ 1. Some code skeleton comes from pykaleidoscope.
14
+ 2. ply and pycparser are embedded into this project for debug use.
15
+
16
+ Install
17
+ --------------------
18
+
19
+ ```bash
20
+ pip install python-cc
21
+ ```
22
+
23
+ This gives you the `pcc` command:
24
+
25
+ ```bash
26
+ pcc hello.c # compile and run
27
+ pcc myproject/ # compile all .c files in directory
28
+ pcc --llvmdump test.c # dump LLVM IR
29
+ pcc myproject/ -- arg1 arg2 # pass args to compiled program
30
+ ```
31
+
32
+ Use as a Python library:
33
+
34
+ ```python
35
+ from pcc.evaluater.c_evaluator import CEvaluator
36
+
37
+ pcc = CEvaluator()
38
+
39
+ # Run main()
40
+ pcc.evaluate(r'''
41
+ #include <stdio.h>
42
+ int main() { printf("Hello from pcc!\n"); return 0; }
43
+ ''')
44
+
45
+ # Call any C function directly
46
+ ret = pcc.evaluate(r'''
47
+ int add(int a, int b) { return a + b; }
48
+ ''', entry="add", args=[3, 7])
49
+ print(ret) # 10
50
+ ```
51
+
52
+ Development
53
+ --------------------
54
+
55
+ Requires Python 3.13+ and [uv](https://docs.astral.sh/uv/).
56
+
57
+ ```bash
58
+ uv sync # install dependencies
59
+ uv run pytest # run all 500+ tests
60
+ ```
61
+
62
+ Multi-file projects: put `.c` and `.h` files in a directory, one `.c` must contain `main()`. Pcc auto-discovers all `.c` files, merges them, and compiles.
63
+
64
+ Compiling Lua 5.5.0
65
+ --------------------
66
+
67
+ Pcc can compile the entire [Lua 5.5.0](https://github.com/lua/lua) interpreter (~30k lines of C) and run Lua scripts directly.
68
+
69
+ For one representative script (`math.lua`), these are the important cases:
70
+
71
+ ```bash
72
+ git clone https://github.com/jiamo/pcc && cd pcc
73
+ uv sync
74
+
75
+ # 1) Canonical Lua tree in default directory mode: fails
76
+ # Reason: directory mode merges every .c into one TU, and projects/lua-5.5.0
77
+ # contains both onelua.c and the individual source files.
78
+ uv run pcc projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
79
+
80
+ # 2) Explicit amalgamation mode: works
81
+ uv run pcc projects/lua-5.5.0/onelua.c -- projects/lua-5.5.0/testes/math.lua
82
+
83
+ # 3) Canonical Lua tree, but collect only the sources used by `make -nB lua`: works
84
+ uv run pcc --sources-from-make lua projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
85
+
86
+ # 4) Same make-derived source list, but compile as separate translation units: works
87
+ uv run pcc --separate-tus --sources-from-make lua projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
88
+
89
+ # 5) Same separate-TU path, but compile translation units in parallel: works
90
+ uv run pcc --separate-tus --sources-from-make lua --jobs 2 projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
91
+
92
+ # 6) Canonical Lua tree with raw --separate-tus: fails
93
+ # Reason: onelua.c and the individual source files become separate TUs with
94
+ # duplicate external definitions at link semantics.
95
+ uv run pcc --separate-tus projects/lua-5.5.0 -- projects/lua-5.5.0/testes/math.lua
96
+
97
+ # Run all 130+ Lua tests (pcc vs native, pcc vs makefile, makefile baseline)
98
+ uv run pytest tests/test_lua.py -v
99
+ ```
100
+
101
+ ```
102
+ projects/lua-5.5.0/ - canonical Lua 5.5.0 source tree, includes onelua.c and the standard multi-file sources
103
+ projects/lua-5.5.0/testes/ - Lua test suite
104
+ ```
105
+
106
+ Use `projects/lua-5.5.0/onelua.c` when you want Lua's official amalgamation build.
107
+ Use `--sources-from-make lua` when you want `pcc` to follow the same source list
108
+ that Lua's makefile uses for the `lua` target.
109
+ Use `--separate-tus` when you want normal multi-file C semantics: each `.c`
110
+ file is compiled as its own translation unit instead of being merged into one
111
+ big source string first.
112
+
113
+ In other words:
114
+
115
+ - default directory mode: merge all selected `.c` files into one TU
116
+ - `--sources-from-make lua`: keep directory mode, but let `make -nB lua` choose which `.c` files participate
117
+ - `--separate-tus`: compile each selected `.c` as a separate TU, then link them together
118
+
119
+ ### Test Structure
120
+
121
+ Tests in `tests/test_lua.py` compare three builds:
122
+
123
+ | Build | Method |
124
+ |-------|--------|
125
+ | **pcc** | `onelua.c` → pcc preprocess/parse/codegen → LLVM IR → cc compile+link |
126
+ | **native** | `onelua.c` → `cc -O0` single-file compile |
127
+ | **makefile** | `make` with project Makefile (separate compilation of each .c, static lib + link) |
128
+
129
+ ```bash
130
+ # Run all Lua tests (~25s with auto workers)
131
+ uv run pytest tests/test_lua.py -v
132
+
133
+ # Individual file compilation through pcc pipeline
134
+ uv run pytest tests/test_lua.py::test_lua_source_compile -v
135
+ # pcc vs native (same onelua.c, test pcc as C compiler)
136
+ uv run pytest tests/test_lua.py::test_pcc_runtime_matches_native -v
137
+ # pcc vs Makefile-built lua (official reference)
138
+ uv run pytest tests/test_lua.py::test_pcc_runtime_matches_makefile -v
139
+ # Lua test suite with Makefile-built binary (baseline)
140
+ uv run pytest tests/test_lua.py::test_makefile_lua_test_suite -v
141
+ ```
142
+
143
+ Note: `heavy.lua` is excluded from automated tests (runs ~2 min+, may timeout). Run manually:
144
+ ```bash
145
+ # Build Makefile lua, then run heavy.lua directly
146
+ cd projects/lua-5.5.0 && make CC=cc CWARNS= MYCFLAGS="-std=c99 -DLUA_USE_MACOSX" MYLDFLAGS= MYLIBS=
147
+ ./lua testes/heavy.lua
148
+ ```
149
+
150
+ Add C test cases
151
+ --------------------
152
+
153
+ ```bash
154
+ # Single file: add to c_tests/ with expected return value
155
+ echo '// EXPECT: 42
156
+ int main(){ return 42; }' > c_tests/mytest.c
157
+
158
+ # Multi-file project: create a directory with main.c
159
+ mkdir c_tests/myproject
160
+ # ... add .c and .h files, main.c must have: // EXPECT: N
161
+
162
+ # Run all C file tests
163
+ uv run pytest tests/test_c_files.py -v
164
+ ```
165
+
166
+ Preprocessor
167
+ --------------------
168
+
169
+ ```c
170
+ #include <stdio.h> // system headers: 133 libc functions auto-declared
171
+ #include "mylib.h" // user headers: read and inline file content
172
+ #define MAX_SIZE 100 // object-like macro
173
+ #define MAX(a,b) ((a)>(b)?(a):(b)) // function-like macro
174
+ #define DEBUG // flag for conditional compilation
175
+ #ifdef / #ifndef / #if / #elif / #else / #endif // conditional compilation
176
+ #if defined(X) && (VERSION >= 3) // expression evaluation with defined()
177
+ #undef NAME // undefine macro
178
+ ```
179
+
180
+ Built-in macros: `NULL`, `EOF`, `EXIT_SUCCESS`, `EXIT_FAILURE`, `RAND_MAX`, `INT_MAX`, `INT_MIN`, `LLONG_MAX`, `CHAR_BIT`, `true`, `false`, `__STDC__`
181
+
182
+ Built-in typedefs: `size_t`, `ssize_t`, `ptrdiff_t`, `va_list`, `FILE`, `time_t`, `clock_t`, `pid_t`
183
+
184
+ Supported C Features
185
+ --------------------
186
+
187
+ Supports all C99 features needed to compile real-world projects like Lua 5.5.0: all types (int, float, double, char, void, structs, unions, enums, typedefs, pointers, arrays, function pointers), all operators, all control flow (if/else, for, while, do-while, switch, goto), variadic functions, preprocessor directives, and 133 libc functions auto-declared from stdio.h, stdlib.h, string.h, math.h, etc.