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.
- multilingualprogramming/__init__.py +74 -0
- multilingualprogramming/__main__.py +194 -0
- multilingualprogramming/codegen/__init__.py +12 -0
- multilingualprogramming/codegen/executor.py +215 -0
- multilingualprogramming/codegen/python_generator.py +592 -0
- multilingualprogramming/codegen/repl.py +489 -0
- multilingualprogramming/codegen/runtime_builtins.py +308 -0
- multilingualprogramming/core/__init__.py +12 -0
- multilingualprogramming/core/ir.py +29 -0
- multilingualprogramming/core/lowering.py +24 -0
- multilingualprogramming/datetime/__init__.py +11 -0
- multilingualprogramming/datetime/date_parser.py +190 -0
- multilingualprogramming/datetime/mp_date.py +210 -0
- multilingualprogramming/datetime/mp_datetime.py +153 -0
- multilingualprogramming/datetime/mp_time.py +147 -0
- multilingualprogramming/datetime/resource_loader.py +18 -0
- multilingualprogramming/exceptions.py +158 -0
- multilingualprogramming/imports.py +150 -0
- multilingualprogramming/keyword/__init__.py +13 -0
- multilingualprogramming/keyword/keyword_registry.py +249 -0
- multilingualprogramming/keyword/keyword_validator.py +59 -0
- multilingualprogramming/keyword/language_pack_validator.py +110 -0
- multilingualprogramming/lexer/__init__.py +11 -0
- multilingualprogramming/lexer/lexer.py +570 -0
- multilingualprogramming/lexer/source_reader.py +91 -0
- multilingualprogramming/lexer/token.py +54 -0
- multilingualprogramming/lexer/token_types.py +38 -0
- multilingualprogramming/numeral/__init__.py +11 -0
- multilingualprogramming/numeral/abstract_numeral.py +232 -0
- multilingualprogramming/numeral/complex_numeral.py +190 -0
- multilingualprogramming/numeral/fraction_numeral.py +165 -0
- multilingualprogramming/numeral/mp_numeral.py +243 -0
- multilingualprogramming/numeral/numeral_converter.py +151 -0
- multilingualprogramming/numeral/roman_numeral.py +301 -0
- multilingualprogramming/numeral/unicode_numeral.py +292 -0
- multilingualprogramming/parser/__init__.py +28 -0
- multilingualprogramming/parser/ast_nodes.py +459 -0
- multilingualprogramming/parser/ast_printer.py +677 -0
- multilingualprogramming/parser/error_messages.py +75 -0
- multilingualprogramming/parser/parser.py +1796 -0
- multilingualprogramming/parser/semantic_analyzer.py +689 -0
- multilingualprogramming/parser/surface_normalizer.py +282 -0
- multilingualprogramming/resources/datetime/eras.json +23 -0
- multilingualprogramming/resources/datetime/formats.json +32 -0
- multilingualprogramming/resources/datetime/months.json +150 -0
- multilingualprogramming/resources/datetime/weekdays.json +90 -0
- multilingualprogramming/resources/parser/error_messages.json +310 -0
- multilingualprogramming/resources/repl/commands.json +636 -0
- multilingualprogramming/resources/usm/builtins_aliases.json +731 -0
- multilingualprogramming/resources/usm/keywords.json +1063 -0
- multilingualprogramming/resources/usm/operators.json +532 -0
- multilingualprogramming/resources/usm/schema.json +34 -0
- multilingualprogramming/resources/usm/surface_patterns.json +1523 -0
- multilingualprogramming/unicode_string.py +140 -0
- multilingualprogramming/version.py +9 -0
- multilingualprogramming-0.2.0.dist-info/METADATA +350 -0
- multilingualprogramming-0.2.0.dist-info/RECORD +61 -0
- multilingualprogramming-0.2.0.dist-info/WHEEL +5 -0
- multilingualprogramming-0.2.0.dist-info/entry_points.txt +3 -0
- multilingualprogramming-0.2.0.dist-info/licenses/LICENSE +674 -0
- 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
|