bare-script 4.1.1__tar.gz → 4.1.3__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.
- {bare_script-4.1.1/src/bare_script.egg-info → bare_script-4.1.3}/PKG-INFO +1 -1
- {bare_script-4.1.1 → bare_script-4.1.3}/setup.cfg +1 -1
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/__init__.py +2 -2
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/bare.py +2 -2
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/library.py +2 -2
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/parser.py +179 -156
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/runtime.py +36 -32
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/runtime_c.c +50 -34
- {bare_script-4.1.1 → bare_script-4.1.3/src/bare_script.egg-info}/PKG-INFO +1 -1
- {bare_script-4.1.1 → bare_script-4.1.3}/LICENSE +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/README.md +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/pyproject.toml +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/setup.py +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/__main__.py +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/__init__.py +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/args.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/baredoc.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/baredocCLI.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/data.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/dataLineChart.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/dataTable.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/dataUtil.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/diff.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/draw.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/elementModel.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/forms.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/markdown.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/markdownElements.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/markdownHighlight.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/markdownParser.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/markdownUp.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/pager.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/qrcode.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/schemaDoc.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/unittest.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/include/unittestMock.bare +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/model.py +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/options.py +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script/value.py +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script.egg-info/SOURCES.txt +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script.egg-info/dependency_links.txt +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script.egg-info/entry_points.txt +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script.egg-info/requires.txt +0 -0
- {bare_script-4.1.1 → bare_script-4.1.3}/src/bare_script.egg-info/top_level.txt +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
bare-script package
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import os
|
|
8
|
+
import os
|
|
9
9
|
|
|
10
10
|
from .model import \
|
|
11
11
|
lint_script, \
|
|
@@ -29,7 +29,7 @@ from .parser import \
|
|
|
29
29
|
from .runtime import \
|
|
30
30
|
BareScriptRuntimeError
|
|
31
31
|
|
|
32
|
-
if not
|
|
32
|
+
if not os.environ.get('BARESCRIPT_RUNTIME_PY'): # pragma: no cover
|
|
33
33
|
try:
|
|
34
34
|
from .runtime_c import evaluate_expression, execute_script
|
|
35
35
|
except ImportError:
|
|
@@ -7,7 +7,7 @@ bare-script command-line interface (CLI)
|
|
|
7
7
|
|
|
8
8
|
import argparse
|
|
9
9
|
from functools import partial
|
|
10
|
-
import os
|
|
10
|
+
import os
|
|
11
11
|
import sys
|
|
12
12
|
import time
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@ from .options import FETCH_SYSTEM_PREFIX, fetch_read_write, fetch_system, log_st
|
|
|
16
16
|
from .parser import parse_expression, parse_script
|
|
17
17
|
from .runtime import SYSTEM_GLOBAL_INCLUDES_NAME
|
|
18
18
|
from .value import value_boolean
|
|
19
|
-
if not
|
|
19
|
+
if not os.environ.get('BARESCRIPT_RUNTIME_PY'): # pragma: no cover
|
|
20
20
|
try:
|
|
21
21
|
from .runtime_c import evaluate_expression, execute_script
|
|
22
22
|
except ImportError:
|
|
@@ -11,7 +11,7 @@ import functools
|
|
|
11
11
|
import importlib
|
|
12
12
|
import json
|
|
13
13
|
import math
|
|
14
|
-
import os
|
|
14
|
+
import os
|
|
15
15
|
import random
|
|
16
16
|
import re
|
|
17
17
|
import urllib
|
|
@@ -28,7 +28,7 @@ from .value import R_NUMBER_CLEANUP, ValueArgsError, value_args_model, value_arg
|
|
|
28
28
|
# Helper to dynamically import evaluate_expression to avoid the circular dependency
|
|
29
29
|
def _import_evaluate_expression():
|
|
30
30
|
if not _EVALUATE_EXPRESSION:
|
|
31
|
-
if not
|
|
31
|
+
if not os.environ.get('BARESCRIPT_RUNTIME_PY'): # pragma: no cover
|
|
32
32
|
try:
|
|
33
33
|
_EVALUATE_EXPRESSION.append(importlib.import_module('bare_script.runtime_c').evaluate_expression)
|
|
34
34
|
except (ImportError, AttributeError):
|
|
@@ -44,8 +44,9 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
44
44
|
for ix_line_part, line_part in enumerate(lines):
|
|
45
45
|
statements = function_def['function']['statements'] if function_def is not None else script['statements']
|
|
46
46
|
|
|
47
|
-
# Comment?
|
|
48
|
-
|
|
47
|
+
# Comment or empty line?
|
|
48
|
+
line_part_trimmed = line_part.lstrip()
|
|
49
|
+
if not line_part_trimmed or line_part_trimmed[0] == '#':
|
|
49
50
|
continue
|
|
50
51
|
|
|
51
52
|
# Set the line index
|
|
@@ -74,29 +75,12 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
74
75
|
if ix_line != ix_line_part:
|
|
75
76
|
statement_base['lineCount'] = (ix_line_part - ix_line) + 1
|
|
76
77
|
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
if
|
|
80
|
-
# Parse the expression
|
|
81
|
-
try:
|
|
82
|
-
assignment_expr = parse_expression(match_assignment.group('expr'), line_number, script_name, True)
|
|
83
|
-
except BareScriptParserError as error:
|
|
84
|
-
column_number = len(line) - len(match_assignment.group('expr')) + error.column_number
|
|
85
|
-
raise BareScriptParserError(error.error, line, column_number, start_line_number + ix_line, script_name)
|
|
86
|
-
|
|
87
|
-
# Add the expression statement
|
|
88
|
-
expr_statement = {
|
|
89
|
-
'expr': {
|
|
90
|
-
'name': match_assignment.group('name'),
|
|
91
|
-
'expr': assignment_expr,
|
|
92
|
-
**statement_base
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
statements.append(expr_statement)
|
|
96
|
-
continue
|
|
78
|
+
# Determine the line's leading keyword for dispatch
|
|
79
|
+
match_keyword = _R_SCRIPT_KEYWORD.match(line)
|
|
80
|
+
keyword = match_keyword.group(1) if match_keyword else None
|
|
97
81
|
|
|
98
82
|
# Function definition begin?
|
|
99
|
-
match_function_begin = _R_SCRIPT_FUNCTION_BEGIN.match(line)
|
|
83
|
+
match_function_begin = _R_SCRIPT_FUNCTION_BEGIN.match(line) if keyword in ('function', 'async') else None
|
|
100
84
|
if match_function_begin:
|
|
101
85
|
# Nested function definitions are not allowed
|
|
102
86
|
if function_def is not None:
|
|
@@ -121,7 +105,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
121
105
|
continue
|
|
122
106
|
|
|
123
107
|
# Function definition end?
|
|
124
|
-
match_function_end = _R_SCRIPT_FUNCTION_END.match(line)
|
|
108
|
+
match_function_end = _R_SCRIPT_FUNCTION_END.match(line) if keyword == 'endfunction' else None
|
|
125
109
|
if match_function_end:
|
|
126
110
|
if function_def is None:
|
|
127
111
|
raise BareScriptParserError('No matching function definition', line, 1, start_line_number + ix_line, script_name)
|
|
@@ -138,7 +122,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
138
122
|
continue
|
|
139
123
|
|
|
140
124
|
# If-then begin?
|
|
141
|
-
match_if_begin = _R_SCRIPT_IF_BEGIN.match(line)
|
|
125
|
+
match_if_begin = _R_SCRIPT_IF_BEGIN.match(line) if keyword == 'if' else None
|
|
142
126
|
if match_if_begin:
|
|
143
127
|
# Parse the if-then expression
|
|
144
128
|
try:
|
|
@@ -167,7 +151,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
167
151
|
continue
|
|
168
152
|
|
|
169
153
|
# Else-if-then?
|
|
170
|
-
match_if_else_if = _R_SCRIPT_IF_ELSE_IF.match(line)
|
|
154
|
+
match_if_else_if = _R_SCRIPT_IF_ELSE_IF.match(line) if keyword == 'elif' else None
|
|
171
155
|
if match_if_else_if:
|
|
172
156
|
# Get the else-if-then definition
|
|
173
157
|
label_def_depth = function_label_def_depth if function_def is not None else 0
|
|
@@ -177,7 +161,9 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
177
161
|
|
|
178
162
|
# Cannot come after the else-then statement
|
|
179
163
|
if ifthen['hasElse']:
|
|
180
|
-
raise BareScriptParserError(
|
|
164
|
+
raise BareScriptParserError(
|
|
165
|
+
'Elif statement following else statement', line, 1, start_line_number + ix_line, script_name
|
|
166
|
+
)
|
|
181
167
|
|
|
182
168
|
# Parse teh else-if-then expression
|
|
183
169
|
try:
|
|
@@ -204,7 +190,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
204
190
|
continue
|
|
205
191
|
|
|
206
192
|
# Else-then?
|
|
207
|
-
match_if_else = _R_SCRIPT_IF_ELSE.match(line)
|
|
193
|
+
match_if_else = _R_SCRIPT_IF_ELSE.match(line) if keyword == 'else' else None
|
|
208
194
|
if match_if_else:
|
|
209
195
|
# Get the if-then definition
|
|
210
196
|
label_def_depth = function_label_def_depth if function_def is not None else 0
|
|
@@ -225,7 +211,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
225
211
|
continue
|
|
226
212
|
|
|
227
213
|
# If-then end?
|
|
228
|
-
match_if_end = _R_SCRIPT_IF_END.match(line)
|
|
214
|
+
match_if_end = _R_SCRIPT_IF_END.match(line) if keyword == 'endif' else None
|
|
229
215
|
if match_if_end:
|
|
230
216
|
# Pop the if-then definition
|
|
231
217
|
label_def_depth = function_label_def_depth if function_def is not None else 0
|
|
@@ -242,7 +228,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
242
228
|
continue
|
|
243
229
|
|
|
244
230
|
# While-do begin?
|
|
245
|
-
match_while_begin = _R_SCRIPT_WHILE_BEGIN.match(line)
|
|
231
|
+
match_while_begin = _R_SCRIPT_WHILE_BEGIN.match(line) if keyword == 'while' else None
|
|
246
232
|
if match_while_begin:
|
|
247
233
|
# Parse the while-do expression
|
|
248
234
|
try:
|
|
@@ -271,7 +257,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
271
257
|
continue
|
|
272
258
|
|
|
273
259
|
# While-do end?
|
|
274
|
-
match_while_end = _R_SCRIPT_WHILE_END.match(line)
|
|
260
|
+
match_while_end = _R_SCRIPT_WHILE_END.match(line) if keyword == 'endwhile' else None
|
|
275
261
|
if match_while_end:
|
|
276
262
|
# Pop the while-do definition
|
|
277
263
|
label_def_depth = function_label_def_depth if function_def is not None else 0
|
|
@@ -290,7 +276,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
290
276
|
continue
|
|
291
277
|
|
|
292
278
|
# For-each begin?
|
|
293
|
-
match_for_begin = _R_SCRIPT_FOR_BEGIN.match(line)
|
|
279
|
+
match_for_begin = _R_SCRIPT_FOR_BEGIN.match(line) if keyword == 'for' else None
|
|
294
280
|
if match_for_begin:
|
|
295
281
|
# Add the for-each label
|
|
296
282
|
foreach = {
|
|
@@ -335,14 +321,19 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
335
321
|
{'label': {'name': foreach['loop'], **statement_base}},
|
|
336
322
|
{'expr': {
|
|
337
323
|
'name': foreach['value'],
|
|
338
|
-
'expr': {
|
|
324
|
+
'expr': {
|
|
325
|
+
'function': {
|
|
326
|
+
'name': 'arrayGet',
|
|
327
|
+
'args': [{'variable': foreach['values']}, {'variable': foreach['index']}]
|
|
328
|
+
}
|
|
329
|
+
},
|
|
339
330
|
**statement_base
|
|
340
331
|
}}
|
|
341
332
|
])
|
|
342
333
|
continue
|
|
343
334
|
|
|
344
335
|
# For-each end?
|
|
345
|
-
match_for_end = _R_SCRIPT_FOR_END.match(line)
|
|
336
|
+
match_for_end = _R_SCRIPT_FOR_END.match(line) if keyword == 'endfor' else None
|
|
346
337
|
if match_for_end:
|
|
347
338
|
# Pop the foreach definition
|
|
348
339
|
label_def_depth = function_label_def_depth if function_def is not None else 0
|
|
@@ -364,7 +355,9 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
364
355
|
}},
|
|
365
356
|
{'jump': {
|
|
366
357
|
'label': foreach['loop'],
|
|
367
|
-
'expr': {
|
|
358
|
+
'expr': {
|
|
359
|
+
'binary': {'op': '<', 'left': {'variable': foreach['index']}, 'right': {'variable': foreach['length']}}
|
|
360
|
+
},
|
|
368
361
|
**statement_base
|
|
369
362
|
}},
|
|
370
363
|
{'label': {'name': foreach['done'], **statement_base}}
|
|
@@ -372,7 +365,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
372
365
|
continue
|
|
373
366
|
|
|
374
367
|
# Break statement?
|
|
375
|
-
match_break = _R_SCRIPT_BREAK.match(line)
|
|
368
|
+
match_break = _R_SCRIPT_BREAK.match(line) if keyword == 'break' else None
|
|
376
369
|
if match_break:
|
|
377
370
|
# Get the loop definition
|
|
378
371
|
label_def_depth = function_label_def_depth if function_def is not None else 0
|
|
@@ -388,13 +381,15 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
388
381
|
continue
|
|
389
382
|
|
|
390
383
|
# Continue statement?
|
|
391
|
-
match_continue = _R_SCRIPT_CONTINUE.match(line)
|
|
384
|
+
match_continue = _R_SCRIPT_CONTINUE.match(line) if keyword == 'continue' else None
|
|
392
385
|
if match_continue:
|
|
393
386
|
# Get the loop definition
|
|
394
387
|
label_def_depth = function_label_def_depth if function_def is not None else 0
|
|
395
388
|
ix_label_def = next((i for i, d in reversed(list(enumerate(label_defs))) if 'if' not in d), -1)
|
|
396
389
|
if ix_label_def < label_def_depth:
|
|
397
|
-
raise BareScriptParserError(
|
|
390
|
+
raise BareScriptParserError(
|
|
391
|
+
'Continue statement outside of loop', line, 1, start_line_number + ix_line, script_name
|
|
392
|
+
)
|
|
398
393
|
label_def = label_defs[ix_label_def]
|
|
399
394
|
label_key = next(iter(label_def))
|
|
400
395
|
loop_def = label_def[label_key]
|
|
@@ -404,14 +399,8 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
404
399
|
statements.append({'jump': {'label': loop_def['continue'], **statement_base}})
|
|
405
400
|
continue
|
|
406
401
|
|
|
407
|
-
# Label definition?
|
|
408
|
-
match_label = _R_SCRIPT_LABEL.match(line)
|
|
409
|
-
if match_label:
|
|
410
|
-
statements.append({'label': {'name': match_label.group('name'), **statement_base}})
|
|
411
|
-
continue
|
|
412
|
-
|
|
413
402
|
# Jump definition?
|
|
414
|
-
match_jump = _R_SCRIPT_JUMP.match(line)
|
|
403
|
+
match_jump = _R_SCRIPT_JUMP.match(line) if keyword in ('jump', 'jumpif') else None
|
|
415
404
|
if match_jump:
|
|
416
405
|
jump_statement = {'jump': {'label': match_jump.group('name'), **statement_base}}
|
|
417
406
|
if match_jump.group('expr'):
|
|
@@ -424,12 +413,14 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
424
413
|
continue
|
|
425
414
|
|
|
426
415
|
# Return definition?
|
|
427
|
-
match_return = _R_SCRIPT_RETURN.match(line)
|
|
416
|
+
match_return = _R_SCRIPT_RETURN.match(line) if keyword == 'return' else None
|
|
428
417
|
if match_return:
|
|
429
418
|
return_statement = {'return': {**statement_base}}
|
|
430
419
|
if match_return.group('expr'):
|
|
431
420
|
try:
|
|
432
|
-
return_statement['return']['expr'] = parse_expression(
|
|
421
|
+
return_statement['return']['expr'] = parse_expression(
|
|
422
|
+
match_return.group('expr'), line_number, script_name, True
|
|
423
|
+
)
|
|
433
424
|
except BareScriptParserError as error:
|
|
434
425
|
column_number = len(match_return.group('return')) - len(match_return.group('expr')) + error.column_number
|
|
435
426
|
raise BareScriptParserError(error.error, line, column_number, start_line_number + ix_line, script_name)
|
|
@@ -437,7 +428,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
437
428
|
continue
|
|
438
429
|
|
|
439
430
|
# Include definition?
|
|
440
|
-
match_include = _R_SCRIPT_INCLUDE.match(line) or _R_SCRIPT_INCLUDE_SYSTEM.match(line)
|
|
431
|
+
match_include = _R_SCRIPT_INCLUDE.match(line) or _R_SCRIPT_INCLUDE_SYSTEM.match(line) if keyword == 'include' else None
|
|
441
432
|
if match_include:
|
|
442
433
|
delim = match_include.group('delim')
|
|
443
434
|
url = match_include.group('url') if delim == '<' else \
|
|
@@ -451,6 +442,35 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
451
442
|
include_statement['include']['includes'].append({'url': url, 'system': True} if delim == '<' else {'url': url})
|
|
452
443
|
continue
|
|
453
444
|
|
|
445
|
+
# Catch-all (line starts with an identifier but isn't a recognized control statement)
|
|
446
|
+
if keyword is not None:
|
|
447
|
+
# Assignment?
|
|
448
|
+
match_assignment = _R_SCRIPT_ASSIGNMENT.match(line)
|
|
449
|
+
if match_assignment:
|
|
450
|
+
# Parse the expression
|
|
451
|
+
try:
|
|
452
|
+
assignment_expr = parse_expression(match_assignment.group('expr'), line_number, script_name, True)
|
|
453
|
+
except BareScriptParserError as error:
|
|
454
|
+
column_number = len(line) - len(match_assignment.group('expr')) + error.column_number
|
|
455
|
+
raise BareScriptParserError(error.error, line, column_number, start_line_number + ix_line, script_name)
|
|
456
|
+
|
|
457
|
+
# Add the expression statement
|
|
458
|
+
expr_statement = {
|
|
459
|
+
'expr': {
|
|
460
|
+
'name': match_assignment.group('name'),
|
|
461
|
+
'expr': assignment_expr,
|
|
462
|
+
**statement_base
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
statements.append(expr_statement)
|
|
466
|
+
continue
|
|
467
|
+
|
|
468
|
+
# Label definition?
|
|
469
|
+
match_label = _R_SCRIPT_LABEL.match(line)
|
|
470
|
+
if match_label:
|
|
471
|
+
statements.append({'label': {'name': match_label.group('name'), **statement_base}})
|
|
472
|
+
continue
|
|
473
|
+
|
|
454
474
|
# Expression
|
|
455
475
|
try:
|
|
456
476
|
expr_statement = {'expr': {'expr': parse_expression(line, line_number, script_name, True), **statement_base}}
|
|
@@ -471,7 +491,7 @@ def parse_script(script_text, start_line_number=1, script_name=None):
|
|
|
471
491
|
# BareScript regex
|
|
472
492
|
_R_SCRIPT_LINE_SPLIT = re.compile(r'\r?\n')
|
|
473
493
|
_R_SCRIPT_CONTINUATION = re.compile(r'\\\s*$')
|
|
474
|
-
|
|
494
|
+
_R_SCRIPT_KEYWORD = re.compile(r'^\s*([A-Za-z_]\w*)')
|
|
475
495
|
_R_SCRIPT_ASSIGNMENT = re.compile(r'^\s*(?P<name>[A-Za-z_]\w*)\s*=\s*(?P<expr>.+)$')
|
|
476
496
|
_R_PART_COMMENT = r'\s*(#.*)?$'
|
|
477
497
|
_R_SCRIPT_FUNCTION_BEGIN = re.compile(
|
|
@@ -516,7 +536,7 @@ def parse_expression(expr_text, line_number=None, script_name=None, array_litera
|
|
|
516
536
|
:raises BareScriptParserError: A parsing error occurred
|
|
517
537
|
"""
|
|
518
538
|
try:
|
|
519
|
-
expr, next_text = _parse_binary_expression(expr_text,
|
|
539
|
+
expr, next_text = _parse_binary_expression(expr_text, array_literals)
|
|
520
540
|
if next_text.strip() != '':
|
|
521
541
|
raise BareScriptParserError('Syntax error', next_text, 1, line_number, script_name)
|
|
522
542
|
return expr
|
|
@@ -526,42 +546,47 @@ def parse_expression(expr_text, line_number=None, script_name=None, array_litera
|
|
|
526
546
|
|
|
527
547
|
|
|
528
548
|
# Helper function to parse a binary operator expression chain
|
|
529
|
-
def _parse_binary_expression(expr_text,
|
|
530
|
-
# Parse the binary operator's left unary expression
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
549
|
+
def _parse_binary_expression(expr_text, array_literals):
|
|
550
|
+
# Parse the binary operator's left unary expression
|
|
551
|
+
left_expr, bin_text = _parse_unary_expression(expr_text, array_literals)
|
|
552
|
+
|
|
553
|
+
# Consume binary operators while present, building up the binary expression tree
|
|
554
|
+
while True:
|
|
555
|
+
# Skip leading whitespace to find the first dispatch char
|
|
556
|
+
pos = 0
|
|
557
|
+
n = len(bin_text)
|
|
558
|
+
while pos < n and bin_text[pos] in ' \t\r\n\v\f':
|
|
559
|
+
pos += 1
|
|
560
|
+
|
|
561
|
+
# End of binary expression (empty, whitespace-only, or end-of-line comment)?
|
|
562
|
+
if pos >= n or bin_text[pos] == '#':
|
|
563
|
+
return [left_expr, '']
|
|
564
|
+
|
|
565
|
+
# Binary operator? First char must be one of "!%&*+-/<=>^|"
|
|
566
|
+
is_binary_op_start = bin_text[pos] in '!%&*+-/<=>^|'
|
|
567
|
+
match_binary_op = _R_EXPR_BINARY_OP.match(bin_text) if is_binary_op_start else None
|
|
568
|
+
if match_binary_op is None:
|
|
569
|
+
return [left_expr, bin_text]
|
|
570
|
+
bin_op = match_binary_op.group(1)
|
|
571
|
+
right_text = bin_text[len(match_binary_op.group(0)):]
|
|
572
|
+
|
|
573
|
+
# Parse the right sub-expression
|
|
574
|
+
right_expr, next_text = _parse_unary_expression(right_text, array_literals)
|
|
575
|
+
|
|
576
|
+
# Create the binary expression - re-order for binary operators as necessary
|
|
577
|
+
if 'binary' in left_expr and bin_op in BINARY_REORDER and left_expr['binary']['op'] in BINARY_REORDER[bin_op]:
|
|
578
|
+
# Left expression has lower precedence - find where to put this expression within the left expression
|
|
579
|
+
reorder_expr = left_expr
|
|
580
|
+
while ('binary' in reorder_expr['binary']['right']
|
|
581
|
+
and reorder_expr['binary']['right']['binary']['op'] in BINARY_REORDER[bin_op]):
|
|
582
|
+
reorder_expr = reorder_expr['binary']['right']
|
|
583
|
+
reorder_expr['binary']['right'] = {
|
|
584
|
+
'binary': {'op': bin_op, 'left': reorder_expr['binary']['right'], 'right': right_expr}
|
|
585
|
+
}
|
|
586
|
+
else:
|
|
587
|
+
left_expr = {'binary': {'op': bin_op, 'left': left_expr, 'right': right_expr}}
|
|
562
588
|
|
|
563
|
-
|
|
564
|
-
return _parse_binary_expression(next_text, bin_expr, array_literals)
|
|
589
|
+
bin_text = next_text
|
|
565
590
|
|
|
566
591
|
|
|
567
592
|
# Binary operator re-order map
|
|
@@ -590,48 +615,54 @@ BINARY_REORDER = {
|
|
|
590
615
|
|
|
591
616
|
# Helper function to parse a unary expression
|
|
592
617
|
def _parse_unary_expression(expr_text, array_literals):
|
|
593
|
-
#
|
|
594
|
-
|
|
618
|
+
# Skip leading whitespace to find the first dispatch char
|
|
619
|
+
pos = 0
|
|
620
|
+
n = len(expr_text)
|
|
621
|
+
while pos < n and expr_text[pos] in ' \t\r\n\v\f':
|
|
622
|
+
pos += 1
|
|
623
|
+
if pos >= n:
|
|
624
|
+
raise BareScriptParserError('Syntax error', expr_text, 1, None, None)
|
|
625
|
+
c = expr_text[pos]
|
|
626
|
+
|
|
627
|
+
# Group? '('
|
|
628
|
+
match_group_open = _R_EXPR_GROUP_OPEN.match(expr_text) if c == '(' else None
|
|
595
629
|
if match_group_open:
|
|
596
630
|
group_text = expr_text[len(match_group_open.group(0)):]
|
|
597
|
-
expr, next_text = _parse_binary_expression(group_text,
|
|
631
|
+
expr, next_text = _parse_binary_expression(group_text, array_literals)
|
|
598
632
|
match_group_close = _R_EXPR_GROUP_CLOSE.match(next_text)
|
|
599
633
|
if match_group_close is None:
|
|
600
634
|
raise BareScriptParserError('Unmatched parenthesis', expr_text, 1, None, None)
|
|
601
635
|
return [{'group': expr}, next_text[len(match_group_close.group(0)):]]
|
|
602
636
|
|
|
603
|
-
# Number?
|
|
604
|
-
match_number = _R_EXPR_NUMBER.match(expr_text)
|
|
637
|
+
# Number? digit, '+', or '-' (the '-' falls through to unary below if no number matches)
|
|
638
|
+
match_number = _R_EXPR_NUMBER.match(expr_text) if c.isdigit() or c in '+-' else None
|
|
605
639
|
if match_number:
|
|
606
640
|
number_str = match_number.group(1)
|
|
607
641
|
number = float(int(number_str, base=16)) if number_str.startswith('0x') else float(number_str)
|
|
608
|
-
|
|
609
|
-
return [expr, expr_text[len(match_number.group(0)):]]
|
|
642
|
+
return [{'number': number}, expr_text[len(match_number.group(0)):]]
|
|
610
643
|
|
|
611
|
-
# String?
|
|
612
|
-
match_string = _R_EXPR_STRING.match(expr_text)
|
|
644
|
+
# String? '\''
|
|
645
|
+
match_string = _R_EXPR_STRING.match(expr_text) if c == "'" else None
|
|
613
646
|
if match_string:
|
|
614
647
|
string = _R_EXPR_STRING_ESCAPES.sub(_replace_string_escape, match_string.group(1))
|
|
615
|
-
|
|
616
|
-
return [expr, expr_text[len(match_string.group(0)):]]
|
|
648
|
+
return [{'string': string}, expr_text[len(match_string.group(0)):]]
|
|
617
649
|
|
|
618
|
-
# String (double quotes)?
|
|
619
|
-
match_string_double = _R_EXPR_STRING_DOUBLE.match(expr_text)
|
|
650
|
+
# String (double quotes)? '"'
|
|
651
|
+
match_string_double = _R_EXPR_STRING_DOUBLE.match(expr_text) if c == '"' else None
|
|
620
652
|
if match_string_double:
|
|
621
653
|
string = _R_EXPR_STRING_ESCAPES.sub(_replace_string_escape, match_string_double.group(1))
|
|
622
|
-
|
|
623
|
-
return [expr, expr_text[len(match_string_double.group(0)):]]
|
|
654
|
+
return [{'string': string}, expr_text[len(match_string_double.group(0)):]]
|
|
624
655
|
|
|
625
|
-
# Unary operator?
|
|
626
|
-
match_unary = _R_EXPR_UNARY_OP.match(expr_text)
|
|
656
|
+
# Unary operator? '!', '-', '~'
|
|
657
|
+
match_unary = _R_EXPR_UNARY_OP.match(expr_text) if c in '!-~' else None
|
|
627
658
|
if match_unary:
|
|
628
659
|
unary_text = expr_text[len(match_unary.group(0)):]
|
|
629
660
|
expr, next_text = _parse_unary_expression(unary_text, array_literals)
|
|
630
|
-
|
|
631
|
-
return [unary_expr, next_text]
|
|
661
|
+
return [{'unary': {'op': match_unary.group(1), 'expr': expr}}, next_text]
|
|
632
662
|
|
|
633
|
-
# Function?
|
|
634
|
-
|
|
663
|
+
# Function call? identifier followed by '('
|
|
664
|
+
is_ident = c.isalpha() or c == '_'
|
|
665
|
+
match_function_open = _R_EXPR_FUNCTION_OPEN.match(expr_text) if is_ident else None
|
|
635
666
|
if match_function_open:
|
|
636
667
|
arg_text = expr_text[len(match_function_open.group(0)):]
|
|
637
668
|
args = []
|
|
@@ -650,15 +681,19 @@ def _parse_unary_expression(expr_text, array_literals):
|
|
|
650
681
|
arg_text = arg_text[len(match_function_separator.group(0)):]
|
|
651
682
|
|
|
652
683
|
# Get the argument
|
|
653
|
-
arg_expr, next_arg_text = _parse_binary_expression(arg_text,
|
|
684
|
+
arg_expr, next_arg_text = _parse_binary_expression(arg_text, array_literals)
|
|
654
685
|
args.append(arg_expr)
|
|
655
686
|
arg_text = next_arg_text
|
|
656
687
|
|
|
657
|
-
|
|
658
|
-
return [fn_expr, arg_text]
|
|
688
|
+
return [{'function': {'name': match_function_open.group(1), 'args': args}}, arg_text]
|
|
659
689
|
|
|
660
|
-
#
|
|
661
|
-
|
|
690
|
+
# Variable
|
|
691
|
+
match_variable = _R_EXPR_VARIABLE.match(expr_text) if is_ident else None
|
|
692
|
+
if match_variable:
|
|
693
|
+
return [{'variable': match_variable.group(1)}, expr_text[len(match_variable.group(0)):]]
|
|
694
|
+
|
|
695
|
+
# Object creation? '{'
|
|
696
|
+
match_object_open = _R_EXPR_OBJECT_OPEN.match(expr_text) if c == '{' else None
|
|
662
697
|
if match_object_open:
|
|
663
698
|
arg_text = expr_text[len(match_object_open.group(0)):]
|
|
664
699
|
args = []
|
|
@@ -677,7 +712,7 @@ def _parse_unary_expression(expr_text, array_literals):
|
|
|
677
712
|
arg_text = arg_text[len(match_object_separator.group(0)):]
|
|
678
713
|
|
|
679
714
|
# Get the key
|
|
680
|
-
arg_key, arg_text = _parse_binary_expression(arg_text,
|
|
715
|
+
arg_key, arg_text = _parse_binary_expression(arg_text, array_literals)
|
|
681
716
|
args.append(arg_key)
|
|
682
717
|
|
|
683
718
|
# Key/value separator
|
|
@@ -687,58 +722,46 @@ def _parse_unary_expression(expr_text, array_literals):
|
|
|
687
722
|
arg_text = arg_text[len(match_object_separator_key.group(0)):]
|
|
688
723
|
|
|
689
724
|
# Get the value
|
|
690
|
-
arg_value, arg_text = _parse_binary_expression(arg_text,
|
|
725
|
+
arg_value, arg_text = _parse_binary_expression(arg_text, array_literals)
|
|
691
726
|
args.append(arg_value)
|
|
692
727
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
if
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
fn_expr = {'function': {'name': 'arrayNew', 'args': args}}
|
|
721
|
-
return [fn_expr, arg_text]
|
|
722
|
-
|
|
723
|
-
# Variable?
|
|
724
|
-
match_variable = _R_EXPR_VARIABLE.match(expr_text)
|
|
725
|
-
if match_variable:
|
|
726
|
-
expr = {'variable': match_variable.group(1)}
|
|
727
|
-
return [expr, expr_text[len(match_variable.group(0)):]]
|
|
728
|
+
return [{'function': {'name': 'objectNew', 'args': args}}, arg_text]
|
|
729
|
+
|
|
730
|
+
# Array creation? '['
|
|
731
|
+
match_array_open = _R_EXPR_ARRAY_OPEN.match(expr_text) if c == '[' and array_literals else None
|
|
732
|
+
if match_array_open:
|
|
733
|
+
arg_text = expr_text[len(match_array_open.group(0)):]
|
|
734
|
+
args = []
|
|
735
|
+
while True:
|
|
736
|
+
# Array close?
|
|
737
|
+
match_array_close = _R_EXPR_ARRAY_CLOSE.match(arg_text)
|
|
738
|
+
if match_array_close:
|
|
739
|
+
arg_text = arg_text[len(match_array_close.group(0)):]
|
|
740
|
+
break
|
|
741
|
+
|
|
742
|
+
# Array key separator
|
|
743
|
+
if args:
|
|
744
|
+
match_array_separator = _R_EXPR_ARRAY_SEPARATOR.match(arg_text)
|
|
745
|
+
if match_array_separator is None:
|
|
746
|
+
raise BareScriptParserError('Syntax error', arg_text, 1, None, None)
|
|
747
|
+
arg_text = arg_text[len(match_array_separator.group(0)):]
|
|
748
|
+
|
|
749
|
+
# Get the value
|
|
750
|
+
arg_value, arg_text = _parse_binary_expression(arg_text, array_literals)
|
|
751
|
+
args.append(arg_value)
|
|
752
|
+
|
|
753
|
+
return [{'function': {'name': 'arrayNew', 'args': args}}, arg_text]
|
|
728
754
|
|
|
729
|
-
# Variable (brackets)?
|
|
730
|
-
if not array_literals
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
expr = {'variable': variable_name}
|
|
735
|
-
return [expr, expr_text[len(match_variable_ex.group(0)):]]
|
|
755
|
+
# Variable (brackets)? '['
|
|
756
|
+
match_variable_ex = _R_EXPR_VARIABLE_EX.match(expr_text) if c == '[' and not array_literals else None
|
|
757
|
+
if match_variable_ex:
|
|
758
|
+
variable_name = _R_EXPR_VARIABLE_EX_ESCAPE.sub('\\1', match_variable_ex.group(1))
|
|
759
|
+
return [{'variable': variable_name}, expr_text[len(match_variable_ex.group(0)):]]
|
|
736
760
|
|
|
737
761
|
raise BareScriptParserError('Syntax error', expr_text, 1, None, None)
|
|
738
762
|
|
|
739
763
|
|
|
740
764
|
# BareScript expression regex
|
|
741
|
-
_R_EXPR_COMMENT = re.compile(r'^\s*#.*$')
|
|
742
765
|
_R_EXPR_BINARY_OP = re.compile(r'^\s*(\*\*|\*|\/|%|\+|-|<<|>>|<=|<|>=|>|==|!=|&&|\|\||&|\^|\|)')
|
|
743
766
|
_R_EXPR_UNARY_OP = re.compile(r'^\s*(!|-|~)')
|
|
744
767
|
_R_EXPR_FUNCTION_OPEN = re.compile(r'^\s*([A-Za-z_]\w+)\s*\(')
|
|
@@ -224,13 +224,17 @@ def _script_function(script, function, args, options):
|
|
|
224
224
|
if func_args is not None:
|
|
225
225
|
args_length = len(args)
|
|
226
226
|
func_args_length = len(func_args)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
227
|
+
if function.get('lastArgArray'):
|
|
228
|
+
ix_arg_last = func_args_length - 1
|
|
229
|
+
for ix_arg in range(func_args_length):
|
|
230
|
+
arg_name = func_args[ix_arg]
|
|
231
|
+
if ix_arg < args_length:
|
|
232
|
+
func_locals[arg_name] = args[ix_arg] if ix_arg != ix_arg_last else args[ix_arg:]
|
|
233
|
+
else:
|
|
234
|
+
func_locals[arg_name] = [] if ix_arg == ix_arg_last else None
|
|
235
|
+
else:
|
|
236
|
+
for ix_arg in range(func_args_length):
|
|
237
|
+
func_locals[func_args[ix_arg]] = args[ix_arg] if ix_arg < args_length else None
|
|
234
238
|
return _execute_script_helper(script, function['statements'], options, func_locals)
|
|
235
239
|
|
|
236
240
|
|
|
@@ -399,35 +403,35 @@ def evaluate_expression(expr, options=None, locals_=None, builtins=True, script=
|
|
|
399
403
|
(right_type is int or right_type is float)):
|
|
400
404
|
return left_value / right_value
|
|
401
405
|
|
|
402
|
-
elif bin_op == '
|
|
403
|
-
if (left_type is int or left_type is float) and (right_type is int or right_type is float):
|
|
404
|
-
return left_value == right_value
|
|
405
|
-
return value_compare(left_value, right_value) == 0
|
|
406
|
-
|
|
407
|
-
elif bin_op == '!=':
|
|
406
|
+
elif bin_op == '<':
|
|
408
407
|
if (left_type is int or left_type is float) and (right_type is int or right_type is float):
|
|
409
|
-
return left_value
|
|
410
|
-
return value_compare(left_value, right_value)
|
|
408
|
+
return left_value < right_value
|
|
409
|
+
return value_compare(left_value, right_value) < 0
|
|
411
410
|
|
|
412
411
|
elif bin_op == '<=':
|
|
413
412
|
if (left_type is int or left_type is float) and (right_type is int or right_type is float):
|
|
414
413
|
return left_value <= right_value
|
|
415
414
|
return value_compare(left_value, right_value) <= 0
|
|
416
415
|
|
|
417
|
-
elif bin_op == '
|
|
416
|
+
elif bin_op == '>':
|
|
418
417
|
if (left_type is int or left_type is float) and (right_type is int or right_type is float):
|
|
419
|
-
return left_value
|
|
420
|
-
return value_compare(left_value, right_value)
|
|
418
|
+
return left_value > right_value
|
|
419
|
+
return value_compare(left_value, right_value) > 0
|
|
421
420
|
|
|
422
421
|
elif bin_op == '>=':
|
|
423
422
|
if (left_type is int or left_type is float) and (right_type is int or right_type is float):
|
|
424
423
|
return left_value >= right_value
|
|
425
424
|
return value_compare(left_value, right_value) >= 0
|
|
426
425
|
|
|
427
|
-
elif bin_op == '
|
|
426
|
+
elif bin_op == '==':
|
|
428
427
|
if (left_type is int or left_type is float) and (right_type is int or right_type is float):
|
|
429
|
-
return left_value
|
|
430
|
-
return value_compare(left_value, right_value)
|
|
428
|
+
return left_value == right_value
|
|
429
|
+
return value_compare(left_value, right_value) == 0
|
|
430
|
+
|
|
431
|
+
elif bin_op == '!=':
|
|
432
|
+
if (left_type is int or left_type is float) and (right_type is int or right_type is float):
|
|
433
|
+
return left_value != right_value
|
|
434
|
+
return value_compare(left_value, right_value) != 0
|
|
431
435
|
|
|
432
436
|
elif bin_op == '%':
|
|
433
437
|
# number % number
|
|
@@ -443,32 +447,32 @@ def evaluate_expression(expr, options=None, locals_=None, builtins=True, script=
|
|
|
443
447
|
|
|
444
448
|
elif bin_op == '&':
|
|
445
449
|
# int & int
|
|
446
|
-
if ((left_type is int or left_type is float
|
|
447
|
-
(right_type is int or right_type is float
|
|
450
|
+
if ((left_type is int or (left_type is float and left_value.is_integer())) and
|
|
451
|
+
(right_type is int or (right_type is float and right_value.is_integer()))):
|
|
448
452
|
return int(left_value) & int(right_value)
|
|
449
453
|
|
|
450
454
|
elif bin_op == '|':
|
|
451
455
|
# int & int
|
|
452
|
-
if ((left_type is int or left_type is float
|
|
453
|
-
(right_type is int or right_type is float
|
|
456
|
+
if ((left_type is int or (left_type is float and left_value.is_integer())) and
|
|
457
|
+
(right_type is int or (right_type is float and right_value.is_integer()))):
|
|
454
458
|
return int(left_value) | int(right_value)
|
|
455
459
|
|
|
456
460
|
elif bin_op == '^':
|
|
457
461
|
# int & int
|
|
458
|
-
if ((left_type is int or left_type is float
|
|
459
|
-
(right_type is int or right_type is float
|
|
462
|
+
if ((left_type is int or (left_type is float and left_value.is_integer())) and
|
|
463
|
+
(right_type is int or (right_type is float and right_value.is_integer()))):
|
|
460
464
|
return int(left_value) ^ int(right_value)
|
|
461
465
|
|
|
462
466
|
elif bin_op == '<<':
|
|
463
467
|
# int & int
|
|
464
|
-
if ((left_type is int or left_type is float
|
|
465
|
-
(right_type is int or right_type is float
|
|
468
|
+
if ((left_type is int or (left_type is float and left_value.is_integer())) and
|
|
469
|
+
(right_type is int or (right_type is float and right_value.is_integer()))):
|
|
466
470
|
return int(left_value) << int(right_value)
|
|
467
471
|
|
|
468
472
|
else: # bin_op == '>>':
|
|
469
473
|
# int & int
|
|
470
|
-
if ((left_type is int or left_type is float
|
|
471
|
-
(right_type is int or right_type is float
|
|
474
|
+
if ((left_type is int or (left_type is float and left_value.is_integer())) and
|
|
475
|
+
(right_type is int or (right_type is float and right_value.is_integer()))):
|
|
472
476
|
return int(left_value) >> int(right_value)
|
|
473
477
|
|
|
474
478
|
# Invalid operation values
|
|
@@ -486,7 +490,7 @@ def evaluate_expression(expr, options=None, locals_=None, builtins=True, script=
|
|
|
486
490
|
if val_type is int or val_type is float:
|
|
487
491
|
return -value
|
|
488
492
|
else: # unary_op == '~':
|
|
489
|
-
if
|
|
493
|
+
if val_type is int or (val_type is float and value.is_integer()):
|
|
490
494
|
return ~int(value)
|
|
491
495
|
|
|
492
496
|
# Invalid operation value
|
|
@@ -400,42 +400,58 @@ script_function_call(PyObject *script, PyObject *function, PyObject *args, PyObj
|
|
|
400
400
|
|
|
401
401
|
PyObject *last_arg_array = dict_getitem_borrow(function, K_lastArgArray);
|
|
402
402
|
if (PyErr_Occurred()) { Py_DECREF(func_locals); return NULL; }
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
403
|
+
int has_last_arg_array = (last_arg_array != NULL && PyObject_IsTrue(last_arg_array) == 1);
|
|
404
|
+
|
|
405
|
+
if (has_last_arg_array) {
|
|
406
|
+
Py_ssize_t ix_arg_last = func_args_length - 1;
|
|
407
|
+
for (Py_ssize_t ix = 0; ix < func_args_length; ix++) {
|
|
408
|
+
PyObject *arg_name = PyList_GET_ITEM(func_args, ix);
|
|
409
|
+
PyObject *val = NULL;
|
|
410
|
+
int needs_decref = 0;
|
|
411
|
+
if (ix < args_length) {
|
|
412
|
+
if (ix == ix_arg_last) {
|
|
413
|
+
/* args[ix:] */
|
|
414
|
+
if (PyList_Check(args)) {
|
|
415
|
+
val = PyList_GetSlice(args, ix, args_length);
|
|
416
|
+
} else {
|
|
417
|
+
val = PySequence_GetSlice(args, ix, args_length);
|
|
418
|
+
}
|
|
419
|
+
if (!val) { Py_DECREF(func_locals); return NULL; }
|
|
420
|
+
needs_decref = 1;
|
|
417
421
|
} else {
|
|
418
|
-
val =
|
|
422
|
+
val = PySequence_GetItem(args, ix);
|
|
423
|
+
if (!val) { Py_DECREF(func_locals); return NULL; }
|
|
424
|
+
needs_decref = 1;
|
|
419
425
|
}
|
|
420
|
-
if (!val) { Py_DECREF(func_locals); return NULL; }
|
|
421
|
-
needs_decref = 1;
|
|
422
426
|
} else {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
427
|
+
if (ix == ix_arg_last) {
|
|
428
|
+
val = PyList_New(0);
|
|
429
|
+
if (!val) { Py_DECREF(func_locals); return NULL; }
|
|
430
|
+
needs_decref = 1;
|
|
431
|
+
} else {
|
|
432
|
+
val = Py_None;
|
|
433
|
+
}
|
|
426
434
|
}
|
|
427
|
-
|
|
428
|
-
if (
|
|
429
|
-
|
|
435
|
+
int rc = PyDict_SetItem(func_locals, arg_name, val);
|
|
436
|
+
if (needs_decref) Py_DECREF(val);
|
|
437
|
+
if (rc < 0) { Py_DECREF(func_locals); return NULL; }
|
|
438
|
+
}
|
|
439
|
+
} else {
|
|
440
|
+
for (Py_ssize_t ix = 0; ix < func_args_length; ix++) {
|
|
441
|
+
PyObject *arg_name = PyList_GET_ITEM(func_args, ix);
|
|
442
|
+
PyObject *val;
|
|
443
|
+
int needs_decref = 0;
|
|
444
|
+
if (ix < args_length) {
|
|
445
|
+
val = PySequence_GetItem(args, ix);
|
|
430
446
|
if (!val) { Py_DECREF(func_locals); return NULL; }
|
|
431
447
|
needs_decref = 1;
|
|
432
448
|
} else {
|
|
433
449
|
val = Py_None;
|
|
434
450
|
}
|
|
451
|
+
int rc = PyDict_SetItem(func_locals, arg_name, val);
|
|
452
|
+
if (needs_decref) Py_DECREF(val);
|
|
453
|
+
if (rc < 0) { Py_DECREF(func_locals); return NULL; }
|
|
435
454
|
}
|
|
436
|
-
int rc = PyDict_SetItem(func_locals, arg_name, val);
|
|
437
|
-
if (needs_decref) Py_DECREF(val);
|
|
438
|
-
if (rc < 0) { Py_DECREF(func_locals); return NULL; }
|
|
439
455
|
}
|
|
440
456
|
}
|
|
441
457
|
|
|
@@ -588,12 +604,12 @@ op_to_id(PyObject *op)
|
|
|
588
604
|
if (op == K_op_minus) return OP_MINUS;
|
|
589
605
|
if (op == K_op_star) return OP_STAR;
|
|
590
606
|
if (op == K_op_slash) return OP_SLASH;
|
|
591
|
-
if (op == K_op_eq) return OP_EQ;
|
|
592
|
-
if (op == K_op_ne) return OP_NE;
|
|
593
|
-
if (op == K_op_le) return OP_LE;
|
|
594
607
|
if (op == K_op_lt) return OP_LT;
|
|
595
|
-
if (op ==
|
|
608
|
+
if (op == K_op_le) return OP_LE;
|
|
596
609
|
if (op == K_op_gt) return OP_GT;
|
|
610
|
+
if (op == K_op_ge) return OP_GE;
|
|
611
|
+
if (op == K_op_eq) return OP_EQ;
|
|
612
|
+
if (op == K_op_ne) return OP_NE;
|
|
597
613
|
if (op == K_op_pct) return OP_PCT;
|
|
598
614
|
if (op == K_op_star_star) return OP_STAR_STAR;
|
|
599
615
|
if (op == K_op_amp_amp) return OP_AND_AND;
|
|
@@ -611,12 +627,12 @@ op_to_id(PyObject *op)
|
|
|
611
627
|
if (PyUnicode_Compare(op, K_op_minus) == 0) return OP_MINUS;
|
|
612
628
|
if (PyUnicode_Compare(op, K_op_star) == 0) return OP_STAR;
|
|
613
629
|
if (PyUnicode_Compare(op, K_op_slash) == 0) return OP_SLASH;
|
|
614
|
-
if (PyUnicode_Compare(op, K_op_eq) == 0) return OP_EQ;
|
|
615
|
-
if (PyUnicode_Compare(op, K_op_ne) == 0) return OP_NE;
|
|
616
|
-
if (PyUnicode_Compare(op, K_op_le) == 0) return OP_LE;
|
|
617
630
|
if (PyUnicode_Compare(op, K_op_lt) == 0) return OP_LT;
|
|
618
|
-
if (PyUnicode_Compare(op,
|
|
631
|
+
if (PyUnicode_Compare(op, K_op_le) == 0) return OP_LE;
|
|
619
632
|
if (PyUnicode_Compare(op, K_op_gt) == 0) return OP_GT;
|
|
633
|
+
if (PyUnicode_Compare(op, K_op_ge) == 0) return OP_GE;
|
|
634
|
+
if (PyUnicode_Compare(op, K_op_eq) == 0) return OP_EQ;
|
|
635
|
+
if (PyUnicode_Compare(op, K_op_ne) == 0) return OP_NE;
|
|
620
636
|
if (PyUnicode_Compare(op, K_op_pct) == 0) return OP_PCT;
|
|
621
637
|
if (PyUnicode_Compare(op, K_op_star_star) == 0) return OP_STAR_STAR;
|
|
622
638
|
if (PyUnicode_Compare(op, K_op_amp_amp) == 0) return OP_AND_AND;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|