tojscript 1.0.10__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.
tojscript/__init__.py ADDED
@@ -0,0 +1,305 @@
1
+ from colorama import Fore, Style, init
2
+ init()
3
+ import re
4
+ import sys
5
+ import os
6
+
7
+ # 🎨 Цвета
8
+ colors = {
9
+ "сабз": Fore.GREEN,
10
+ "сурх": Fore.RED,
11
+ "зард": Fore.YELLOW,
12
+ "кабуд": Fore.BLUE,
13
+ "норинҷӣ": Fore.LIGHTYELLOW_EX,
14
+ "reset": Style.RESET_ALL
15
+ }
16
+
17
+ def toj_print(*args):
18
+ text = ""
19
+ color = ""
20
+ for arg in args:
21
+ if isinstance(arg, str):
22
+ clean = arg.strip("/")
23
+ if clean in colors:
24
+ color = colors[clean]
25
+ continue
26
+ text += str(arg) + " "
27
+ if color:
28
+ print(color + text.strip() + colors["reset"])
29
+ else:
30
+ print(text.strip())
31
+
32
+ def brb(a, b): return a == b
33
+ def nbr(a, b): return a != b
34
+
35
+ def fakt(n):
36
+ n = int(n)
37
+ if n < 0: print("Хато: адад бояд мусбат бошад"); exit()
38
+ result = 1
39
+ for i in range(1, n + 1): result *= i
40
+ return result
41
+
42
+ def fibonachi(n):
43
+ n = int(n)
44
+ if n <= 0: print("Хато: адад бояд > 0 бошад"); exit()
45
+ a, b = 0, 1
46
+ for _ in range(n - 1): a, b = b, a + b
47
+ return b
48
+
49
+ def musb(x): return abs(int(x))
50
+
51
+ def darozi(x):
52
+ try: return len(x)
53
+ except: print("Хато: дарозӣ танҳо барои сатр ё рӯйхат аст"); exit()
54
+
55
+ def ilova(arr, x): arr.append(x); return arr
56
+ def pok(arr, i): return arr[i]
57
+ def калон(s): return str(s).upper()
58
+ def хурд(s): return str(s).lower()
59
+ def min_tj(*args): return min(*args)
60
+ def max_tj(*args): return max(*args)
61
+
62
+ def toq(*args):
63
+ """Ададҳои тоқ — нечётные числа из аргументов"""
64
+ result = [x for x in args if isinstance(x, (int, float)) and int(x) % 2 != 0]
65
+ if not result: return []
66
+ return result if len(result) != 1 else result[0]
67
+
68
+ def juft(*args):
69
+ """Ададҳои ҷуфт — чётные числа из аргументов"""
70
+ result = [x for x in args if isinstance(x, (int, float)) and int(x) % 2 == 0]
71
+ if not result: return []
72
+ return result if len(result) != 1 else result[0]
73
+
74
+ _input_buffer = []
75
+ def toj_input(prompt=""):
76
+ global _input_buffer
77
+ while not _input_buffer:
78
+ line = input(prompt)
79
+ parts = line.split()
80
+ if len(parts) > 1:
81
+ _input_buffer = parts
82
+ else:
83
+ return line.strip()
84
+ return _input_buffer.pop(0)
85
+
86
+ TOJ_GLOBALS = {
87
+ "toj_print": toj_print, "brb": brb, "nbr": nbr,
88
+ "fakt": fakt, "fibonachi": fibonachi, "musb": musb,
89
+ "darozi": darozi, "ilova": ilova, "pok": pok,
90
+ "калон": калон, "хурд": хурд,
91
+ "min_tj": min_tj, "max_tj": max_tj,
92
+ "тоқ": toq, "ҷуфт": juft,
93
+ "toj_input": toj_input, "input": toj_input, "print": print
94
+ }
95
+
96
+ def toj_to_python(code):
97
+ code = re.sub(r'^\s*import\s+tojscript\s*$', '', code, flags=re.MULTILINE)
98
+
99
+ translations = {
100
+ "агар": "if", "дигар": "else", "чоп": "toj_print",
101
+ "ворид": "toj_input", "барои": "for", "дар": "in",
102
+ "функсия": "def", "баргардон": "return",
103
+ "бутун": "int", "сатр": "str",
104
+ "брб": "brb", "нбр": "nbr", "факт": "fakt",
105
+ "фибоначи": "fibonachi", "мусб": "musb",
106
+ "дарозӣ": "darozi", "мин": "min_tj", "макс": "max_tj",
107
+ "тоқ": "тоқ", "ҷуфт": "ҷуфт",
108
+ "дар_ҳолати": "while",
109
+ }
110
+
111
+ lines = code.split("\n")
112
+ new_lines = []
113
+ indent = 0
114
+
115
+ for line in lines:
116
+ stripped = line.strip()
117
+
118
+ # метод-вызовы
119
+ stripped = re.sub(r'(\w+)\.дарозӣ', r'darozi(\1)', stripped)
120
+ stripped = re.sub(r'(\w+)\.калон\(\)', r'калон(\1)', stripped)
121
+ stripped = re.sub(r'(\w+)\.хурд\(\)', r'хурд(\1)', stripped)
122
+
123
+ # операторы присваивания *= += -= /= (уже поддерживаются Python — просто пропускаем без изменений)
124
+
125
+ if not stripped:
126
+ continue
127
+
128
+ # закрывающие скобки
129
+ while stripped.startswith("}"):
130
+ indent = max(indent - 1, 0)
131
+ stripped = stripped[1:].strip()
132
+
133
+ if not stripped:
134
+ continue
135
+
136
+ # оғоз() — точка входа
137
+ if stripped.startswith("оғоз()"):
138
+ new_lines.append(" " * indent + "if True:")
139
+ indent += 1
140
+ continue
141
+
142
+ # просто открывающая скобка
143
+ if stripped == "{":
144
+ indent += 1
145
+ continue
146
+
147
+ # функсия ном(аргументҳо){ → def ном(аргументҳо):
148
+ func_match = re.match(r'^функсия\s+(\w+)\s*\(([^)]*)\)\s*\{?$', stripped)
149
+ if func_match:
150
+ name, args = func_match.group(1), func_match.group(2)
151
+ new_lines.append(" " * indent + f"def {name}({args}):")
152
+ indent += 1
153
+ continue
154
+
155
+ # барои м (1..10){ → for м in range(1, 11):
156
+ for_range = re.match(r'^барои\s+(\S+)\s*\((\d+)\.\.(\d+)\)\s*\{?$', stripped)
157
+ if for_range:
158
+ var, start, end = for_range.group(1), int(for_range.group(2)), int(for_range.group(3))
159
+ new_lines.append(" " * indent + f"for {var} in range({start}, {end + 1}):")
160
+ indent += 1
161
+ continue
162
+
163
+ # дар_ҳолати(условие){ → while условие:
164
+ while_match = re.match(r'^дар_ҳолати\s*\((.+)\)\s*\{?$', stripped)
165
+ if while_match:
166
+ cond = while_match.group(1)
167
+ new_lines.append(" " * indent + f"while {cond}:")
168
+ indent += 1
169
+ continue
170
+
171
+ # перевод остальных ключевых слов
172
+ for toj, py in translations.items():
173
+ if toj in ("тоқ", "ҷуфт", "дар_ҳолати"):
174
+ continue # уже обработаны выше
175
+ stripped = re.sub(rf'\b{toj}\b', py, stripped)
176
+
177
+ # { в конце строки → двоеточие + увеличить отступ
178
+ if "{" in stripped:
179
+ stripped = stripped.replace("{", "").rstrip() + ":"
180
+ new_lines.append(" " * indent + stripped)
181
+ indent += 1
182
+ else:
183
+ new_lines.append(" " * indent + stripped)
184
+
185
+ return "\n".join(new_lines)
186
+
187
+ def fix_file(filename):
188
+ """Исправляет кодировку файла — конвертирует в UTF-8"""
189
+ if not os.path.isabs(filename):
190
+ filename = os.path.join(os.getcwd(), filename)
191
+ if not os.path.exists(filename):
192
+ print(f"Хато: файл '{filename}' не найден")
193
+ sys.exit(1)
194
+
195
+ with open(filename, "rb") as f:
196
+ raw = f.read()
197
+
198
+ # Пробуем все возможные кодировки
199
+ decoded = None
200
+ for enc in ["utf-8-sig", "utf-8", "cp1251", "cp1252", "iso-8859-1", "windows-1252"]:
201
+ try:
202
+ decoded = raw.decode(enc)
203
+ break
204
+ except Exception:
205
+ continue
206
+
207
+ if decoded is None:
208
+ # Последняя попытка — игнорируем ошибки
209
+ decoded = raw.decode("utf-8", errors="replace")
210
+
211
+ # Сохраняем как UTF-8
212
+ with open(filename, "w", encoding="utf-8") as f:
213
+ f.write(decoded)
214
+ print(f"✓ Файл '{os.path.basename(filename)}' конвертирован в UTF-8")
215
+
216
+ def run(filename):
217
+ """Запуск .toj или .py файла"""
218
+ # Если путь не абсолютный — ищем относительно текущей папки
219
+ if not os.path.isabs(filename):
220
+ filename = os.path.join(os.getcwd(), filename)
221
+
222
+ if not os.path.exists(filename):
223
+ print(f"Хато: файл '{filename}' не найден")
224
+ sys.exit(1)
225
+
226
+ # Автоопределение кодировки через chardet
227
+ with open(filename, "rb") as f:
228
+ raw = f.read()
229
+ try:
230
+ import chardet
231
+ detected = chardet.detect(raw)
232
+ enc = detected.get("encoding") or "utf-8"
233
+ except ImportError:
234
+ enc = "utf-8"
235
+ try:
236
+ code = raw.decode(enc)
237
+ except Exception:
238
+ try:
239
+ code = raw.decode("utf-8", errors="replace")
240
+ except Exception:
241
+ print("Хато: не удалось прочитать файл")
242
+ sys.exit(1)
243
+
244
+ # Всегда запускаем как TojScript (работает с .py и .toj)
245
+ python_code = toj_to_python(code)
246
+ try:
247
+ exec(python_code, {**TOJ_GLOBALS})
248
+ except Exception as e:
249
+ print("Хато:", e)
250
+
251
+ import base64 as _b64, tempfile as _tmp, subprocess as _sp
252
+
253
+ _VSIX_DATA = "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"
254
+
255
+ def install_extension():
256
+ try:
257
+ vsix_bytes = _b64.b64decode(_VSIX_DATA)
258
+ tmp = _tmp.NamedTemporaryFile(suffix=".vsix", delete=False)
259
+ tmp.write(vsix_bytes)
260
+ tmp.close()
261
+ result = _sp.run(["code", "--install-extension", tmp.name], capture_output=True, text=True)
262
+ os.unlink(tmp.name)
263
+ if result.returncode == 0:
264
+ print("TojScript подсветка установлена!")
265
+ else:
266
+ print("VS Code не найден. Установи вручную: toj --get-extension")
267
+ except Exception as e:
268
+ print("Хато:", e)
269
+
270
+ def get_extension():
271
+ try:
272
+ vsix_bytes = _b64.b64decode(_VSIX_DATA)
273
+ path = os.path.join(os.getcwd(), "tojlang.vsix")
274
+ with open(path, "wb") as f:
275
+ f.write(vsix_bytes)
276
+ print("Файл сохранён:", path)
277
+ print("Установи: code --install-extension tojlang.vsix")
278
+ except Exception as e:
279
+ print("Хато:", e)
280
+
281
+ def main():
282
+ if len(sys.argv) > 1:
283
+ if sys.argv[1] == "--version":
284
+ print("TojScript 1.0.9")
285
+ return
286
+ if sys.argv[1] == "--fix" and len(sys.argv) > 2:
287
+ fix_file(sys.argv[2])
288
+ return
289
+ if sys.argv[1] == "--install-extension":
290
+ install_extension()
291
+ return
292
+ if sys.argv[1] == "--get-extension":
293
+ get_extension()
294
+ return
295
+ run(sys.argv[1])
296
+ else:
297
+ # ищем main.toj в текущей папке
298
+ default = os.path.join(os.getcwd(), "main.toj")
299
+ if os.path.exists(default):
300
+ run(default)
301
+ else:
302
+ print("Хато: укажи файл. Пример: toj main.toj")
303
+
304
+ if __name__ == "__main__":
305
+ main()
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: tojscript
3
+ Version: 1.0.10
4
+ Requires-Dist: colorama
5
+ Requires-Dist: chardet
6
+ Dynamic: requires-dist
@@ -0,0 +1,6 @@
1
+ tojscript/__init__.py,sha256=ReIj5HcPORE6YeAFNZDQOtcou3y46ba_cy0qkXIDVtc,13244
2
+ tojscript-1.0.10.dist-info/METADATA,sha256=Iu0_WvqRLOtb2b12fxPgsfN1phdBzs1jMM2rIWeODL0,130
3
+ tojscript-1.0.10.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
4
+ tojscript-1.0.10.dist-info/entry_points.txt,sha256=k0R0RwMtxCeCKkWZIAW_wp2g0Sxjcd5of3oop9eUARo,39
5
+ tojscript-1.0.10.dist-info/top_level.txt,sha256=YlrnYNtofFbaITrwU_hRW07Llaz3MLD9AOeJn9MFNIo,10
6
+ tojscript-1.0.10.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ toj = tojscript:main
@@ -0,0 +1 @@
1
+ tojscript