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,277 @@
1
+ """Edge case tests for mixed-type collections."""
2
+
3
+ import pytest
4
+
5
+ from machine_dialect.parser.parser import Parser
6
+
7
+
8
+ class TestTypeMixing:
9
+ """Test collections with mixed types."""
10
+
11
+ def test_mixed_type_unordered_list(self) -> None:
12
+ """Test unordered list with various types."""
13
+ source = """
14
+ Define `mixed` as unordered list.
15
+ Set `mixed` to:
16
+ - _42_.
17
+ - _3.14_.
18
+ - _"string"_.
19
+ - _yes_.
20
+ - _no_.
21
+ - empty.
22
+
23
+ Define `first` as Text.
24
+ Define `last` as Text.
25
+
26
+ Set `first` to the first item of `mixed`.
27
+ Set `last` to the last item of `mixed`.
28
+ """
29
+ parser = Parser()
30
+ parser.parse(source, check_semantics=False)
31
+
32
+ # Should parse successfully
33
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
34
+
35
+ def test_mixed_type_ordered_list(self) -> None:
36
+ """Test ordered list with various types."""
37
+ source = """
38
+ Define `mixed` as ordered list.
39
+ Set `mixed` to:
40
+ 1. _42_.
41
+ 2. _"text"_.
42
+ 3. _yes_.
43
+ 4. empty.
44
+ 5. _-5_.
45
+ 6. _0.0_.
46
+
47
+ Add _no_ to `mixed`.
48
+ Remove empty from `mixed`.
49
+ """
50
+ parser = Parser()
51
+ parser.parse(source, check_semantics=False)
52
+
53
+ # Should parse successfully
54
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
55
+
56
+ @pytest.mark.skip(reason="TODO: Statement count mismatch - needs investigation")
57
+ def test_empty_value_in_collections(self) -> None:
58
+ """Test handling of 'empty' literal in collections.""" # TODO: Fix statement count mismatch
59
+ source = """
60
+ Define `list_with_empty` as unordered list.
61
+ Set `list_with_empty` to:
62
+ - _"before"_.
63
+ - empty.
64
+ - _"after"_.
65
+
66
+ Define `x` as Text.
67
+ Set `x` to item _2_ of `list_with_empty`. # Should be empty
68
+
69
+ Remove empty from `list_with_empty`.
70
+ Add empty to `list_with_empty`.
71
+ """
72
+ parser = Parser()
73
+ parser.parse(source, check_semantics=False)
74
+
75
+ # Should parse successfully
76
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
77
+
78
+ @pytest.mark.skip(reason="TODO: Fix assertion counts after parser updates")
79
+ def test_identifier_vs_literal_mixing(self) -> None:
80
+ """Test mixing identifiers and literals in collections.""" # TODO: Fix assertion counts after parser updates
81
+ source = """
82
+ Define `var1` as Whole Number.
83
+ Define `var2` as Text.
84
+ Set `var1` to _10_.
85
+ Set `var2` to _"hello"_.
86
+
87
+ Define `mixed` as unordered list.
88
+ Set `mixed` to:
89
+ - `var1`.
90
+ - _20_.
91
+ - `var2`.
92
+ - _"world"_.
93
+
94
+ Define `x` as Text.
95
+ Define `y` as Text.
96
+
97
+ Set `x` to the first item of `mixed`. # Identifier value
98
+ Set `y` to the second item of `mixed`. # Literal value
99
+ """
100
+ parser = Parser()
101
+ parser.parse(source, check_semantics=False)
102
+
103
+ # Should parse successfully
104
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
105
+
106
+ @pytest.mark.skip(reason="TODO: Fix assertion counts after parser updates")
107
+ def test_boolean_mixing(self) -> None:
108
+ """Test collections with boolean values.""" # TODO: Fix assertion counts after parser updates
109
+ source = """
110
+ Define `booleans` as unordered list.
111
+ Set `booleans` to:
112
+ - _yes_.
113
+ - _no_.
114
+ - _yes_.
115
+ - _no_.
116
+
117
+ # Operations with boolean values
118
+ Remove _yes_ from `booleans`.
119
+ Add _no_ to `booleans`.
120
+ Set item _1_ of `booleans` to _yes_.
121
+ """
122
+ parser = Parser()
123
+ parser.parse(source, check_semantics=False)
124
+
125
+ # Should parse successfully
126
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
127
+
128
+ @pytest.mark.skip(reason="TODO: Fix assertion counts after parser updates")
129
+ def test_numeric_type_mixing(self) -> None:
130
+ """Test mixing integer and float types.""" # TODO: Fix assertion counts after parser updates
131
+ source = """
132
+ Define `numbers` as ordered list.
133
+ Set `numbers` to:
134
+ 1. _1_.
135
+ 2. _1.0_.
136
+ 3. _2_.
137
+ 4. _2.0_.
138
+ 5. _-3_.
139
+ 6. _-3.14_.
140
+
141
+ # Operations with mixed numeric types
142
+ Remove _1_ from `numbers`. # Integer
143
+ Remove _2.0_ from `numbers`. # Float
144
+ Add _0_ to `numbers`. # Integer zero
145
+ Add _0.0_ to `numbers`. # Float zero
146
+ """
147
+ parser = Parser()
148
+ parser.parse(source, check_semantics=False)
149
+
150
+ # Should parse successfully
151
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
152
+
153
+ @pytest.mark.skip(reason="TODO: Fix test - remove comments and verify assertions")
154
+ def test_nested_mixed_types(self) -> None:
155
+ """Test nested collections with mixed types.""" # TODO: Fix test - remove comments and verify assertions
156
+ source = """
157
+ Define `inner1` as unordered list.
158
+ Set `inner1` to:
159
+ - _1_.
160
+ - _"text"_.
161
+
162
+ Define `inner2` as ordered list.
163
+ Set `inner2` to:
164
+ 1. _yes_.
165
+ 2. empty.
166
+
167
+ Define `nested` as unordered list.
168
+ Set `nested` to:
169
+ - `inner1`.
170
+ - _42_.
171
+ - `inner2`.
172
+ - _"standalone"_.
173
+
174
+ Define `x` as Text.
175
+ Define `y` as Text.
176
+
177
+ Set `x` to the first item of `nested`. # A list
178
+ Set `y` to the second item of `nested`. # A number
179
+ """
180
+ parser = Parser()
181
+ parser.parse(source, check_semantics=False)
182
+
183
+ # Should parse successfully
184
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
185
+
186
+ @pytest.mark.skip(reason="TODO: Fix assertion counts after parser updates")
187
+ def test_type_changing_operations(self) -> None:
188
+ """Test operations that change element types.""" # TODO: Fix assertion counts after parser updates
189
+ source = """
190
+ Define `list` as unordered list.
191
+ Set `list` to:
192
+ - _1_.
193
+ - _2_.
194
+ - _3_.
195
+
196
+ # Change numeric to string
197
+ Set item _1_ of `list` to _"one"_.
198
+
199
+ # Change to boolean
200
+ Set item _2_ of `list` to _yes_.
201
+
202
+ # Change to empty
203
+ Set item _3_ of `list` to empty.
204
+
205
+ # Now list has mixed types
206
+ Add _4_ to `list`. # Add number to mixed list
207
+ Add _"five"_ to `list`. # Add string to mixed list
208
+ """
209
+ parser = Parser()
210
+ parser.parse(source, check_semantics=False)
211
+
212
+ # Should parse successfully
213
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
214
+
215
+ @pytest.mark.skip(reason="TODO: Fix assertion counts after parser updates")
216
+ def test_comparison_with_mixed_types(self) -> None:
217
+ """Test accessing and comparing mixed type elements.""" # TODO: Fix assertion counts after parser updates
218
+ source = """
219
+ Define `mixed` as unordered list.
220
+ Set `mixed` to:
221
+ - _1_.
222
+ - _"1"_.
223
+ - _yes_.
224
+ - empty.
225
+
226
+ Define `num` as Whole Number.
227
+ Define `str` as Text.
228
+ Define `bool` as Yes/No.
229
+ Define `null` as Text.
230
+
231
+ Set `num` to item _1_ of `mixed`. # Number 1
232
+ Set `str` to item _2_ of `mixed`. # String "1"
233
+ Set `bool` to item _3_ of `mixed`. # Boolean yes
234
+ Set `null` to item _4_ of `mixed`. # empty/null
235
+ """
236
+ parser = Parser()
237
+ parser.parse(source, check_semantics=False)
238
+
239
+ # Should parse successfully
240
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
241
+
242
+ @pytest.mark.skip(reason="TODO: Fix assertion counts after parser updates")
243
+ def test_large_mixed_collection(self) -> None:
244
+ """Test large collection with many different types.""" # TODO: Fix assertion counts after parser updates
245
+ source = """
246
+ Define `large_mixed` as unordered list.
247
+ Set `large_mixed` to:
248
+ - _0_.
249
+ - _"zero"_.
250
+ - _yes_.
251
+ - _1_.
252
+ - _"one"_.
253
+ - _no_.
254
+ - _2_.
255
+ - _"two"_.
256
+ - empty.
257
+ - _3.14_.
258
+ - _"pi"_.
259
+ - _-1_.
260
+ - _"negative"_.
261
+ - _0.0_.
262
+ - _""_.
263
+
264
+ Define `a` as Text.
265
+ Define `b` as Text.
266
+ Define `c` as Text.
267
+
268
+ # Access various elements
269
+ Set `a` to item _1_ of `large_mixed`.
270
+ Set `b` to item _9_ of `large_mixed`.
271
+ Set `c` to the last item of `large_mixed`.
272
+ """
273
+ parser = Parser()
274
+ parser.parse(source, check_semantics=False)
275
+
276
+ # Should parse successfully
277
+ # assert len(parser.program.statements) if hasattr(parser, "program") else pass
@@ -0,0 +1,248 @@
1
+ """Integration tests for emulated array operations."""
2
+
3
+ import tempfile
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from machine_dialect.compiler.config import CompilerConfig
8
+ from machine_dialect.compiler.pipeline import CompilationPipeline
9
+
10
+
11
+ def compile_source(source: str) -> Any:
12
+ """Helper function to compile source string."""
13
+ config = CompilerConfig(verbose=False)
14
+ pipeline = CompilationPipeline(config)
15
+
16
+ # Write source to temporary file
17
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
18
+ f.write(source)
19
+ temp_path = Path(f.name)
20
+
21
+ try:
22
+ context = pipeline.compile_file(temp_path)
23
+ return context
24
+ finally:
25
+ temp_path.unlink(missing_ok=True)
26
+
27
+
28
+ class TestArrayOperationsEmulation:
29
+ """Test that array operations compile and generate correct bytecode."""
30
+
31
+ def test_insert_operation_compiles(self) -> None:
32
+ """Test that insert operations compile to bytecode."""
33
+ source = """
34
+ Define `items` as Ordered List.
35
+ Set `items` to:
36
+ 1. _"first"_.
37
+ 2. _"second"_.
38
+ 3. _"third"_.
39
+
40
+ Insert _"new"_ at position _2_ in `items`.
41
+ """
42
+
43
+ context = compile_source(source)
44
+
45
+ # Should compile without errors
46
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
47
+
48
+ # Should generate bytecode
49
+ assert context.bytecode_module is not None
50
+ assert len(context.bytecode_module.chunks) > 0
51
+ bytecode = context.bytecode_module.chunks[0].bytecode
52
+ assert len(bytecode) > 0
53
+
54
+ # Should have substantial bytecode (insert is complex)
55
+ assert len(bytecode) > 100, "Insert should generate substantial bytecode"
56
+
57
+ def test_remove_by_value_compiles(self) -> None:
58
+ """Test that remove by value operations compile."""
59
+ source = """
60
+ Define `fruits` as Unordered List.
61
+ Set `fruits` to:
62
+ - _"apple"_.
63
+ - _"banana"_.
64
+ - _"cherry"_.
65
+
66
+ Remove _"banana"_ from `fruits`.
67
+ """
68
+
69
+ context = compile_source(source)
70
+
71
+ # Should compile without errors
72
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
73
+
74
+ # Should generate bytecode
75
+ assert context.bytecode_module is not None
76
+ assert len(context.bytecode_module.chunks) > 0
77
+ bytecode = context.bytecode_module.chunks[0].bytecode
78
+ assert len(bytecode) > 0
79
+
80
+ # Remove by value uses ArrayFindIndex + ArrayRemove, so lots of code
81
+ assert len(bytecode) > 150, "Remove by value should generate substantial bytecode"
82
+
83
+ def test_multiple_operations(self) -> None:
84
+ """Test that multiple array operations work together."""
85
+ source = """
86
+ Define `tasks` as Ordered List.
87
+ Set `tasks` to:
88
+ 1. _"Task A"_.
89
+ 2. _"Task B"_.
90
+ 3. _"Task C"_.
91
+
92
+ Insert _"Task A.5"_ at position _2_ in `tasks`.
93
+ Remove _"Task B"_ from `tasks`.
94
+ Add _"Task D"_ to `tasks`.
95
+ """
96
+
97
+ context = compile_source(source)
98
+
99
+ # Should compile without errors
100
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
101
+
102
+ # Should generate bytecode
103
+ assert context.bytecode_module is not None
104
+ assert len(context.bytecode_module.chunks) > 0
105
+ bytecode = context.bytecode_module.chunks[0].bytecode
106
+ assert len(bytecode) > 0
107
+
108
+ def test_insert_at_beginning(self) -> None:
109
+ """Test inserting at the beginning of a list."""
110
+ source = """
111
+ Define `numbers` as Unordered List.
112
+ Set `numbers` to:
113
+ - _10_.
114
+ - _20_.
115
+ - _30_.
116
+
117
+ Insert _5_ at position _1_ in `numbers`.
118
+ """
119
+
120
+ context = compile_source(source)
121
+
122
+ # Should compile without errors
123
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
124
+
125
+ # Should generate bytecode
126
+ assert context.bytecode_module is not None
127
+
128
+ def test_insert_at_end(self) -> None:
129
+ """Test inserting at the end of a list (like append but with position)."""
130
+ source = """
131
+ Define `items` as Ordered List.
132
+ Set `items` to:
133
+ 1. _"one"_.
134
+ 2. _"two"_.
135
+
136
+ Define `length` as Whole Number.
137
+ Set `length` to _3_.
138
+ Insert _"three"_ at position `length` in `items`.
139
+ """
140
+
141
+ context = compile_source(source)
142
+
143
+ # Should compile without errors
144
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
145
+
146
+ def test_remove_nonexistent_value(self) -> None:
147
+ """Test removing a value that doesn't exist in the list."""
148
+ source = """
149
+ Define `colors` as Unordered List.
150
+ Set `colors` to:
151
+ - _"red"_.
152
+ - _"green"_.
153
+ - _"blue"_.
154
+
155
+ Remove _"yellow"_ from `colors`.
156
+ """
157
+
158
+ context = compile_source(source)
159
+
160
+ # Should compile without errors (runtime will handle -1 index)
161
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
162
+
163
+ def test_nested_list_operations(self) -> None:
164
+ """Test operations on lists containing lists."""
165
+ source = """
166
+ Define `matrix` as Unordered List.
167
+ Define `row1` as Unordered List.
168
+ Set `row1` to:
169
+ - _1_.
170
+ - _2_.
171
+
172
+ Define `row2` as Unordered List.
173
+ Set `row2` to:
174
+ - _3_.
175
+ - _4_.
176
+
177
+ Set `matrix` to:
178
+ - `row1`.
179
+ - `row2`.
180
+
181
+ Define `row3` as Unordered List.
182
+ Set `row3` to:
183
+ - _5_.
184
+ - _6_.
185
+
186
+ Add `row3` to `matrix`.
187
+ """
188
+
189
+ context = compile_source(source)
190
+
191
+ # Should compile without errors
192
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
193
+
194
+ def test_bytecode_contains_loops(self) -> None:
195
+ """Test that generated bytecode contains loop structures."""
196
+ source = """
197
+ Define `items` as Unordered List.
198
+ Set `items` to:
199
+ - _1_.
200
+ - _2_.
201
+ - _3_.
202
+
203
+ Remove _2_ from `items`.
204
+ """
205
+
206
+ context = compile_source(source)
207
+
208
+ assert not context.has_errors()
209
+ assert context.bytecode_module is not None
210
+ assert len(context.bytecode_module.chunks) > 0
211
+
212
+ # Check for jump instructions (indicate loops)
213
+ bytecode = context.bytecode_module.chunks[0].bytecode
214
+ has_jumps = False
215
+
216
+ # Look for jump opcodes (0x16 = JUMP_R, 0x17 = JUMP_IF_R, 0x18 = JUMP_IF_NOT_R)
217
+ for byte in bytecode:
218
+ if byte in [0x16, 0x17, 0x18]:
219
+ has_jumps = True
220
+ break
221
+
222
+ assert has_jumps, "Should contain jump instructions for loops"
223
+
224
+ def test_operations_with_variables(self) -> None:
225
+ """Test array operations using variables for positions and values."""
226
+ source = """
227
+ Define `data` as Ordered List.
228
+ Set `data` to:
229
+ 1. _100_.
230
+ 2. _200_.
231
+ 3. _300_.
232
+
233
+ Define `pos` as Whole Number.
234
+ Set `pos` to _2_.
235
+
236
+ Define `val` as Whole Number.
237
+ Set `val` to _150_.
238
+
239
+ Insert `val` at position `pos` in `data`.
240
+ """
241
+
242
+ context = compile_source(source)
243
+
244
+ # Should compile without errors
245
+ assert not context.has_errors(), f"Compilation errors: {context.errors}"
246
+
247
+ # Should generate bytecode
248
+ assert context.bytecode_module is not None