machine-dialect 0.1.0a1__py3-none-any.whl

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 (268) hide show
  1. machine_dialect/__main__.py +667 -0
  2. machine_dialect/agent/__init__.py +5 -0
  3. machine_dialect/agent/agent.py +360 -0
  4. machine_dialect/ast/__init__.py +95 -0
  5. machine_dialect/ast/ast_node.py +35 -0
  6. machine_dialect/ast/call_expression.py +82 -0
  7. machine_dialect/ast/dict_extraction.py +60 -0
  8. machine_dialect/ast/expressions.py +439 -0
  9. machine_dialect/ast/literals.py +309 -0
  10. machine_dialect/ast/program.py +35 -0
  11. machine_dialect/ast/statements.py +1433 -0
  12. machine_dialect/ast/tests/test_ast_string_representation.py +62 -0
  13. machine_dialect/ast/tests/test_boolean_literal.py +29 -0
  14. machine_dialect/ast/tests/test_collection_hir.py +138 -0
  15. machine_dialect/ast/tests/test_define_statement.py +142 -0
  16. machine_dialect/ast/tests/test_desugar.py +541 -0
  17. machine_dialect/ast/tests/test_foreach_desugar.py +245 -0
  18. machine_dialect/cfg/__init__.py +6 -0
  19. machine_dialect/cfg/config.py +156 -0
  20. machine_dialect/cfg/examples.py +221 -0
  21. machine_dialect/cfg/generate_with_ai.py +187 -0
  22. machine_dialect/cfg/openai_generation.py +200 -0
  23. machine_dialect/cfg/parser.py +94 -0
  24. machine_dialect/cfg/tests/__init__.py +1 -0
  25. machine_dialect/cfg/tests/test_cfg_parser.py +252 -0
  26. machine_dialect/cfg/tests/test_config.py +188 -0
  27. machine_dialect/cfg/tests/test_examples.py +391 -0
  28. machine_dialect/cfg/tests/test_generate_with_ai.py +354 -0
  29. machine_dialect/cfg/tests/test_openai_generation.py +256 -0
  30. machine_dialect/codegen/__init__.py +5 -0
  31. machine_dialect/codegen/bytecode_module.py +89 -0
  32. machine_dialect/codegen/bytecode_serializer.py +300 -0
  33. machine_dialect/codegen/opcodes.py +101 -0
  34. machine_dialect/codegen/register_codegen.py +1996 -0
  35. machine_dialect/codegen/symtab.py +208 -0
  36. machine_dialect/codegen/tests/__init__.py +1 -0
  37. machine_dialect/codegen/tests/test_array_operations_codegen.py +295 -0
  38. machine_dialect/codegen/tests/test_bytecode_serializer.py +185 -0
  39. machine_dialect/codegen/tests/test_register_codegen_ssa.py +324 -0
  40. machine_dialect/codegen/tests/test_symtab.py +418 -0
  41. machine_dialect/codegen/vm_serializer.py +621 -0
  42. machine_dialect/compiler/__init__.py +18 -0
  43. machine_dialect/compiler/compiler.py +197 -0
  44. machine_dialect/compiler/config.py +149 -0
  45. machine_dialect/compiler/context.py +149 -0
  46. machine_dialect/compiler/phases/__init__.py +19 -0
  47. machine_dialect/compiler/phases/bytecode_optimization.py +90 -0
  48. machine_dialect/compiler/phases/codegen.py +40 -0
  49. machine_dialect/compiler/phases/hir_generation.py +39 -0
  50. machine_dialect/compiler/phases/mir_generation.py +86 -0
  51. machine_dialect/compiler/phases/optimization.py +110 -0
  52. machine_dialect/compiler/phases/parsing.py +39 -0
  53. machine_dialect/compiler/pipeline.py +143 -0
  54. machine_dialect/compiler/tests/__init__.py +1 -0
  55. machine_dialect/compiler/tests/test_compiler.py +568 -0
  56. machine_dialect/compiler/vm_runner.py +173 -0
  57. machine_dialect/errors/__init__.py +32 -0
  58. machine_dialect/errors/exceptions.py +369 -0
  59. machine_dialect/errors/messages.py +82 -0
  60. machine_dialect/errors/tests/__init__.py +0 -0
  61. machine_dialect/errors/tests/test_expected_token_errors.py +188 -0
  62. machine_dialect/errors/tests/test_name_errors.py +118 -0
  63. machine_dialect/helpers/__init__.py +0 -0
  64. machine_dialect/helpers/stopwords.py +225 -0
  65. machine_dialect/helpers/validators.py +30 -0
  66. machine_dialect/lexer/__init__.py +9 -0
  67. machine_dialect/lexer/constants.py +23 -0
  68. machine_dialect/lexer/lexer.py +907 -0
  69. machine_dialect/lexer/tests/__init__.py +0 -0
  70. machine_dialect/lexer/tests/helpers.py +86 -0
  71. machine_dialect/lexer/tests/test_apostrophe_identifiers.py +122 -0
  72. machine_dialect/lexer/tests/test_backtick_identifiers.py +140 -0
  73. machine_dialect/lexer/tests/test_boolean_literals.py +108 -0
  74. machine_dialect/lexer/tests/test_case_insensitive_keywords.py +188 -0
  75. machine_dialect/lexer/tests/test_comments.py +200 -0
  76. machine_dialect/lexer/tests/test_double_asterisk_keywords.py +127 -0
  77. machine_dialect/lexer/tests/test_lexer_position.py +113 -0
  78. machine_dialect/lexer/tests/test_list_tokens.py +282 -0
  79. machine_dialect/lexer/tests/test_stopwords.py +80 -0
  80. machine_dialect/lexer/tests/test_strict_equality.py +129 -0
  81. machine_dialect/lexer/tests/test_token.py +41 -0
  82. machine_dialect/lexer/tests/test_tokenization.py +294 -0
  83. machine_dialect/lexer/tests/test_underscore_literals.py +343 -0
  84. machine_dialect/lexer/tests/test_url_literals.py +169 -0
  85. machine_dialect/lexer/tokens.py +487 -0
  86. machine_dialect/linter/__init__.py +10 -0
  87. machine_dialect/linter/__main__.py +144 -0
  88. machine_dialect/linter/linter.py +154 -0
  89. machine_dialect/linter/rules/__init__.py +8 -0
  90. machine_dialect/linter/rules/base.py +112 -0
  91. machine_dialect/linter/rules/statement_termination.py +99 -0
  92. machine_dialect/linter/tests/__init__.py +1 -0
  93. machine_dialect/linter/tests/mdrules/__init__.py +0 -0
  94. machine_dialect/linter/tests/mdrules/test_md101_statement_termination.py +181 -0
  95. machine_dialect/linter/tests/test_linter.py +81 -0
  96. machine_dialect/linter/tests/test_rules.py +110 -0
  97. machine_dialect/linter/tests/test_violations.py +71 -0
  98. machine_dialect/linter/violations.py +51 -0
  99. machine_dialect/mir/__init__.py +69 -0
  100. machine_dialect/mir/analyses/__init__.py +20 -0
  101. machine_dialect/mir/analyses/alias_analysis.py +315 -0
  102. machine_dialect/mir/analyses/dominance_analysis.py +49 -0
  103. machine_dialect/mir/analyses/escape_analysis.py +286 -0
  104. machine_dialect/mir/analyses/loop_analysis.py +272 -0
  105. machine_dialect/mir/analyses/tests/test_type_analysis.py +736 -0
  106. machine_dialect/mir/analyses/type_analysis.py +448 -0
  107. machine_dialect/mir/analyses/use_def_chains.py +232 -0
  108. machine_dialect/mir/basic_block.py +385 -0
  109. machine_dialect/mir/dataflow.py +445 -0
  110. machine_dialect/mir/debug_info.py +208 -0
  111. machine_dialect/mir/hir_to_mir.py +1738 -0
  112. machine_dialect/mir/mir_dumper.py +366 -0
  113. machine_dialect/mir/mir_function.py +167 -0
  114. machine_dialect/mir/mir_instructions.py +1877 -0
  115. machine_dialect/mir/mir_interpreter.py +556 -0
  116. machine_dialect/mir/mir_module.py +225 -0
  117. machine_dialect/mir/mir_printer.py +480 -0
  118. machine_dialect/mir/mir_transformer.py +410 -0
  119. machine_dialect/mir/mir_types.py +367 -0
  120. machine_dialect/mir/mir_validation.py +455 -0
  121. machine_dialect/mir/mir_values.py +268 -0
  122. machine_dialect/mir/optimization_config.py +233 -0
  123. machine_dialect/mir/optimization_pass.py +251 -0
  124. machine_dialect/mir/optimization_pipeline.py +355 -0
  125. machine_dialect/mir/optimizations/__init__.py +84 -0
  126. machine_dialect/mir/optimizations/algebraic_simplification.py +733 -0
  127. machine_dialect/mir/optimizations/branch_prediction.py +372 -0
  128. machine_dialect/mir/optimizations/constant_propagation.py +634 -0
  129. machine_dialect/mir/optimizations/cse.py +398 -0
  130. machine_dialect/mir/optimizations/dce.py +288 -0
  131. machine_dialect/mir/optimizations/inlining.py +551 -0
  132. machine_dialect/mir/optimizations/jump_threading.py +487 -0
  133. machine_dialect/mir/optimizations/licm.py +405 -0
  134. machine_dialect/mir/optimizations/loop_unrolling.py +366 -0
  135. machine_dialect/mir/optimizations/strength_reduction.py +422 -0
  136. machine_dialect/mir/optimizations/tail_call.py +207 -0
  137. machine_dialect/mir/optimizations/tests/test_loop_unrolling.py +483 -0
  138. machine_dialect/mir/optimizations/type_narrowing.py +397 -0
  139. machine_dialect/mir/optimizations/type_specialization.py +447 -0
  140. machine_dialect/mir/optimizations/type_specific.py +906 -0
  141. machine_dialect/mir/optimize_mir.py +89 -0
  142. machine_dialect/mir/pass_manager.py +391 -0
  143. machine_dialect/mir/profiling/__init__.py +26 -0
  144. machine_dialect/mir/profiling/profile_collector.py +318 -0
  145. machine_dialect/mir/profiling/profile_data.py +372 -0
  146. machine_dialect/mir/profiling/profile_reader.py +272 -0
  147. machine_dialect/mir/profiling/profile_writer.py +226 -0
  148. machine_dialect/mir/register_allocation.py +302 -0
  149. machine_dialect/mir/reporting/__init__.py +17 -0
  150. machine_dialect/mir/reporting/optimization_reporter.py +314 -0
  151. machine_dialect/mir/reporting/report_formatter.py +289 -0
  152. machine_dialect/mir/ssa_construction.py +342 -0
  153. machine_dialect/mir/tests/__init__.py +1 -0
  154. machine_dialect/mir/tests/test_algebraic_associativity.py +204 -0
  155. machine_dialect/mir/tests/test_algebraic_complex_patterns.py +221 -0
  156. machine_dialect/mir/tests/test_algebraic_division.py +126 -0
  157. machine_dialect/mir/tests/test_algebraic_simplification.py +863 -0
  158. machine_dialect/mir/tests/test_basic_block.py +425 -0
  159. machine_dialect/mir/tests/test_branch_prediction.py +459 -0
  160. machine_dialect/mir/tests/test_call_lowering.py +168 -0
  161. machine_dialect/mir/tests/test_collection_lowering.py +604 -0
  162. machine_dialect/mir/tests/test_cross_block_constant_propagation.py +255 -0
  163. machine_dialect/mir/tests/test_custom_passes.py +166 -0
  164. machine_dialect/mir/tests/test_debug_info.py +285 -0
  165. machine_dialect/mir/tests/test_dict_extraction_lowering.py +192 -0
  166. machine_dialect/mir/tests/test_dictionary_lowering.py +299 -0
  167. machine_dialect/mir/tests/test_double_negation.py +231 -0
  168. machine_dialect/mir/tests/test_escape_analysis.py +233 -0
  169. machine_dialect/mir/tests/test_hir_to_mir.py +465 -0
  170. machine_dialect/mir/tests/test_hir_to_mir_complete.py +389 -0
  171. machine_dialect/mir/tests/test_hir_to_mir_simple.py +130 -0
  172. machine_dialect/mir/tests/test_inlining.py +435 -0
  173. machine_dialect/mir/tests/test_licm.py +472 -0
  174. machine_dialect/mir/tests/test_mir_dumper.py +313 -0
  175. machine_dialect/mir/tests/test_mir_instructions.py +445 -0
  176. machine_dialect/mir/tests/test_mir_module.py +860 -0
  177. machine_dialect/mir/tests/test_mir_printer.py +387 -0
  178. machine_dialect/mir/tests/test_mir_types.py +123 -0
  179. machine_dialect/mir/tests/test_mir_types_enhanced.py +132 -0
  180. machine_dialect/mir/tests/test_mir_validation.py +378 -0
  181. machine_dialect/mir/tests/test_mir_values.py +168 -0
  182. machine_dialect/mir/tests/test_one_based_indexing.py +202 -0
  183. machine_dialect/mir/tests/test_optimization_helpers.py +60 -0
  184. machine_dialect/mir/tests/test_optimization_pipeline.py +554 -0
  185. machine_dialect/mir/tests/test_optimization_reporter.py +318 -0
  186. machine_dialect/mir/tests/test_pass_manager.py +294 -0
  187. machine_dialect/mir/tests/test_pass_registration.py +64 -0
  188. machine_dialect/mir/tests/test_profiling.py +356 -0
  189. machine_dialect/mir/tests/test_register_allocation.py +307 -0
  190. machine_dialect/mir/tests/test_report_formatters.py +372 -0
  191. machine_dialect/mir/tests/test_ssa_construction.py +433 -0
  192. machine_dialect/mir/tests/test_tail_call.py +236 -0
  193. machine_dialect/mir/tests/test_type_annotated_instructions.py +192 -0
  194. machine_dialect/mir/tests/test_type_narrowing.py +277 -0
  195. machine_dialect/mir/tests/test_type_specialization.py +421 -0
  196. machine_dialect/mir/tests/test_type_specific_optimization.py +545 -0
  197. machine_dialect/mir/tests/test_type_specific_optimization_advanced.py +382 -0
  198. machine_dialect/mir/type_inference.py +368 -0
  199. machine_dialect/parser/__init__.py +12 -0
  200. machine_dialect/parser/enums.py +45 -0
  201. machine_dialect/parser/parser.py +3655 -0
  202. machine_dialect/parser/protocols.py +11 -0
  203. machine_dialect/parser/symbol_table.py +169 -0
  204. machine_dialect/parser/tests/__init__.py +0 -0
  205. machine_dialect/parser/tests/helper_functions.py +193 -0
  206. machine_dialect/parser/tests/test_action_statements.py +334 -0
  207. machine_dialect/parser/tests/test_boolean_literal_expressions.py +152 -0
  208. machine_dialect/parser/tests/test_call_statements.py +154 -0
  209. machine_dialect/parser/tests/test_call_statements_errors.py +187 -0
  210. machine_dialect/parser/tests/test_collection_mutations.py +264 -0
  211. machine_dialect/parser/tests/test_conditional_expressions.py +343 -0
  212. machine_dialect/parser/tests/test_define_integration.py +468 -0
  213. machine_dialect/parser/tests/test_define_statements.py +311 -0
  214. machine_dialect/parser/tests/test_dict_extraction.py +115 -0
  215. machine_dialect/parser/tests/test_empty_literal.py +155 -0
  216. machine_dialect/parser/tests/test_float_literal_expressions.py +163 -0
  217. machine_dialect/parser/tests/test_identifier_expressions.py +57 -0
  218. machine_dialect/parser/tests/test_if_empty_block.py +61 -0
  219. machine_dialect/parser/tests/test_if_statements.py +299 -0
  220. machine_dialect/parser/tests/test_illegal_tokens.py +86 -0
  221. machine_dialect/parser/tests/test_infix_expressions.py +680 -0
  222. machine_dialect/parser/tests/test_integer_literal_expressions.py +137 -0
  223. machine_dialect/parser/tests/test_interaction_statements.py +269 -0
  224. machine_dialect/parser/tests/test_list_literals.py +277 -0
  225. machine_dialect/parser/tests/test_no_none_in_ast.py +94 -0
  226. machine_dialect/parser/tests/test_panic_mode_recovery.py +171 -0
  227. machine_dialect/parser/tests/test_parse_errors.py +114 -0
  228. machine_dialect/parser/tests/test_possessive_syntax.py +182 -0
  229. machine_dialect/parser/tests/test_prefix_expressions.py +415 -0
  230. machine_dialect/parser/tests/test_program.py +13 -0
  231. machine_dialect/parser/tests/test_return_statements.py +89 -0
  232. machine_dialect/parser/tests/test_set_statements.py +152 -0
  233. machine_dialect/parser/tests/test_strict_equality.py +258 -0
  234. machine_dialect/parser/tests/test_symbol_table.py +217 -0
  235. machine_dialect/parser/tests/test_url_literal_expressions.py +209 -0
  236. machine_dialect/parser/tests/test_utility_statements.py +423 -0
  237. machine_dialect/parser/token_buffer.py +159 -0
  238. machine_dialect/repl/__init__.py +3 -0
  239. machine_dialect/repl/repl.py +426 -0
  240. machine_dialect/repl/tests/__init__.py +0 -0
  241. machine_dialect/repl/tests/test_repl.py +606 -0
  242. machine_dialect/semantic/__init__.py +12 -0
  243. machine_dialect/semantic/analyzer.py +906 -0
  244. machine_dialect/semantic/error_messages.py +189 -0
  245. machine_dialect/semantic/tests/__init__.py +1 -0
  246. machine_dialect/semantic/tests/test_analyzer.py +364 -0
  247. machine_dialect/semantic/tests/test_error_messages.py +104 -0
  248. machine_dialect/tests/edge_cases/__init__.py +10 -0
  249. machine_dialect/tests/edge_cases/test_boundary_access.py +256 -0
  250. machine_dialect/tests/edge_cases/test_empty_collections.py +166 -0
  251. machine_dialect/tests/edge_cases/test_invalid_operations.py +243 -0
  252. machine_dialect/tests/edge_cases/test_named_list_edge_cases.py +295 -0
  253. machine_dialect/tests/edge_cases/test_nested_structures.py +313 -0
  254. machine_dialect/tests/edge_cases/test_type_mixing.py +277 -0
  255. machine_dialect/tests/integration/test_array_operations_emulation.py +248 -0
  256. machine_dialect/tests/integration/test_list_compilation.py +395 -0
  257. machine_dialect/tests/integration/test_lists_and_dictionaries.py +322 -0
  258. machine_dialect/type_checking/__init__.py +21 -0
  259. machine_dialect/type_checking/tests/__init__.py +1 -0
  260. machine_dialect/type_checking/tests/test_type_system.py +230 -0
  261. machine_dialect/type_checking/type_system.py +270 -0
  262. machine_dialect-0.1.0a1.dist-info/METADATA +128 -0
  263. machine_dialect-0.1.0a1.dist-info/RECORD +268 -0
  264. machine_dialect-0.1.0a1.dist-info/WHEEL +5 -0
  265. machine_dialect-0.1.0a1.dist-info/entry_points.txt +3 -0
  266. machine_dialect-0.1.0a1.dist-info/licenses/LICENSE +201 -0
  267. machine_dialect-0.1.0a1.dist-info/top_level.txt +2 -0
  268. machine_dialect_vm/__init__.pyi +15 -0
