multilingualprogramming 0.2.0__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 (61) hide show
  1. multilingualprogramming/__init__.py +74 -0
  2. multilingualprogramming/__main__.py +194 -0
  3. multilingualprogramming/codegen/__init__.py +12 -0
  4. multilingualprogramming/codegen/executor.py +215 -0
  5. multilingualprogramming/codegen/python_generator.py +592 -0
  6. multilingualprogramming/codegen/repl.py +489 -0
  7. multilingualprogramming/codegen/runtime_builtins.py +308 -0
  8. multilingualprogramming/core/__init__.py +12 -0
  9. multilingualprogramming/core/ir.py +29 -0
  10. multilingualprogramming/core/lowering.py +24 -0
  11. multilingualprogramming/datetime/__init__.py +11 -0
  12. multilingualprogramming/datetime/date_parser.py +190 -0
  13. multilingualprogramming/datetime/mp_date.py +210 -0
  14. multilingualprogramming/datetime/mp_datetime.py +153 -0
  15. multilingualprogramming/datetime/mp_time.py +147 -0
  16. multilingualprogramming/datetime/resource_loader.py +18 -0
  17. multilingualprogramming/exceptions.py +158 -0
  18. multilingualprogramming/imports.py +150 -0
  19. multilingualprogramming/keyword/__init__.py +13 -0
  20. multilingualprogramming/keyword/keyword_registry.py +249 -0
  21. multilingualprogramming/keyword/keyword_validator.py +59 -0
  22. multilingualprogramming/keyword/language_pack_validator.py +110 -0
  23. multilingualprogramming/lexer/__init__.py +11 -0
  24. multilingualprogramming/lexer/lexer.py +570 -0
  25. multilingualprogramming/lexer/source_reader.py +91 -0
  26. multilingualprogramming/lexer/token.py +54 -0
  27. multilingualprogramming/lexer/token_types.py +38 -0
  28. multilingualprogramming/numeral/__init__.py +11 -0
  29. multilingualprogramming/numeral/abstract_numeral.py +232 -0
  30. multilingualprogramming/numeral/complex_numeral.py +190 -0
  31. multilingualprogramming/numeral/fraction_numeral.py +165 -0
  32. multilingualprogramming/numeral/mp_numeral.py +243 -0
  33. multilingualprogramming/numeral/numeral_converter.py +151 -0
  34. multilingualprogramming/numeral/roman_numeral.py +301 -0
  35. multilingualprogramming/numeral/unicode_numeral.py +292 -0
  36. multilingualprogramming/parser/__init__.py +28 -0
  37. multilingualprogramming/parser/ast_nodes.py +459 -0
  38. multilingualprogramming/parser/ast_printer.py +677 -0
  39. multilingualprogramming/parser/error_messages.py +75 -0
  40. multilingualprogramming/parser/parser.py +1796 -0
  41. multilingualprogramming/parser/semantic_analyzer.py +689 -0
  42. multilingualprogramming/parser/surface_normalizer.py +282 -0
  43. multilingualprogramming/resources/datetime/eras.json +23 -0
  44. multilingualprogramming/resources/datetime/formats.json +32 -0
  45. multilingualprogramming/resources/datetime/months.json +150 -0
  46. multilingualprogramming/resources/datetime/weekdays.json +90 -0
  47. multilingualprogramming/resources/parser/error_messages.json +310 -0
  48. multilingualprogramming/resources/repl/commands.json +636 -0
  49. multilingualprogramming/resources/usm/builtins_aliases.json +731 -0
  50. multilingualprogramming/resources/usm/keywords.json +1063 -0
  51. multilingualprogramming/resources/usm/operators.json +532 -0
  52. multilingualprogramming/resources/usm/schema.json +34 -0
  53. multilingualprogramming/resources/usm/surface_patterns.json +1523 -0
  54. multilingualprogramming/unicode_string.py +140 -0
  55. multilingualprogramming/version.py +9 -0
  56. multilingualprogramming-0.2.0.dist-info/METADATA +350 -0
  57. multilingualprogramming-0.2.0.dist-info/RECORD +61 -0
  58. multilingualprogramming-0.2.0.dist-info/WHEEL +5 -0
  59. multilingualprogramming-0.2.0.dist-info/entry_points.txt +3 -0
  60. multilingualprogramming-0.2.0.dist-info/licenses/LICENSE +674 -0
  61. multilingualprogramming-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,292 @@
