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,270 @@
1
+ """Type system for compile-time type checking in Machine Dialect™.
2
+
3
+ This module provides the type system used during compilation for:
4
+ - Type checking variable definitions
5
+ - Validating assignments
6
+ - Union type support
7
+ - Type compatibility checking
8
+
9
+ IMPORTANT: This is for compile-time checking. Runtime types are in runtime/types.py.
10
+ """
11
+
12
+ from dataclasses import dataclass
13
+ from enum import Enum, auto
14
+ from typing import Any
15
+
16
+
17
+ class MDType(Enum):
18
+ """Machine Dialect™ type enumeration for compile-time type checking.
19
+
20
+ Maps to the language's type keywords and provides type compatibility rules.
21
+ """
22
+
23
+ TEXT = auto() # "Text" keyword
24
+ WHOLE_NUMBER = auto() # "Whole Number" keyword
25
+ FLOAT = auto() # "Float" keyword
26
+ NUMBER = auto() # "Number" keyword (integer or float)
27
+ YES_NO = auto() # "Yes/No" keyword (boolean)
28
+ URL = auto() # "URL" keyword
29
+ DATE = auto() # "Date" keyword
30
+ DATETIME = auto() # "DateTime" keyword
31
+ TIME = auto() # "Time" keyword
32
+ LIST = auto() # "List" keyword (generic list)
33
+ UNORDERED_LIST = auto() # Unordered list (dash markers)
34
+ ORDERED_LIST = auto() # Ordered list (numbered markers)
35
+ NAMED_LIST = auto() # Named list (dictionary with colon syntax)
36
+ EMPTY = auto() # "Empty" keyword (null/none)
37
+ ANY = auto() # "Any" keyword (future, dynamic type)
38
+
39
+
40
+ # Mapping from type names (as they appear in source) to MDType enum
41
+ TYPE_NAME_MAP = {
42
+ "Text": MDType.TEXT,
43
+ "Whole Number": MDType.WHOLE_NUMBER,
44
+ "Float": MDType.FLOAT,
45
+ "Number": MDType.NUMBER,
46
+ "Yes/No": MDType.YES_NO,
47
+ "URL": MDType.URL,
48
+ "Date": MDType.DATE,
49
+ "DateTime": MDType.DATETIME,
50
+ "Time": MDType.TIME,
51
+ "List": MDType.LIST,
52
+ "Unordered List": MDType.UNORDERED_LIST,
53
+ "Ordered List": MDType.ORDERED_LIST,
54
+ "Named List": MDType.NAMED_LIST,
55
+ "Empty": MDType.EMPTY,
56
+ "Any": MDType.ANY,
57
+ }
58
+
59
+
60
+ # Reverse mapping for error messages
61
+ TYPE_DISPLAY_NAMES = {
62
+ MDType.TEXT: "Text",
63
+ MDType.WHOLE_NUMBER: "Whole Number",
64
+ MDType.FLOAT: "Float",
65
+ MDType.NUMBER: "Number",
66
+ MDType.YES_NO: "Yes/No",
67
+ MDType.URL: "URL",
68
+ MDType.DATE: "Date",
69
+ MDType.DATETIME: "DateTime",
70
+ MDType.TIME: "Time",
71
+ MDType.LIST: "List",
72
+ MDType.UNORDERED_LIST: "Unordered List",
73
+ MDType.ORDERED_LIST: "Ordered List",
74
+ MDType.NAMED_LIST: "Named List",
75
+ MDType.EMPTY: "Empty",
76
+ MDType.ANY: "Any",
77
+ }
78
+
79
+
80
+ @dataclass
81
+ class TypeSpec:
82
+ """Type specification for a variable, supporting union types.
83
+
84
+ Attributes:
85
+ types: List of allowed types (for union types)
86
+ """
87
+
88
+ types: list[MDType]
89
+
90
+ def __init__(self, type_names: list[str]) -> None:
91
+ """Initialize TypeSpec from type name strings.
92
+
93
+ Args:
94
+ type_names: List of type names as strings (e.g., ["Whole Number", "Text"])
95
+ """
96
+ self.types = []
97
+ for name in type_names:
98
+ md_type = get_type_from_name(name)
99
+ if md_type:
100
+ self.types.append(md_type)
101
+
102
+ def allows_type(self, md_type: MDType) -> bool:
103
+ """Check if this TypeSpec allows the given type.
104
+
105
+ Args:
106
+ md_type: The type to check
107
+
108
+ Returns:
109
+ True if type is allowed, False otherwise
110
+ """
111
+ # ANY type allows everything
112
+ if MDType.ANY in self.types:
113
+ return True
114
+
115
+ # Check direct membership
116
+ if md_type in self.types:
117
+ return True
118
+
119
+ # Special case: Number allows both Whole Number and Float
120
+ if MDType.NUMBER in self.types:
121
+ if md_type in (MDType.WHOLE_NUMBER, MDType.FLOAT):
122
+ return True
123
+
124
+ # Special case: Whole Number/Float are assignable to Number
125
+ # (This is for when we have a Number variable and assign int/float)
126
+ # But this is handled by is_assignable_to, not here
127
+
128
+ return False
129
+
130
+ def __str__(self) -> str:
131
+ """Return human-readable type specification."""
132
+ if len(self.types) == 1:
133
+ return TYPE_DISPLAY_NAMES[self.types[0]]
134
+ return " or ".join(TYPE_DISPLAY_NAMES[t] for t in self.types)
135
+
136
+
137
+ def get_type_from_name(name: str) -> MDType | None:
138
+ """Convert type name string to MDType enum.
139
+
140
+ Args:
141
+ name: Type name as it appears in source code
142
+
143
+ Returns:
144
+ Corresponding MDType or None if not recognized
145
+ """
146
+ return TYPE_NAME_MAP.get(name)
147
+
148
+
149
+ def get_type_from_value(value: Any) -> MDType | None:
150
+ """Determine the MDType of a literal value during compilation.
151
+
152
+ Args:
153
+ value: The value to determine the type of
154
+
155
+ Returns:
156
+ The MDType of the value or None if unknown
157
+ """
158
+ # This is for compile-time type checking of literals
159
+ # The value here would typically be from AST literal nodes
160
+
161
+ if value is None or (hasattr(value, "value") and value.value is None):
162
+ return MDType.EMPTY
163
+
164
+ # Check AST literal nodes
165
+ if hasattr(value, "__class__"):
166
+ class_name = value.__class__.__name__
167
+
168
+ if class_name == "WholeNumberLiteral":
169
+ return MDType.WHOLE_NUMBER
170
+ elif class_name == "FloatLiteral":
171
+ return MDType.FLOAT
172
+ elif class_name == "StringLiteral":
173
+ # Check if it's a URL
174
+ if hasattr(value, "value") and isinstance(value.value, str):
175
+ if value.value.startswith(("http://", "https://", "ftp://", "file://")):
176
+ return MDType.URL
177
+ return MDType.TEXT
178
+ elif class_name == "YesNoLiteral":
179
+ return MDType.YES_NO
180
+ elif class_name == "EmptyLiteral":
181
+ return MDType.EMPTY
182
+ elif class_name == "URLLiteral":
183
+ return MDType.URL
184
+ elif class_name == "UnorderedListLiteral":
185
+ return MDType.UNORDERED_LIST
186
+ elif class_name == "OrderedListLiteral":
187
+ return MDType.ORDERED_LIST
188
+ elif class_name == "NamedListLiteral":
189
+ return MDType.NAMED_LIST
190
+
191
+ # Fallback to Python types (for testing or when we have actual values)
192
+ if isinstance(value, bool):
193
+ return MDType.YES_NO
194
+ elif isinstance(value, int):
195
+ return MDType.WHOLE_NUMBER
196
+ elif isinstance(value, float):
197
+ return MDType.FLOAT
198
+ elif isinstance(value, str):
199
+ if value.startswith(("http://", "https://", "ftp://", "file://")):
200
+ return MDType.URL
201
+ return MDType.TEXT
202
+ elif isinstance(value, list):
203
+ return MDType.LIST # Generic list for Python lists
204
+ elif isinstance(value, dict):
205
+ return MDType.NAMED_LIST # Dictionary maps to named list
206
+ elif value == "empty" or value is None:
207
+ return MDType.EMPTY
208
+
209
+ return None
210
+
211
+
212
+ def is_assignable_to(value_type: MDType, target_type: MDType) -> bool:
213
+ """Check if a value of one type can be assigned to a variable of another type.
214
+
215
+ This implements the Machine Dialect™ type compatibility rules.
216
+ NO implicit conversions are allowed per the spec.
217
+
218
+ Args:
219
+ value_type: The type of the value being assigned
220
+ target_type: The type of the variable being assigned to
221
+
222
+ Returns:
223
+ True if assignment is allowed, False otherwise
224
+ """
225
+ # Exact match is always allowed
226
+ if value_type == target_type:
227
+ return True
228
+
229
+ # ANY type can accept anything
230
+ if target_type == MDType.ANY:
231
+ return True
232
+
233
+ # Number type can accept Whole Number or Float
234
+ if target_type == MDType.NUMBER:
235
+ if value_type in (MDType.WHOLE_NUMBER, MDType.FLOAT):
236
+ return True
237
+
238
+ # Empty can be assigned to any type (null/none value)
239
+ if value_type == MDType.EMPTY:
240
+ return True
241
+
242
+ # NO other implicit conversions per spec
243
+ return False
244
+
245
+
246
+ def check_type_compatibility(
247
+ value_type: MDType,
248
+ type_spec: TypeSpec,
249
+ ) -> tuple[bool, str | None]:
250
+ """Check if a value type is compatible with a type specification.
251
+
252
+ Args:
253
+ value_type: The type of the value being checked
254
+ type_spec: The type specification to check against
255
+
256
+ Returns:
257
+ Tuple of (is_compatible, error_message)
258
+ error_message is None if compatible
259
+ """
260
+ # Check each type in the union
261
+ for allowed_type in type_spec.types:
262
+ if is_assignable_to(value_type, allowed_type):
263
+ return (True, None)
264
+
265
+ # Not compatible with any type in the union
266
+ value_name = TYPE_DISPLAY_NAMES[value_type]
267
+ spec_name = str(type_spec)
268
+ error = f"Cannot assign {value_name} value to variable of type {spec_name}"
269
+
270
+ return (False, error)
@@ -0,0 +1,128 @@
1
+ Metadata-Version: 2.4
2
+ Name: machine-dialect
3
+ Version: 0.1.0a1
4
+ Summary: Machine Dialect™ - Natural language programming in Markdown
5
+ Author: Lajara AI, LLC
6
+ Project-URL: Homepage, https://github.com/kennylajara/machine-dialect
7
+ Project-URL: Bug Tracker, https://github.com/kennylajara/machine-dialect/issues
8
+ Keywords: programming-language,natural-language,markdown,compiler
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Code Generators
18
+ Classifier: Topic :: Software Development :: Compilers
19
+ Classifier: Topic :: Software Development :: Interpreters
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: rfc3986>=2.0.0
24
+ Requires-Dist: click>=8.1.0
25
+ Requires-Dist: lark>=1.2.2
26
+ Requires-Dist: openai>=1.99.9
27
+ Requires-Dist: machine-dialect-vm>=0.1.0a1
28
+ Dynamic: license-file
29
+
30
+ # Machine Dialect™
31
+
32
+ The **Machine Dialect™ programming language** is designed to look like natural language and feel
33
+ like structured documentation. It is written in Markdown and intended to be both human-friendly
34
+ and AI-native — readable by people, generatable and parsable by machines.
35
+
36
+ > ⚠️ **ALPHA VERSION** ⚠️
37
+ >
38
+ > The Machine Dialect™ language is currently in **ALPHA** stage. We are rapidly iterating on the language
39
+ > design and implementation. During this phase:
40
+ >
41
+ > - **Breaking changes will be frequent** and without deprecation warnings
42
+ > - The syntax and semantics are still evolving based on user feedback
43
+ > - APIs and compiler behavior may change between any versions
44
+ > - No backward compatibility is maintained during alpha
45
+ >
46
+ > We encourage experimentation and feedback, but please be aware that code written today
47
+ > may require updates to work with future versions.
48
+
49
+ ## Table of Contents
50
+
51
+ - [Why Another Programming Language?](#why-another-programming-language)
52
+ - [Installation](#installation)
53
+ - [Getting Started](#getting-started)
54
+ - [Contributing](#contributing)
55
+ - [License](#license)
56
+
57
+ ## Why Another Programming Language?
58
+
59
+ Modern programming languages were made for humans to instruct machines. But now that machines
60
+ can understand and generate human-like language, it's time to rethink the language itself.
61
+
62
+ The Machine Dialect™ language is designed for a world where:
63
+
64
+ - **AI writes most of the code**, and humans supervise, modify, and approve
65
+ - Code is **visually readable**, even by non-programmers
66
+ - The structure of the program is as **intuitive as a document**, and lives comfortably inside
67
+ Markdown files
68
+
69
+ ### The Philosophy of Machine Dialect™
70
+
71
+ - **Natural structure**: Programs are written as paragraphs, headings, lists — not brackets,
72
+ semicolons, and cryptic symbols
73
+ - **AI-first**: Syntax is deterministic enough for parsing, but optimized for LLMs to
74
+ generate and understand effortlessly
75
+ - **Human-friendly**: Uses everyday words over technical jargon. Markdown keeps everything readable,
76
+ diffable, and renderable
77
+ - **Self-documenting**: Looks like pseudocode. Reads like an explanation of what the code does
78
+
79
+ ## Installation
80
+
81
+ ### From PyPI (Recommended)
82
+
83
+ ```bash
84
+ pip install machine-dialect
85
+ ```
86
+
87
+ ### From Source
88
+
89
+ For development installation, please see our [Contributing Guide](CONTRIBUTING.md#development-setup)
90
+ for detailed setup instructions.
91
+
92
+ ## Getting started
93
+
94
+ ### Writing Your First Program
95
+
96
+ Create a file `hello.md`:
97
+
98
+ > Define `greeting` as _Text_.\
99
+ > Set `greeting` to _"Hello, World!"_.
100
+ >
101
+ > Say `greeting`.
102
+
103
+ ### Compiling and Running Programs
104
+
105
+ The Machine Dialect™ toolchain provides a complete toolchain for compiling and executing programs:
106
+
107
+ ```bash
108
+ # Compile a .md file to bytecode (.mdbc)
109
+ python -m machine_dialect compile hello.md
110
+
111
+ # Compile with custom filename (main)
112
+ python -m machine_dialect compile hello.md -o main.mdbc
113
+
114
+ # Run a compiled bytecode file
115
+ python -m machine_dialect run hello.mdbc
116
+
117
+ # Interactive shell (REPL)
118
+ python -m machine_dialect shell
119
+ ```
120
+
121
+ ## Contributing
122
+
123
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for detailed information.
124
+
125
+ ## License
126
+
127
+ This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file
128
+ for details.