@@ -0,0 +1,197 @@
1
+ """Main compiler module.
2
+
3
+ This module provides the main Compiler class that manages the entire
4
+ compilation process.
5
+ """
6
+
7
+ from pathlib import Path
8
+
9
+ from machine_dialect.compiler.config import CompilerConfig
10
+ from machine_dialect.compiler.context import CompilationContext
11
+ from machine_dialect.compiler.pipeline import CompilationPipeline
12
+
13
+
14
+ class Compiler:
15
+ """Main compiler class for Machine Dialect™.
16
+
17
+ Manages the entire compilation process from source files to bytecode,
18
+ including lexing, parsing, HIR/MIR generation, optimization, and
19
+ bytecode generation.
20
+
21
+ Attributes:
22
+ config: Compiler configuration settings.
23
+ pipeline: Compilation pipeline instance.
24
+ """
25
+
26
+ def __init__(self, config: CompilerConfig | None = None) -> None:
27
+ """Initialize the compiler.
28
+
29
+ Args:
30
+ config: Compiler configuration.
31
+ """
32
+ self.config = config or CompilerConfig()
33
+ self.pipeline = CompilationPipeline(self.config)
34
+
35
+ def compile_file(
36
+ self,
37
+ source_path: str | Path,
38
+ output_path: str | Path | None = None,
39
+ ) -> bool:
40
+ """Compile a Machine Dialect™ source file to bytecode.
41
+
42
+ Args:
43
+ source_path: Path to the .md source file to compile.
44
+ output_path: Optional output path for compiled bytecode.
45
+ If not provided, uses config default or derives from source.
46
+
47
+ Returns:
48
+ True if compilation succeeded without errors.
49
+
50
+ Raises:
51
+ FileNotFoundError: If source file doesn't exist.
52
+ PermissionError: If unable to write output file.
53
+ """
54
+ source_path = Path(source_path)
55
+
56
+ # Update output path in config if provided
57
+ if output_path:
58
+ self.config.output_path = Path(output_path)
59
+
60
+ # Run compilation pipeline
61
+ context = self.pipeline.compile_file(source_path)
62
+
63
+ # Print errors and warnings
64
+ context.print_errors_and_warnings()
65
+
66
+ # Check for errors
67
+ if context.has_errors():
68
+ return False
69
+
70
+ # Save compiled module if bytecode was generated
71
+ if context.bytecode_module and not self.config.mir_phase_only:
72
+ success = self._save_module(context)
73
+ if not success:
74
+ return False
75
+
76
+ # Show disassembly if requested
77
+ if self.config.verbose and context.bytecode_module:
78
+ self._show_disassembly(context)
79
+
80
+ # Print success message (but not for MIR-only mode)
81
+ if not self.config.mir_phase_only:
82
+ if self.config.verbose:
83
+ self._print_success(context)
84
+ else:
85
+ # Always print basic success message
86
+ output_path = context.get_output_path()
87
+ print(f"Successfully compiled to '{output_path}'")
88
+
89
+ return True
90
+
91
+ def compile_string(self, source: str, module_name: str = "__main__") -> CompilationContext:
92
+ """Compile a string of source code.
93
+
94
+ Args:
95
+ source: Source code string.
96
+ module_name: Name for the module.
97
+
98
+ Returns:
99
+ Compilation context with results.
100
+ """
101
+ # Create a context with dummy source path
102
+ context = CompilationContext(
103
+ source_path=Path("<string>"),
104
+ config=self.config,
105
+ source_content=source,
106
+ )
107
+
108
+ # Set module name
109
+ self.config.module_name = module_name
110
+
111
+ # Run compilation pipeline
112
+ return self.pipeline.compile(context)
113
+
114
+ def _save_module(self, context: CompilationContext) -> bool:
115
+ """Save compiled bytecode module to disk.
116
+
117
+ Args:
118
+ context: Compilation context containing bytecode module.
119
+
120
+ Returns:
121
+ True if save succeeded, False otherwise.
122
+
123
+ Note:
124
+ Errors during save are added to the compilation context.
125
+ """
126
+ if not context.bytecode_module:
127
+ return False
128
+
129
+ output_path = context.get_output_path()
130
+
131
+ try:
132
+ # Set module name
133
+ context.bytecode_module.name = context.get_module_name()
134
+
135
+ # Serialize and save using VM serializer
136
+ bytecode_data = context.bytecode_module.serialize()
137
+ with open(output_path, "wb") as f:
138
+ f.write(bytecode_data)
139
+
140
+ if self.config.verbose:
141
+ print(f"Wrote compiled module to {output_path}")
142
+
143
+ return True
144
+
145
+ except Exception as e:
146
+ context.add_error(f"Failed to save module: {e}")
147
+ return False
148
+
149
+ def _show_disassembly(self, context: CompilationContext) -> None:
150
+ """Display human-readable disassembly of compiled bytecode.
151
+
152
+ Args:
153
+ context: Compilation context containing bytecode module.
154
+
155
+ Note:
156
+ Currently placeholder - disassembly for register-based
157
+ bytecode is not yet implemented.
158
+ """
159
+ if not context.bytecode_module:
160
+ return
161
+
162
+ print("\n=== Disassembly ===")
163
+ # TODO: Implement disassembly for new register-based bytecode
164
+ print("Disassembly not yet implemented for register-based bytecode")
165
+
166
+ def _print_success(self, context: CompilationContext) -> None:
167
+ """Print detailed compilation success summary.
168
+
169
+ Args:
170
+ context: Compilation context containing statistics and results.
171
+
172
+ Note:
173
+ Only called when verbose mode is enabled in config.
174
+ """
175
+ stats = context.get_statistics()
176
+
177
+ print("\n=== Compilation Summary ===")
178
+ print(f"Source: {stats['source_file']}")
179
+ print(f"Module: {stats['module_name']}")
180
+
181
+ if "mir_functions" in stats:
182
+ print(f"Functions: {stats['mir_functions']}")
183
+
184
+ if "optimizations" in stats:
185
+ opt_stats = stats["optimizations"]
186
+ if opt_stats:
187
+ # opt_stats is a string summary, not a dict
188
+ if isinstance(opt_stats, str):
189
+ # Just show that optimizations were applied
190
+ print("Optimizations applied")
191
+ elif isinstance(opt_stats, dict):
192
+ print(f"Optimizations applied: {opt_stats.get('total_transformations', 0)}")
193
+
194
+ if "bytecode_chunks" in stats:
195
+ print(f"Bytecode chunks: {stats['bytecode_chunks']}")
196
+
197
+ print("Compilation successful!")
@@ -0,0 +1,149 @@
1
+ """Compiler configuration module.
2
+
3
+ This module defines configuration options for the Machine Dialect™ compiler.
4
+ """
5
+
6
+ from dataclasses import dataclass, field
7
+ from enum import IntEnum
8
+ from pathlib import Path
9
+
10
+
11
+ class OptimizationLevel(IntEnum):
12
+ """Optimization level enumeration."""
13
+
14
+ NONE = 0 # No optimizations
15
+ BASIC = 1 # Basic optimizations (constant folding, DCE)
16
+ STANDARD = 2 # Standard optimizations (default)
17
+ AGGRESSIVE = 3 # Aggressive optimizations (inlining, specialization)
18
+
19
+
20
+ @dataclass
21
+ class CompilerConfig:
22
+ """Compiler configuration settings.
23
+
24
+ Attributes:
25
+ optimization_level: Level of optimization to apply.
26
+ dump_mir: Whether to dump MIR representation.
27
+ dump_cfg: Path to export control flow graph.
28
+ show_optimization_report: Whether to show optimization report.
29
+ verbose: Enable verbose output.
30
+ debug: Enable debug mode.
31
+ profile_path: Path to profile data for PGO.
32
+ mir_phase_only: Stop after MIR generation.
33
+ output_path: Output file path.
34
+ module_name: Name for the compiled module.
35
+ """
36
+
37
+ optimization_level: OptimizationLevel = OptimizationLevel.STANDARD
38
+ dump_mir: bool = False
39
+ dump_cfg: Path | None = None
40
+ show_optimization_report: bool = False
41
+ verbose: bool = False
42
+ debug: bool = False
43
+ profile_path: Path | None = None
44
+ mir_phase_only: bool = False
45
+ output_path: Path | None = None
46
+ module_name: str | None = None
47
+
48
+ # MIR dumping options
49
+ mir_dump_verbosity: str = "normal"
50
+ mir_dump_phases: list[str] = field(default_factory=list)
51
+
52
+ # Optimization pass configuration
53
+ enabled_passes: list[str] | None = None
54
+ disabled_passes: list[str] | None = None
55
+ pass_pipeline: str | None = None # Custom pass pipeline
56
+
57
+ @classmethod
58
+ def from_cli_options(
59
+ cls,
60
+ opt_level: str = "2",
61
+ dump_mir: bool = False,
62
+ show_cfg: str | None = None,
63
+ opt_report: bool = False,
64
+ verbose: bool = False,
65
+ debug: bool = False,
66
+ mir_phase: bool = False,
67
+ output: str | None = None,
68
+ module_name: str | None = None,
69
+ **kwargs: object,
70
+ ) -> "CompilerConfig":
71
+ """Create config from CLI options.
72
+
73
+ Args:
74
+ opt_level: Optimization level string.
75
+ dump_mir: Whether to dump MIR.
76
+ show_cfg: Path for CFG export.
77
+ opt_report: Whether to show optimization report.
78
+ verbose: Enable verbose output.
79
+ debug: Enable debug mode.
80
+ mir_phase: Stop after MIR generation.
81
+ output: Output file path.
82
+ module_name: Module name.
83
+ **kwargs: Additional options.
84
+
85
+ Returns:
86
+ Compiler configuration instance.
87
+ """
88
+ return cls(
89
+ optimization_level=OptimizationLevel(int(opt_level)),
90
+ dump_mir=dump_mir,
91
+ dump_cfg=Path(show_cfg) if show_cfg else None,
92
+ show_optimization_report=opt_report,
93
+ verbose=verbose,
94
+ debug=debug,
95
+ mir_phase_only=mir_phase,
96
+ output_path=Path(output) if output else None,
97
+ module_name=module_name,
98
+ )
99
+
100
+ def get_optimization_passes(self) -> list[str]:
101
+ """Get list of optimization passes to run based on level.
102
+
103
+ Returns:
104
+ List of optimization pass names.
105
+ """
106
+ if self.pass_pipeline:
107
+ return self.pass_pipeline.split(",")
108
+
109
+ passes = []
110
+
111
+ if self.optimization_level >= OptimizationLevel.BASIC:
112
+ passes.extend(
113
+ [
114
+ "constant-folding",
115
+ "constant-propagation",
116
+ "dce",
117
+ "simplify-cfg",
118
+ ]
119
+ )
120
+
121
+ if self.optimization_level >= OptimizationLevel.STANDARD:
122
+ passes.extend(
123
+ [
124
+ "cse",
125
+ "strength-reduction",
126
+ "algebraic-simplification", # New pass
127
+ "licm",
128
+ "loop-unrolling",
129
+ "tail-call",
130
+ ]
131
+ )
132
+
133
+ if self.optimization_level >= OptimizationLevel.AGGRESSIVE:
134
+ passes.extend(
135
+ [
136
+ "inlining",
137
+ "type-specialization",
138
+ "branch-prediction",
139
+ "escape-analysis",
140
+ ]
141
+ )
142
+
143
+ # Filter based on enabled/disabled lists
144
+ if self.enabled_passes:
145
+ passes = [p for p in passes if p in self.enabled_passes]
146
+ if self.disabled_passes:
147
+ passes = [p for p in passes if p not in self.disabled_passes]
148
+
149
+ return passes
@@ -0,0 +1,149 @@
1
+ """Compilation context module.
2
+
3
+ This module manages the state and context throughout the compilation process.
4
+ """
5
+
6
+ from dataclasses import dataclass, field
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ from machine_dialect.ast.ast_node import ASTNode
11
+ from machine_dialect.codegen.bytecode_module import BytecodeModule
12
+ from machine_dialect.compiler.config import CompilerConfig
13
+ from machine_dialect.mir.mir_module import MIRModule
14
+ from machine_dialect.mir.profiling.profile_data import ProfileData
15
+ from machine_dialect.mir.reporting.optimization_reporter import OptimizationReporter
16
+
17
+
18
+ @dataclass
19
+ class CompilationContext:
20
+ """Context for a single compilation session.
21
+
22
+ Attributes:
23
+ source_path: Path to source file being compiled.
24
+ config: Compiler configuration.
25
+ source_content: Source file content.
26
+ ast: Abstract syntax tree.
27
+ mir_module: MIR module.
28
+ bytecode_module: Bytecode module.
29
+ optimization_reporter: Optimization statistics reporter.
30
+ profile_data: Profile data for PGO.
31
+ errors: List of compilation errors.
32
+ warnings: List of compilation warnings.
33
+ metadata: Additional compilation metadata.
34
+ """
35
+
36
+ source_path: Path
37
+ config: CompilerConfig
38
+ source_content: str = ""
39
+ ast: ASTNode | None = None
40
+ mir_module: MIRModule | None = None
41
+ bytecode_module: BytecodeModule | None = None
42
+ optimization_reporter: OptimizationReporter | None = None
43
+ profile_data: ProfileData | None = None
44
+ errors: list[str] = field(default_factory=list)
45
+ warnings: list[str] = field(default_factory=list)
46
+ metadata: dict[str, Any] = field(default_factory=dict)
47
+
48
+ def add_error(self, message: str) -> None:
49
+ """Add a compilation error.
50
+
51
+ Args:
52
+ message: Error message.
53
+ """
54
+ self.errors.append(message)
55
+
56
+ def add_warning(self, message: str) -> None:
57
+ """Add a compilation warning.
58
+
59
+ Args:
60
+ message: Warning message.
61
+ """
62
+ self.warnings.append(message)
63
+
64
+ def has_errors(self) -> bool:
65
+ """Check if compilation has errors.
66
+
67
+ Returns:
68
+ True if there are errors.
69
+ """
70
+ return len(self.errors) > 0
71
+
72
+ def get_module_name(self) -> str:
73
+ """Get the module name for compilation.
74
+
75
+ Returns:
76
+ Module name.
77
+ """
78
+ if self.config.module_name:
79
+ return self.config.module_name
80
+ return self.source_path.stem
81
+
82
+ def get_output_path(self) -> Path:
83
+ """Get the output path for compiled module.
84
+
85
+ Returns:
86
+ Output file path.
87
+ """
88
+ if self.config.output_path:
89
+ return self.config.output_path
90
+ return self.source_path.with_suffix(".mdbc")
91
+
92
+ def should_optimize(self) -> bool:
93
+ """Check if optimization should be performed.
94
+
95
+ Returns:
96
+ True if optimization is enabled.
97
+ """
98
+ from machine_dialect.compiler.config import OptimizationLevel
99
+
100
+ return self.config.optimization_level > OptimizationLevel.NONE
101
+
102
+ def should_dump_mir(self) -> bool:
103
+ """Check if MIR should be dumped.
104
+
105
+ Returns:
106
+ True if MIR dumping is enabled.
107
+ """
108
+ return self.config.dump_mir or self.config.mir_phase_only
109
+
110
+ def should_generate_bytecode(self) -> bool:
111
+ """Check if bytecode generation should proceed.
112
+
113
+ Returns:
114
+ True if bytecode should be generated.
115
+ """
116
+ return not self.config.mir_phase_only
117
+
118
+ def print_errors_and_warnings(self) -> None:
119
+ """Print compilation errors and warnings."""
120
+ for warning in self.warnings:
121
+ print(f"Warning: {warning}")
122
+
123
+ for error in self.errors:
124
+ print(f"Error: {error}", file=__import__("sys").stderr)
125
+
126
+ def get_statistics(self) -> dict[str, Any]:
127
+ """Get compilation statistics.
128
+
129
+ Returns:
130
+ Dictionary of compilation statistics.
131
+ """
132
+ stats = {
133
+ "source_file": str(self.source_path),
134
+ "module_name": self.get_module_name(),
135
+ "errors": len(self.errors),
136
+ "warnings": len(self.warnings),
137
+ }
138
+
139
+ if self.mir_module:
140
+ stats["mir_functions"] = len(self.mir_module.functions)
141
+ stats["mir_globals"] = len(self.mir_module.globals)
142
+
143
+ if self.optimization_reporter:
144
+ stats["optimizations"] = self.optimization_reporter.generate_summary()
145
+
146
+ if self.bytecode_module:
147
+ stats["bytecode_chunks"] = len(self.bytecode_module.chunks)
148
+
149
+ return stats
@@ -0,0 +1,19 @@
1
+ """Compilation phases module.
2
+
3
+ This module contains individual compilation phases that make up the
4
+ compilation pipeline.
5
+ """
6
+
7
+ from machine_dialect.compiler.phases.codegen import CodeGenerationPhase
8
+ from machine_dialect.compiler.phases.hir_generation import HIRGenerationPhase
9
+ from machine_dialect.compiler.phases.mir_generation import MIRGenerationPhase
10
+ from machine_dialect.compiler.phases.optimization import OptimizationPhase
11
+ from machine_dialect.compiler.phases.parsing import ParsingPhase
12
+
13
+ __all__ = [
14
+ "CodeGenerationPhase",
15
+ "HIRGenerationPhase",
16
+ "MIRGenerationPhase",
17
+ "OptimizationPhase",
18
+ "ParsingPhase",
19
+ ]
@@ -0,0 +1,90 @@
1
+ """Bytecode optimization phase.
2
+
3
+ This module handles bytecode-level optimizations after code generation.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import TYPE_CHECKING
9
+
10
+ from machine_dialect.codegen.bytecode_module import BytecodeModule
11
+ from machine_dialect.mir.optimizations.jump_threading import JumpThreadingOptimizer
12
+
13
+ if TYPE_CHECKING:
14
+ from machine_dialect.compiler.context import CompilationContext
15
+
16
+
17
+ class BytecodeOptimizationPhase:
18
+ """Bytecode optimization phase.
19
+
20
+ Applies bytecode-level optimizations like jump threading,
21
+ peephole optimization, etc.
22
+ """
23
+
24
+ def __init__(self) -> None:
25
+ """Initialize the bytecode optimization phase."""
26
+ self.jump_threading = JumpThreadingOptimizer()
27
+
28
+ def run(self, context: CompilationContext, bytecode_module: BytecodeModule) -> BytecodeModule:
29
+ """Run bytecode optimizations.
30
+
31
+ Args:
32
+ context: Compilation context.
33
+ bytecode_module: Bytecode module to optimize.
34
+
35
+ Returns:
36
+ Optimized bytecode module.
37
+ """
38
+ if not context.should_optimize():
39
+ return bytecode_module
40
+
41
+ if context.config.verbose:
42
+ print("Running bytecode optimizations...")
43
+
44
+ # Apply jump threading to each chunk
45
+ optimized_chunks = []
46
+ total_stats = {
47
+ "jumps_threaded": 0,
48
+ "blocks_eliminated": 0,
49
+ "jumps_simplified": 0,
50
+ "blocks_merged": 0,
51
+ }
52
+
53
+ for chunk in bytecode_module.chunks:
54
+ # Reset optimizer for each chunk
55
+ self.jump_threading = JumpThreadingOptimizer()
56
+
57
+ # Optimize the chunk
58
+ optimized_chunk = self.jump_threading.optimize(chunk)
59
+ optimized_chunks.append(optimized_chunk)
60
+
61
+ # Accumulate statistics
62
+ stats = self.jump_threading.get_stats()
63
+ for key, value in stats.items():
64
+ total_stats[key] += value
65
+
66
+ # Create new module with optimized chunks
67
+ optimized_module = BytecodeModule(bytecode_module.name)
68
+ optimized_module.chunks = optimized_chunks
69
+ optimized_module.function_table = bytecode_module.function_table.copy()
70
+ optimized_module.global_names = bytecode_module.global_names.copy()
71
+ optimized_module.metadata = bytecode_module.metadata.copy()
72
+
73
+ # Report optimization results
74
+ if context.config.verbose and any(total_stats.values()):
75
+ print("\n=== Bytecode Optimization Results ===")
76
+ if total_stats["jumps_threaded"] > 0:
77
+ print(f" Jumps threaded: {total_stats['jumps_threaded']}")
78
+ if total_stats["blocks_eliminated"] > 0:
79
+ print(f" Dead blocks eliminated: {total_stats['blocks_eliminated']}")
80
+ if total_stats["jumps_simplified"] > 0:
81
+ print(f" Conditional jumps simplified: {total_stats['jumps_simplified']}")
82
+ if total_stats["blocks_merged"] > 0:
83
+ print(f" Blocks merged: {total_stats['blocks_merged']}")
84
+ print()
85
+
86
+ # Store stats in context for reporting
87
+ if context.optimization_reporter:
88
+ context.optimization_reporter.add_custom_stats("bytecode_optimization", total_stats)
89
+
90
+ return optimized_module
@@ -0,0 +1,40 @@
1
+ """Register-based code generation phase.
2
+
3
+ This module handles the register-based bytecode generation for the new Rust VM.
4
+ """
5
+
6
+ from machine_dialect.codegen.bytecode_module import BytecodeModule
7
+ from machine_dialect.codegen.register_codegen import RegisterBytecodeGenerator
8
+ from machine_dialect.compiler.context import CompilationContext
9
+ from machine_dialect.mir.mir_module import MIRModule
10
+
11
+
12
+ class CodeGenerationPhase:
13
+ """Register-based bytecode generation phase."""
14
+
15
+ def run(self, context: CompilationContext, mir_module: MIRModule) -> BytecodeModule | None:
16
+ """Run code generation phase.
17
+
18
+ Args:
19
+ context: Compilation context.
20
+ mir_module: MIR module to generate code from.
21
+
22
+ Returns:
23
+ Bytecode module or None if generation failed.
24
+ """
25
+ try:
26
+ # Create bytecode generator with debug if verbose mode is on
27
+ debug = context.config.verbose if context.config else False
28
+ generator = RegisterBytecodeGenerator(debug=debug)
29
+
30
+ # Generate bytecode from MIR
31
+ bytecode_module = generator.generate(mir_module)
32
+
33
+ # Store in context
34
+ context.bytecode_module = bytecode_module
35
+
36
+ return bytecode_module
37
+
38
+ except Exception as e:
39
+ context.add_error(f"Code generation failed: {e}")
40
+ return None
@@ -0,0 +1,39 @@
1
+ """HIR generation phase of compilation.
2
+
3
+ This module handles the High-level IR generation (desugaring) phase.
4
+ """
5
+
6
+ from machine_dialect.ast.ast_node import ASTNode
7
+ from machine_dialect.compiler.context import CompilationContext
8
+
9
+
10
+ class HIRGenerationPhase:
11
+ """HIR generation (desugaring) phase."""
12
+
13
+ def run(self, context: CompilationContext, ast: ASTNode) -> ASTNode:
14
+ """Run HIR generation phase.
15
+
16
+ Converts AST to HIR by applying desugaring and canonicalization
17
+ transformations using the to_hir method.
18
+
19
+ Args:
20
+ context: Compilation context.
21
+ ast: Abstract syntax tree.
22
+
23
+ Returns:
24
+ HIR representation with desugared and canonicalized nodes.
25
+ """
26
+ if context.config.verbose:
27
+ print("Generating HIR")
28
+
29
+ # Use to_hir to convert AST to HIR
30
+ # The ast should be a Program which has to_hir method
31
+ from machine_dialect.ast.program import Program
32
+
33
+ assert isinstance(ast, Program), "HIR generation expects a Program node"
34
+ hir = ast.to_hir()
35
+
36
+ if context.config.verbose:
37
+ print("HIR generation complete")
38
+
39
+ return hir