1
+ #
2
+ # SPDX-FileCopyrightText: 2022 John Samuel <johnsamuelwrites@gmail.com>
3
+ #
4
+ # SPDX-License-Identifier: GPL-3.0-or-later
5
+ #
6
+
7
+ """Functions to handle numbers of multiple languages
8
+ """
9
+
10
+ import unicodedata
11
+ import re
12
+ import locale
13
+ from operator import invert, neg
14
+ from multilingualprogramming.exceptions import (
15
+ InvalidNumeralCharacterError,
16
+ MultipleLanguageCharacterMixError,
17
+ )
18
+ from multilingualprogramming.unicode_string import (
19
+ get_unicode_character_string,
20
+ convert_numeral_string,
21
+ )
22
+ from multilingualprogramming.numeral.abstract_numeral import AbstractNumeral
23
+
24
+
25
+ class UnicodeNumeral(AbstractNumeral):
26
+ """
27
+ Handling numerals in unicode-supported languages
28
+ """
29
+
30
+ @classmethod
31
+ def __verify_unicode_category__(cls, self, numstr: str):
32
+ """
33
+ Verify the unicode category of each character
34
+ """
35
+ running_character_name = None
36
+ for character in numstr:
37
+ if unicodedata.category(character) != "Nd":
38
+ # Handle decimal separators of all locales
39
+ decimal_separator = locale.localeconv()["decimal_point"]
40
+ if character in decimal_separator or character in ["-"]:
41
+ continue
42
+
43
+ raise InvalidNumeralCharacterError(
44
+ "Not a valid number, contains the character: " + character
45
+ )
46
+ current_character_name = unicodedata.name(character)
47
+ current_character_name = re.sub(r" .*$", "", current_character_name)
48
+
49
+ if running_character_name is not None:
50
+ if running_character_name != current_character_name:
51
+ self.language_name = None
52
+ raise MultipleLanguageCharacterMixError(
53
+ "Not a valid number, mix of characters from multiple scripts, found "
54
+ + character
55
+ )
56
+ else:
57
+ self.language_name = current_character_name
58
+ running_character_name = current_character_name
59
+
60
+ def __init__(self, numstr: str):
61
+ super().__init__(numstr)
62
+ self.numstr = numstr
63
+ self.language_name = None
64
+ self.__verify_unicode_category__(self, numstr)
65
+
66
+ def to_decimal(self):
67
+ """
68
+ Returns the number associated with the number string
69
+ given by the user
70
+
71
+ return:
72
+ number: number associated with the number string
73
+ """
74
+ decimal_separator = locale.localeconv()["decimal_point"]
75
+ self.numstr = self.numstr.replace(decimal_separator, ".")
76
+ try:
77
+ if "." in self.numstr:
78
+ return float(self.numstr)
79
+ return int(self.numstr)
80
+ except ValueError:
81
+ return None
82
+
83
+ def __str__(self):
84
+ """
85
+ Returns the original number string
86
+
87
+ return:
88
+ numstr: original number string
89
+ """
90
+ return self.numstr
91
+
92
+ def __repr__(self):
93
+ """
94
+ Returns the representation of an instance
95
+
96
+ return:
97
+ reprstr: representation of an instance
98
+ """
99
+ return f'UnicodeNumeral("{self.numstr}")'
100
+
101
+ def __add__(self, numeral):
102
+ """
103
+ Add a UnicodeNumeral with a numeral or another UnicodeNumeral
104
+
105
+ return:
106
+ UnicodeNumeral: returns the sum of a UnicodeNumeral
107
+ """
108
+ return UnicodeNumeral(
109
+ get_unicode_character_string(
110
+ self.language_name, self.to_decimal() + numeral.to_decimal()
111
+ )
112
+ )
113
+
114
+ def __mul__(self, numeral):
115
+ """
116
+ Multiply a UnicodeNumeral with a numeral or another UnicodeNumeral
117
+
118
+ return:
119
+ UnicodeNumeral: multiplication of the two UnicodeNumeral values
120
+ """
121
+ return UnicodeNumeral(
122
+ get_unicode_character_string(
123
+ self.language_name, self.to_decimal() * numeral.to_decimal()
124
+ )
125
+ )
126
+
127
+ def __lshift__(self, numeral):
128
+ """
129
+ Left-shifting of Unicode Numerals
130
+
131
+ return:
132
+ AbstractNumeral: returns the left shifted value
133
+ """
134
+ return UnicodeNumeral(
135
+ get_unicode_character_string(
136
+ self.language_name, self.to_decimal() << numeral.to_decimal()
137
+ )
138
+ )
139
+
140
+ def __rshift__(self, numeral):
141
+ """
142
+ Right-shifting of Unicode Numerals
143
+
144
+ return:
145
+ AbstractNumeral: returns the right shifted value
146
+ """
147
+ return UnicodeNumeral(
148
+ get_unicode_character_string(
149
+ self.language_name, self.to_decimal() >> numeral.to_decimal()
150
+ )
151
+ )
152
+
153
+ def __sub__(self, numeral):
154
+ """
155
+ Substraction of Unicode Numerals
156
+
157
+ return:
158
+ AbstractNumeral: returns the difference
159
+ """
160
+ return UnicodeNumeral(
161
+ get_unicode_character_string(
162
+ self.language_name, self.to_decimal() - numeral.to_decimal()
163
+ )
164
+ )
165
+
166
+ def __truediv__(self, numeral):
167
+ """
168
+ True division of Unicode Numerals
169
+
170
+ return:
171
+ AbstractNumeral: returns the value after true division
172
+ """
173
+ return UnicodeNumeral(
174
+ get_unicode_character_string(
175
+ self.language_name, self.to_decimal() / numeral.to_decimal()
176
+ )
177
+ )
178
+
179
+ def __floordiv__(self, numeral):
180
+ """
181
+ Floor division of Unicode Numerals
182
+
183
+ return:
184
+ AbstractNumeral: returns the value after floor division
185
+ """
186
+ return UnicodeNumeral(
187
+ get_unicode_character_string(
188
+ self.language_name, self.to_decimal() // numeral.to_decimal()
189
+ )
190
+ )
191
+
192
+ def __neg__(self):
193
+ """
194
+ Negation of Unicode Numerals
195
+
196
+ return:
197
+ AbstractNumeral: returns the negation
198
+ """
199
+ return UnicodeNumeral(
200
+ get_unicode_character_string(self.language_name, neg(self.to_decimal()))
201
+ )
202
+
203
+ def __pow__(self, numeral):
204
+ """
205
+ Power of Unicode Numerals
206
+
207
+ return:
208
+ AbstractNumeral: returns the power
209
+ """
210
+ return UnicodeNumeral(
211
+ get_unicode_character_string(
212
+ self.language_name, self.to_decimal() ** numeral.to_decimal()
213
+ )
214
+ )
215
+
216
+ def __mod__(self, numeral):
217
+ """
218
+ Modulus of Unicode Numerals
219
+
220
+ return:
221
+ AbstractNumeral: returns the modulus value
222
+ """
223
+ return UnicodeNumeral(
224
+ get_unicode_character_string(
225
+ self.language_name, self.to_decimal() % numeral.to_decimal()
226
+ )
227
+ )
228
+
229
+ def __xor__(self, numeral):
230
+ """
231
+ XOR value of Unicode Numerals
232
+
233
+ return:
234
+ AbstractNumeral: returns the XOR value
235
+ """
236
+ return UnicodeNumeral(
237
+ get_unicode_character_string(
238
+ self.language_name, self.to_decimal() ^ numeral.to_decimal()
239
+ )
240
+ )
241
+
242
+ def __invert__(self):
243
+ """
244
+ Bitwise inversion value of Unicode Numerals
245
+
246
+ return:
247
+ AbstractNumeral: returns the bitwise-inverted value
248
+ """
249
+ return UnicodeNumeral(
250
+ get_unicode_character_string(self.language_name, invert(self.to_decimal()))
251
+ )
252
+
253
+ def __or__(self, numeral):
254
+ """
255
+ OR value of Unicode Numerals
256
+
257
+ return:
258
+ AbstractNumeral: returns the OR value
259
+ """
260
+ return UnicodeNumeral(
261
+ get_unicode_character_string(
262
+ self.language_name, self.to_decimal() | numeral.to_decimal()
263
+ )
264
+ )
265
+
266
+ def __abs__(self):
267
+ """
268
+ Absolute value of Unicode Numerals
269
+
270
+ return:
271
+ UnicodeNumeral: returns the absolute value
272
+ """
273
+ return UnicodeNumeral(
274
+ get_unicode_character_string(
275
+ self.language_name, abs(self.to_decimal())
276
+ )
277
+ )
278
+
279
+ def convert_to(self, target_language):
280
+ """
281
+ Convert this numeral to a different Unicode script.
282
+
283
+ Parameters:
284
+ target_language (str): Target language name (e.g., "ARABIC-INDIC")
285
+
286
+ Returns:
287
+ UnicodeNumeral: A new numeral in the target script
288
+ """
289
+ converted = convert_numeral_string(
290
+ self.numstr, self.language_name, target_language
291
+ )
292
+ return UnicodeNumeral(converted)
@@ -0,0 +1,28 @@
1
+ #
2
+ # SPDX-FileCopyrightText: 2024 John Samuel <johnsamuelwrites@gmail.com>
3
+ #
4
+ # SPDX-License-Identifier: GPL-3.0-or-later
5
+ #
6
+
7
+ """Parser subpackage for the multilingual programming language."""
8
+
9
+ from multilingualprogramming.parser.ast_nodes import (
10
+ ASTNode, Program,
11
+ NumeralLiteral, StringLiteral, DateLiteral, BooleanLiteral,
12
+ NoneLiteral, ListLiteral, DictLiteral, SetLiteral, DictUnpackEntry,
13
+ Identifier, BinaryOp, UnaryOp, BooleanOp, CompareOp,
14
+ CallExpr, AttributeAccess, IndexAccess,
15
+ LambdaExpr, YieldExpr, AwaitExpr, NamedExpr, ConditionalExpr,
16
+ VariableDeclaration, Assignment, AnnAssignment, ExpressionStatement,
17
+ PassStatement, ReturnStatement, BreakStatement, ContinueStatement,
18
+ RaiseStatement, GlobalStatement, LocalStatement, YieldStatement,
19
+ IfStatement, WhileLoop, ForLoop, FunctionDef, ClassDef,
20
+ TryStatement, ExceptHandler, MatchStatement, CaseClause,
21
+ WithStatement, ImportStatement, FromImportStatement,
22
+ )
23
+ from multilingualprogramming.parser.parser import Parser
24
+ from multilingualprogramming.parser.ast_printer import ASTPrinter
25
+ from multilingualprogramming.parser.semantic_analyzer import (
26
+ Symbol, Scope, SymbolTable, SemanticAnalyzer,
27
+ )
28
+ from multilingualprogramming.parser.error_messages import ErrorMessageRegistry