pyscript-programming-language 1.2.1__tar.gz → 1.2.2__tar.gz
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.
Potentially problematic release.
This version of pyscript-programming-language might be problematic. Click here for more details.
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/MANIFEST.in +1 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/PKG-INFO +2 -2
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/README.md +1 -1
- pyscript_programming_language-1.2.2/changelog.md +12 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/interpreter.py +1 -1
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/lexer.py +58 -45
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/objects.py +6 -3
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/parser.py +30 -36
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/pysbuiltins.py +30 -25
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/runner.py +23 -10
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/singletons.py +12 -3
- pyscript_programming_language-1.2.2/pyscript/core/token.py +25 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/utils.py +22 -12
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/validator.py +6 -5
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/version.py +2 -2
- pyscript_programming_language-1.2.2/pyscript/lib/brainfuck.pys +191 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript_programming_language.egg-info/PKG-INFO +2 -2
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript_programming_language.egg-info/SOURCES.txt +3 -5
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/setup.py +1 -1
- pyscript_programming_language-1.2.1/pyscript/core/token.py +0 -21
- pyscript_programming_language-1.2.1/pyscript/lib/_tantee/__init__.pys +0 -50
- pyscript_programming_language-1.2.1/pyscript/lib/_tantee/animate.pys +0 -9
- pyscript_programming_language-1.2.1/pyscript/lib/_tantee/lyrics.pys +0 -12
- pyscript_programming_language-1.2.1/pyscript/lib/_tantee/tantee.mp3 +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/PyScript.png +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/__init__.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/__init__.pyi +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/__main__.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/__init__.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/bases.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/buffer.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/cache.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/constants.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/context.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/exceptions.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/handlers.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/highlight.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/nodes.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/position.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/results.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/symtab.py +0 -0
- /pyscript_programming_language-1.2.1/pyscript/lib/hello.pys → /pyscript_programming_language-1.2.2/pyscript/lib/__hello__.pys +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/lib/clock.pys +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/lib/getch.pys +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/lib/parser.pys +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/lib/sys.pys +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/lib/this.pys +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/this.py +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript_programming_language.egg-info/top_level.txt +0 -0
- {pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyscript-programming-language
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: PyScript Programming Language
|
|
5
5
|
Home-page: https://github.com/azzammuhyala/pyscript
|
|
6
6
|
Author: azzammuhyala
|
|
@@ -32,7 +32,7 @@ Dynamic: summary
|
|
|
32
32
|
# PyScript Language📖
|
|
33
33
|
|
|
34
34
|
<p align="center">
|
|
35
|
-
<img src="PyScript.png" alt="PyScript Logo" width="200">
|
|
35
|
+
<img src="https://github.com/azzammuhyala/pyscript/blob/main/PyScript.png?raw=true" alt="PyScript Logo" width="200">
|
|
36
36
|
</p>
|
|
37
37
|
|
|
38
38
|
PyScript adalah bahasa pemprograman sederhana yang dibuat di atas bahasa Python. Bahasa ini mengabungkan beberapa sintaks dari Python dan JavaScript, jadi bagi Anda yang sudah familiar dengan sintaks Python atau JavaScript atau keduanya pasti seharusnya cukup mudah mempelajari bahasa ini.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# PyScript Language📖
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img src="PyScript.png" alt="PyScript Logo" width="200">
|
|
4
|
+
<img src="https://github.com/azzammuhyala/pyscript/blob/main/PyScript.png?raw=true" alt="PyScript Logo" width="200">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
PyScript adalah bahasa pemprograman sederhana yang dibuat di atas bahasa Python. Bahasa ini mengabungkan beberapa sintaks dari Python dan JavaScript, jadi bagi Anda yang sudah familiar dengan sintaks Python atau JavaScript atau keduanya pasti seharusnya cukup mudah mempelajari bahasa ini.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
## [1.2.2] - 07-10-2025
|
|
4
|
+
### Added
|
|
5
|
+
- _brainfuck_ default library.
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Lexer or tokenization improvements on parsing unicode strings and numbers.
|
|
9
|
+
- Minor improvements to the parser.
|
|
10
|
+
- Newline system fixes in shell (_REPL_).
|
|
11
|
+
- Improvements `pyscript.core.version.version_info`.
|
|
12
|
+
- Improvements _builtins_ `ce`, `nce`, `increment`, and `decrement`.
|
{pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/lexer.py
RENAMED
|
@@ -13,13 +13,10 @@ class PysLexer(Pys):
|
|
|
13
13
|
|
|
14
14
|
def __init__(self, file, context_parent=None, context_parent_entry_position=None, allowed_comment_token=False):
|
|
15
15
|
self.file = file
|
|
16
|
-
self.
|
|
16
|
+
self.context_parent = context_parent
|
|
17
17
|
self.context_parent_entry_position = context_parent_entry_position
|
|
18
18
|
self.allowed_comment_token = allowed_comment_token
|
|
19
19
|
|
|
20
|
-
def peak(self, index):
|
|
21
|
-
return self.file.text[index] if 0 <= index < len(self.file.text) else None
|
|
22
|
-
|
|
23
20
|
def update_current_char(self):
|
|
24
21
|
self.current_char = self.file.text[self.index] if 0 <= self.index < len(self.file.text) else None
|
|
25
22
|
|
|
@@ -53,29 +50,26 @@ class PysLexer(Pys):
|
|
|
53
50
|
PysContext(
|
|
54
51
|
name=None,
|
|
55
52
|
file=self.file,
|
|
56
|
-
parent=self.
|
|
53
|
+
parent=self.context_parent,
|
|
57
54
|
parent_entry_position=self.context_parent_entry_position
|
|
58
55
|
),
|
|
59
56
|
PysPosition(self.file, start, end or self.index)
|
|
60
57
|
)
|
|
61
58
|
|
|
62
|
-
def is_triple_quote(self, prefix):
|
|
63
|
-
return all(self.peak(self.index + i) == prefix for i in range(3))
|
|
64
|
-
|
|
65
59
|
def not_eof(self):
|
|
66
60
|
return self.current_char is not None
|
|
67
61
|
|
|
68
62
|
def char_eq(self, character):
|
|
69
|
-
return self.current_char == character
|
|
63
|
+
return self.not_eof() and self.current_char == character
|
|
70
64
|
|
|
71
65
|
def char_ne(self, character):
|
|
72
|
-
return self.current_char != character
|
|
66
|
+
return self.not_eof() and self.current_char != character
|
|
73
67
|
|
|
74
68
|
def char_in(self, characters):
|
|
75
69
|
return self.not_eof() and self.current_char in characters
|
|
76
70
|
|
|
77
|
-
def char_are(self,
|
|
78
|
-
return self.not_eof() and getattr(self.current_char,
|
|
71
|
+
def char_are(self, string_method, *args, **kwargs):
|
|
72
|
+
return self.not_eof() and getattr(self.current_char, string_method)(*args, **kwargs)
|
|
79
73
|
|
|
80
74
|
def make_tokens(self):
|
|
81
75
|
self.index = -1
|
|
@@ -214,8 +208,8 @@ class PysLexer(Pys):
|
|
|
214
208
|
|
|
215
209
|
def make_number(self):
|
|
216
210
|
start = self.index
|
|
217
|
-
number = ''
|
|
218
211
|
format = int
|
|
212
|
+
number = ''
|
|
219
213
|
|
|
220
214
|
is_scientific = False
|
|
221
215
|
is_complex = False
|
|
@@ -224,8 +218,19 @@ class PysLexer(Pys):
|
|
|
224
218
|
if self.char_eq('.'):
|
|
225
219
|
format = float
|
|
226
220
|
number = '.'
|
|
221
|
+
|
|
227
222
|
self.advance()
|
|
228
223
|
|
|
224
|
+
if self.file.text[self.index:self.index + 2] == '..':
|
|
225
|
+
self.advance()
|
|
226
|
+
self.advance()
|
|
227
|
+
self.add_token(TOKENS['ELLIPSIS'], start)
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
elif not self.char_in('0123456789'):
|
|
231
|
+
self.add_token(TOKENS['DOT'], start)
|
|
232
|
+
return
|
|
233
|
+
|
|
229
234
|
while self.char_in('0123456789'):
|
|
230
235
|
number += self.current_char
|
|
231
236
|
self.advance()
|
|
@@ -238,6 +243,7 @@ class PysLexer(Pys):
|
|
|
238
243
|
|
|
239
244
|
elif self.char_eq('.') and not is_scientific and format is int:
|
|
240
245
|
format = float
|
|
246
|
+
|
|
241
247
|
number += '.'
|
|
242
248
|
self.advance()
|
|
243
249
|
|
|
@@ -248,6 +254,7 @@ class PysLexer(Pys):
|
|
|
248
254
|
|
|
249
255
|
format = str
|
|
250
256
|
number = ''
|
|
257
|
+
|
|
251
258
|
character_base = self.char_are('lower')
|
|
252
259
|
|
|
253
260
|
if character_base == 'b':
|
|
@@ -303,12 +310,7 @@ class PysLexer(Pys):
|
|
|
303
310
|
if self.char_eq('.'):
|
|
304
311
|
self.advance()
|
|
305
312
|
|
|
306
|
-
if format is float
|
|
307
|
-
self.advance()
|
|
308
|
-
self.add_token(TOKENS['ELLIPSIS'], start)
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
if number != '.' and (format is float or is_complex or is_scientific):
|
|
313
|
+
if format is float or is_complex or is_scientific:
|
|
312
314
|
self.throw(self.index - 1, "invalid decimal literal")
|
|
313
315
|
|
|
314
316
|
format = float
|
|
@@ -320,10 +322,7 @@ class PysLexer(Pys):
|
|
|
320
322
|
return complex(0, result) if is_complex else result
|
|
321
323
|
|
|
322
324
|
if format is float:
|
|
323
|
-
|
|
324
|
-
self.add_token(TOKENS['DOT'], start)
|
|
325
|
-
else:
|
|
326
|
-
self.add_token(TOKENS['NUMBER'], start, wrap(float))
|
|
325
|
+
self.add_token(TOKENS['NUMBER'], start, wrap(float))
|
|
327
326
|
|
|
328
327
|
elif format is str:
|
|
329
328
|
self.add_token(TOKENS['NUMBER'], start, wrap(int, base))
|
|
@@ -353,17 +352,25 @@ class PysLexer(Pys):
|
|
|
353
352
|
|
|
354
353
|
prefix = self.current_char
|
|
355
354
|
|
|
356
|
-
|
|
355
|
+
def triple_quote():
|
|
356
|
+
return self.file.text[self.index:self.index + 3] == prefix * 3
|
|
357
|
+
|
|
358
|
+
is_triple_quote = triple_quote()
|
|
357
359
|
warning_displayed = False
|
|
358
360
|
decoded_error_message = None
|
|
359
361
|
|
|
362
|
+
def decode_error(message):
|
|
363
|
+
nonlocal decoded_error_message
|
|
364
|
+
if decoded_error_message is None:
|
|
365
|
+
decoded_error_message = message
|
|
366
|
+
|
|
360
367
|
self.advance()
|
|
361
368
|
|
|
362
369
|
if is_triple_quote:
|
|
363
370
|
self.advance()
|
|
364
371
|
self.advance()
|
|
365
372
|
|
|
366
|
-
while self.not_eof() and not (
|
|
373
|
+
while self.not_eof() and not (triple_quote() if is_triple_quote else self.char_in(prefix + '\n')):
|
|
367
374
|
|
|
368
375
|
if self.char_eq('\\'):
|
|
369
376
|
self.advance()
|
|
@@ -391,62 +398,68 @@ class PysLexer(Pys):
|
|
|
391
398
|
string += '\a'
|
|
392
399
|
elif self.char_eq('v'):
|
|
393
400
|
string += '\v'
|
|
401
|
+
|
|
394
402
|
self.advance()
|
|
395
403
|
|
|
396
404
|
elif decoded_error_message is None:
|
|
397
405
|
escape = ''
|
|
398
406
|
|
|
399
407
|
if self.char_in('01234567'):
|
|
400
|
-
|
|
408
|
+
|
|
409
|
+
while self.char_in('01234567') and len(escape) < 3:
|
|
401
410
|
escape += self.current_char
|
|
402
411
|
self.advance()
|
|
403
412
|
|
|
404
413
|
string += chr(int(escape, 8))
|
|
405
414
|
|
|
406
415
|
elif self.char_in('xuU'):
|
|
407
|
-
|
|
416
|
+
base = self.current_char
|
|
417
|
+
|
|
418
|
+
if base == 'x':
|
|
408
419
|
length = 2
|
|
409
|
-
elif
|
|
420
|
+
elif base == 'u':
|
|
410
421
|
length = 4
|
|
411
|
-
elif
|
|
422
|
+
elif base == 'U':
|
|
412
423
|
length = 8
|
|
413
424
|
|
|
414
|
-
base = self.current_char
|
|
415
|
-
|
|
416
425
|
self.advance()
|
|
417
426
|
|
|
418
|
-
while self.
|
|
427
|
+
while self.char_in('0123456789ABCDEFabcdef') and len(escape) < length:
|
|
419
428
|
escape += self.current_char
|
|
420
429
|
self.advance()
|
|
421
430
|
|
|
422
431
|
if len(escape) != length:
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
)
|
|
432
|
+
decode_error("codec can't decode bytes, truncated \\{}{} escape".format(base, 'X' * length))
|
|
433
|
+
|
|
426
434
|
else:
|
|
427
|
-
|
|
435
|
+
try:
|
|
436
|
+
string += chr(int(escape, 16))
|
|
437
|
+
except:
|
|
438
|
+
decode_error("codec can't decode bytes: illegal Unicode character")
|
|
428
439
|
|
|
429
440
|
elif self.char_eq('N'):
|
|
430
441
|
self.advance()
|
|
431
442
|
|
|
432
443
|
if self.current_char != '{':
|
|
433
|
-
|
|
444
|
+
decode_error("malformed \\N character escape")
|
|
434
445
|
continue
|
|
435
446
|
|
|
436
447
|
self.advance()
|
|
437
448
|
|
|
438
|
-
while self.
|
|
449
|
+
while self.char_ne('}'):
|
|
439
450
|
escape += self.current_char
|
|
440
451
|
self.advance()
|
|
441
452
|
|
|
442
453
|
if self.current_char == '}':
|
|
443
454
|
try:
|
|
444
455
|
string += unicode_lookup(escape)
|
|
445
|
-
except
|
|
446
|
-
|
|
456
|
+
except:
|
|
457
|
+
decode_error("codec can't decode bytes, unknown Unicode character name")
|
|
458
|
+
|
|
447
459
|
self.advance()
|
|
460
|
+
|
|
448
461
|
else:
|
|
449
|
-
|
|
462
|
+
decode_error("malformed \\N character escape")
|
|
450
463
|
|
|
451
464
|
else:
|
|
452
465
|
if not self.not_eof():
|
|
@@ -467,10 +480,10 @@ class PysLexer(Pys):
|
|
|
467
480
|
string += self.current_char
|
|
468
481
|
self.advance()
|
|
469
482
|
|
|
470
|
-
if not (
|
|
483
|
+
if not (triple_quote() if is_triple_quote else self.char_eq(prefix)):
|
|
471
484
|
self.throw(start, "unterminated bytes literal" if is_bytes else "unterminated string literal", start + 1)
|
|
472
485
|
|
|
473
|
-
elif decoded_error_message:
|
|
486
|
+
elif decoded_error_message is not None:
|
|
474
487
|
self.advance()
|
|
475
488
|
self.throw(start, decoded_error_message)
|
|
476
489
|
|
|
@@ -507,7 +520,7 @@ class PysLexer(Pys):
|
|
|
507
520
|
|
|
508
521
|
self.advance()
|
|
509
522
|
|
|
510
|
-
while self.
|
|
523
|
+
while self.char_ne('\n') and self.char_are('isspace'):
|
|
511
524
|
self.advance()
|
|
512
525
|
|
|
513
526
|
if not self.char_are('isidentifier'):
|
|
@@ -744,7 +757,7 @@ class PysLexer(Pys):
|
|
|
744
757
|
|
|
745
758
|
self.advance()
|
|
746
759
|
|
|
747
|
-
while self.
|
|
760
|
+
while self.char_ne('\n'):
|
|
748
761
|
comment += self.current_char
|
|
749
762
|
self.advance()
|
|
750
763
|
|
{pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/objects.py
RENAMED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
from .bases import Pys
|
|
2
2
|
from .buffer import PysCode
|
|
3
3
|
|
|
4
|
-
class
|
|
4
|
+
class PysObject(Pys):
|
|
5
|
+
pass
|
|
6
|
+
|
|
7
|
+
class PysModule(PysObject):
|
|
5
8
|
|
|
6
9
|
def __init__(self, name, doc=None):
|
|
7
10
|
self.__name__ = name
|
|
@@ -17,7 +20,7 @@ class PysModule(Pys):
|
|
|
17
20
|
'' if file is undefined else ' from {!r}'.format(file)
|
|
18
21
|
)
|
|
19
22
|
|
|
20
|
-
class PysChainFunction(
|
|
23
|
+
class PysChainFunction(PysObject):
|
|
21
24
|
|
|
22
25
|
def __init__(self, func):
|
|
23
26
|
from .constants import DEFAULT
|
|
@@ -35,7 +38,7 @@ class PysChainFunction(Pys):
|
|
|
35
38
|
handle_call(self.__func__, self.__code__.context, self.__code__.position, self.__code__.flags)
|
|
36
39
|
return self.__func__(self, *args, **kwargs)
|
|
37
40
|
|
|
38
|
-
class PysFunction(
|
|
41
|
+
class PysFunction(PysObject):
|
|
39
42
|
|
|
40
43
|
def __init__(self, name, parameters, body, position, context):
|
|
41
44
|
from .constants import DEFAULT
|
{pyscript_programming_language-1.2.1 → pyscript_programming_language-1.2.2}/pyscript/core/parser.py
RENAMED
|
@@ -22,6 +22,10 @@ class PysParser(Pys):
|
|
|
22
22
|
|
|
23
23
|
self.advance()
|
|
24
24
|
|
|
25
|
+
def update_current_token(self):
|
|
26
|
+
if 0 <= self.token_index < len(self.tokens):
|
|
27
|
+
self.current_token = self.tokens[self.token_index]
|
|
28
|
+
|
|
25
29
|
def advance(self):
|
|
26
30
|
self.token_index += 1
|
|
27
31
|
self.update_current_token()
|
|
@@ -30,10 +34,6 @@ class PysParser(Pys):
|
|
|
30
34
|
self.token_index -= amount
|
|
31
35
|
self.update_current_token()
|
|
32
36
|
|
|
33
|
-
def update_current_token(self):
|
|
34
|
-
if 0 <= self.token_index < len(self.tokens):
|
|
35
|
-
self.current_token = self.tokens[self.token_index]
|
|
36
|
-
|
|
37
37
|
def error(self, message, position=None):
|
|
38
38
|
return PysException(
|
|
39
39
|
SyntaxError(message),
|
|
@@ -89,11 +89,7 @@ class PysParser(Pys):
|
|
|
89
89
|
PysSequenceNode(
|
|
90
90
|
'statements',
|
|
91
91
|
statements,
|
|
92
|
-
PysPosition(
|
|
93
|
-
self.file,
|
|
94
|
-
start,
|
|
95
|
-
self.current_token.position.end
|
|
96
|
-
)
|
|
92
|
+
PysPosition(self.file, start, self.current_token.position.end)
|
|
97
93
|
)
|
|
98
94
|
)
|
|
99
95
|
|
|
@@ -435,7 +431,7 @@ class PysParser(Pys):
|
|
|
435
431
|
self.advance()
|
|
436
432
|
self.skip(result)
|
|
437
433
|
|
|
438
|
-
|
|
434
|
+
seen_kwargs = False
|
|
439
435
|
args = []
|
|
440
436
|
|
|
441
437
|
while self.current_token.type not in parenthesises_map.values():
|
|
@@ -454,12 +450,12 @@ class PysParser(Pys):
|
|
|
454
450
|
self.advance()
|
|
455
451
|
self.skip(result)
|
|
456
452
|
|
|
457
|
-
|
|
453
|
+
seen_kwargs = True
|
|
458
454
|
|
|
459
|
-
elif
|
|
455
|
+
elif seen_kwargs:
|
|
460
456
|
return result.failure(self.error("expected '=' (follows keyword argument)"))
|
|
461
457
|
|
|
462
|
-
if
|
|
458
|
+
if seen_kwargs:
|
|
463
459
|
value = result.register(self.expr(), True)
|
|
464
460
|
if result.error:
|
|
465
461
|
return result
|
|
@@ -697,11 +693,10 @@ class PysParser(Pys):
|
|
|
697
693
|
|
|
698
694
|
return result.failure(self.error("expected expression", token.position), fatal=False)
|
|
699
695
|
|
|
700
|
-
def sequence_expr(self, type):
|
|
696
|
+
def sequence_expr(self, type, should_sequence=False):
|
|
701
697
|
result = PysParserResult()
|
|
702
698
|
start = self.current_token.position.start
|
|
703
699
|
|
|
704
|
-
should_sequence = True
|
|
705
700
|
elements = []
|
|
706
701
|
|
|
707
702
|
left_parenthesis = parenthesises_sequence_map[type]
|
|
@@ -755,9 +750,9 @@ class PysParser(Pys):
|
|
|
755
750
|
return result.failure(self.error("invalid syntax. Perhaps you forgot a comma?"))
|
|
756
751
|
|
|
757
752
|
else:
|
|
758
|
-
should_sequence = False
|
|
759
753
|
|
|
760
754
|
while self.current_token.type not in parenthesises_map.values():
|
|
755
|
+
|
|
761
756
|
elements.append(result.register(self.expr(), True))
|
|
762
757
|
if result.error:
|
|
763
758
|
return result
|
|
@@ -1009,12 +1004,11 @@ class PysParser(Pys):
|
|
|
1009
1004
|
|
|
1010
1005
|
return result.success(all_cases)
|
|
1011
1006
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
return result
|
|
1007
|
+
else_body = result.register(self.else_expr())
|
|
1008
|
+
if result.error:
|
|
1009
|
+
return result
|
|
1016
1010
|
|
|
1017
|
-
|
|
1011
|
+
return result.success(([], else_body))
|
|
1018
1012
|
|
|
1019
1013
|
def if_expr_cases(self, case_keyword):
|
|
1020
1014
|
result = PysParserResult()
|
|
@@ -1148,8 +1142,8 @@ class PysParser(Pys):
|
|
|
1148
1142
|
return result
|
|
1149
1143
|
|
|
1150
1144
|
return result.success(body)
|
|
1151
|
-
|
|
1152
|
-
|
|
1145
|
+
|
|
1146
|
+
return result.success(None)
|
|
1153
1147
|
|
|
1154
1148
|
def case_or_default_expr(self):
|
|
1155
1149
|
result = PysParserResult()
|
|
@@ -1161,12 +1155,11 @@ class PysParser(Pys):
|
|
|
1161
1155
|
|
|
1162
1156
|
return result.success(all_cases)
|
|
1163
1157
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
return result
|
|
1158
|
+
default_body = result.register(self.default_expr())
|
|
1159
|
+
if result.error:
|
|
1160
|
+
return result
|
|
1168
1161
|
|
|
1169
|
-
|
|
1162
|
+
return result.success(([], default_body))
|
|
1170
1163
|
|
|
1171
1164
|
def try_expr(self):
|
|
1172
1165
|
result = PysParserResult()
|
|
@@ -1316,7 +1309,7 @@ class PysParser(Pys):
|
|
|
1316
1309
|
self.advance()
|
|
1317
1310
|
self.skip(result)
|
|
1318
1311
|
|
|
1319
|
-
|
|
1312
|
+
iter = result.register(self.expr(), True)
|
|
1320
1313
|
if result.error:
|
|
1321
1314
|
return result
|
|
1322
1315
|
|
|
@@ -1354,7 +1347,7 @@ class PysParser(Pys):
|
|
|
1354
1347
|
|
|
1355
1348
|
return result.success(
|
|
1356
1349
|
PysForNode(
|
|
1357
|
-
(init,
|
|
1350
|
+
(init, iter) if foreach else (init, condition, update),
|
|
1358
1351
|
body,
|
|
1359
1352
|
else_body,
|
|
1360
1353
|
position
|
|
@@ -1466,11 +1459,12 @@ class PysParser(Pys):
|
|
|
1466
1459
|
self.skip(result)
|
|
1467
1460
|
|
|
1468
1461
|
if self.current_token.type == TOKENS['LPAREN']:
|
|
1469
|
-
bases = result.register(self.sequence_expr('tuple'))
|
|
1462
|
+
bases = result.register(self.sequence_expr('tuple', should_sequence=True))
|
|
1470
1463
|
if result.error:
|
|
1471
1464
|
return result
|
|
1472
1465
|
|
|
1473
|
-
|
|
1466
|
+
end = bases.position.end
|
|
1467
|
+
bases = bases.elements
|
|
1474
1468
|
|
|
1475
1469
|
else:
|
|
1476
1470
|
bases = []
|
|
@@ -1525,7 +1519,7 @@ class PysParser(Pys):
|
|
|
1525
1519
|
self.advance()
|
|
1526
1520
|
self.skip(result)
|
|
1527
1521
|
|
|
1528
|
-
|
|
1522
|
+
seen_kwargs = False
|
|
1529
1523
|
parameters = []
|
|
1530
1524
|
|
|
1531
1525
|
while self.current_token.type not in parenthesises_map.values():
|
|
@@ -1544,12 +1538,12 @@ class PysParser(Pys):
|
|
|
1544
1538
|
self.advance()
|
|
1545
1539
|
self.skip(result)
|
|
1546
1540
|
|
|
1547
|
-
|
|
1541
|
+
seen_kwargs = True
|
|
1548
1542
|
|
|
1549
|
-
elif
|
|
1543
|
+
elif seen_kwargs:
|
|
1550
1544
|
return result.failure(self.error("expected '=' (follows keyword argument)"))
|
|
1551
1545
|
|
|
1552
|
-
if
|
|
1546
|
+
if seen_kwargs:
|
|
1553
1547
|
value = result.register(self.expr(), True)
|
|
1554
1548
|
if result.error:
|
|
1555
1549
|
return result
|
|
@@ -193,14 +193,13 @@ def ce(a, b, *, rel_tol=1e-9, abs_tol=0):
|
|
|
193
193
|
from math import isclose
|
|
194
194
|
return isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
func = getattr(b, '__ce__', None)
|
|
196
|
+
from .utils import supported_method
|
|
197
|
+
|
|
198
|
+
success, result = supported_method(a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
199
|
+
if not success:
|
|
200
|
+
success, result = supported_method(b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
202
201
|
|
|
203
|
-
if not
|
|
202
|
+
if not success:
|
|
204
203
|
raise TypeError(
|
|
205
204
|
"unsupported operand type(s) for ~= or ce(): {!r} and {!r}".format(
|
|
206
205
|
type(a).__name__,
|
|
@@ -208,24 +207,26 @@ def ce(a, b, *, rel_tol=1e-9, abs_tol=0):
|
|
|
208
207
|
)
|
|
209
208
|
)
|
|
210
209
|
|
|
211
|
-
return
|
|
210
|
+
return result
|
|
212
211
|
|
|
213
212
|
def nce(a, b, *, rel_tol=1e-9, abs_tol=0):
|
|
214
213
|
if isinstance(a, (int, float)) and isinstance(b, (int, float)):
|
|
215
214
|
from math import isclose
|
|
216
215
|
return not isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
217
216
|
|
|
218
|
-
|
|
219
|
-
from_a = True
|
|
220
|
-
func = getattr(a, '__nce__')
|
|
221
|
-
except AttributeError:
|
|
222
|
-
try:
|
|
223
|
-
from_a = False
|
|
224
|
-
func = getattr(b, '__nce__')
|
|
225
|
-
except AttributeError:
|
|
226
|
-
return not ce(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
217
|
+
from .utils import supported_method
|
|
227
218
|
|
|
228
|
-
|
|
219
|
+
success, result = supported_method(a, '__nce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
220
|
+
if not success:
|
|
221
|
+
success, result = supported_method(b, '__nce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
222
|
+
if not success:
|
|
223
|
+
success, result = supported_method(a, '__ce__', b, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
224
|
+
if not success:
|
|
225
|
+
success, result = supported_method(b, '__ce__', a, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
226
|
+
|
|
227
|
+
result = not result
|
|
228
|
+
|
|
229
|
+
if not success:
|
|
229
230
|
raise TypeError(
|
|
230
231
|
"unsupported operand type(s) for ~! or nce(): {!r} and {!r}".format(
|
|
231
232
|
type(a).__name__,
|
|
@@ -233,29 +234,33 @@ def nce(a, b, *, rel_tol=1e-9, abs_tol=0):
|
|
|
233
234
|
)
|
|
234
235
|
)
|
|
235
236
|
|
|
236
|
-
return
|
|
237
|
+
return result
|
|
237
238
|
|
|
238
239
|
def increment(object):
|
|
239
240
|
if isinstance(object, (int, float)):
|
|
240
241
|
return object + 1
|
|
241
242
|
|
|
242
|
-
|
|
243
|
+
from .utils import supported_method
|
|
243
244
|
|
|
244
|
-
|
|
245
|
+
success, result = supported_method(object, '__increment__')
|
|
246
|
+
|
|
247
|
+
if not success:
|
|
245
248
|
raise TypeError("unsupported operand type(s) for ++ or increment(): {!r}".format(type(object).__name__))
|
|
246
249
|
|
|
247
|
-
return
|
|
250
|
+
return result
|
|
248
251
|
|
|
249
252
|
def decrement(object):
|
|
250
253
|
if isinstance(object, (int, float)):
|
|
251
254
|
return object - 1
|
|
252
255
|
|
|
253
|
-
|
|
256
|
+
from .utils import supported_method
|
|
257
|
+
|
|
258
|
+
success, result = supported_method(object, '__decrement__')
|
|
254
259
|
|
|
255
|
-
if not
|
|
260
|
+
if not success:
|
|
256
261
|
raise TypeError("unsupported operand type(s) for -- or decrement(): {!r}".format(type(object).__name__))
|
|
257
262
|
|
|
258
|
-
return
|
|
263
|
+
return result
|
|
259
264
|
|
|
260
265
|
def comprehension(init, wrap, condition=None):
|
|
261
266
|
if not callable(wrap):
|