shell-lite 0.4.1__py3-none-any.whl → 0.4.3__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.
- shell_lite/fix_nulls.py +29 -0
- shell_lite/interpreter.py +76 -7
- shell_lite/interpreter_backup.py +1781 -0
- shell_lite/interpreter_final.py +1773 -0
- shell_lite/interpreter_new.py +1773 -0
- shell_lite/lexer.py +10 -3
- shell_lite/lexer_new.py +252 -0
- shell_lite/main.py +17 -7
- shell_lite/minimal_interpreter.py +25 -0
- shell_lite/parser.py +279 -2
- shell_lite/parser_new.py +2229 -0
- shell_lite/patch_parser.py +41 -0
- {shell_lite-0.4.1.dist-info → shell_lite-0.4.3.dist-info}/METADATA +1 -1
- shell_lite-0.4.3.dist-info/RECORD +25 -0
- shell_lite-0.4.1.dist-info/RECORD +0 -17
- {shell_lite-0.4.1.dist-info → shell_lite-0.4.3.dist-info}/LICENSE +0 -0
- {shell_lite-0.4.1.dist-info → shell_lite-0.4.3.dist-info}/WHEEL +0 -0
- {shell_lite-0.4.1.dist-info → shell_lite-0.4.3.dist-info}/entry_points.txt +0 -0
- {shell_lite-0.4.1.dist-info → shell_lite-0.4.3.dist-info}/top_level.txt +0 -0
shell_lite/fix_nulls.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
import sys
|
|
3
|
+
import glob
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
files = [
|
|
7
|
+
r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\parser.py',
|
|
8
|
+
r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\lexer.py',
|
|
9
|
+
r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\interpreter.py',
|
|
10
|
+
r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\main.py',
|
|
11
|
+
r'c:\Users\shrey\OneDrive\Desktop\oka\shell-lite\shell_lite\ast_nodes.py',
|
|
12
|
+
r'c:\Users\shrey\OneDrive\Desktop\oka\tests_suite\repro_issues.shl'
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
for path in files:
|
|
16
|
+
try:
|
|
17
|
+
with open(path, 'rb') as f:
|
|
18
|
+
content = f.read()
|
|
19
|
+
|
|
20
|
+
if b'\x00' in content:
|
|
21
|
+
print(f"Null bytes found in {path}! Fixing...")
|
|
22
|
+
new_content = content.replace(b'\x00', b'')
|
|
23
|
+
with open(path, 'wb') as f:
|
|
24
|
+
f.write(new_content)
|
|
25
|
+
print(f"Fixed {path}.")
|
|
26
|
+
else:
|
|
27
|
+
print(f"No null bytes in {path}.")
|
|
28
|
+
except Exception as e:
|
|
29
|
+
print(f"Error checking {path}: {e}")
|
shell_lite/interpreter.py
CHANGED
|
@@ -128,6 +128,7 @@ class WebBuilder:
|
|
|
128
128
|
pass
|
|
129
129
|
class Interpreter:
|
|
130
130
|
def __init__(self):
|
|
131
|
+
print('DEBUG: VERSION 2 LOADED')
|
|
131
132
|
self.global_env = Environment()
|
|
132
133
|
self.current_env = self.global_env
|
|
133
134
|
self.functions: Dict[str, FunctionDef] = {}
|
|
@@ -153,11 +154,13 @@ class Interpreter:
|
|
|
153
154
|
'split': lambda s, d=" ": s.split(d),
|
|
154
155
|
'join': lambda lst, d="": d.join(str(x) for x in lst),
|
|
155
156
|
'replace': lambda s, old, new: s.replace(old, new),
|
|
156
|
-
'upper':
|
|
157
|
+
'upper': self._builtin_upper,
|
|
157
158
|
'lower': lambda s: s.lower(),
|
|
158
159
|
'trim': lambda s: s.strip(),
|
|
159
160
|
'startswith': lambda s, p: s.startswith(p),
|
|
160
161
|
'endswith': lambda s, p: s.endswith(p),
|
|
162
|
+
'sum_range': self._builtin_sum_range,
|
|
163
|
+
'range_list': self._builtin_range_list,
|
|
161
164
|
'find': lambda s, sub: s.find(sub),
|
|
162
165
|
'char': chr, 'ord': ord,
|
|
163
166
|
'append': lambda l, x: (l.append(x), l)[1],
|
|
@@ -172,9 +175,6 @@ class Interpreter:
|
|
|
172
175
|
'slice': lambda l, start, end=None: l[start:end],
|
|
173
176
|
'contains': lambda l, x: x in l,
|
|
174
177
|
'index': lambda l, x: l.index(x) if x in l else -1,
|
|
175
|
-
'map': self._builtin_map,
|
|
176
|
-
'filter': self._builtin_filter,
|
|
177
|
-
'reduce': self._builtin_reduce,
|
|
178
178
|
'exists': os.path.exists,
|
|
179
179
|
'delete': os.remove,
|
|
180
180
|
'copy': shutil.copy,
|
|
@@ -825,7 +825,7 @@ class Interpreter:
|
|
|
825
825
|
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
826
826
|
if result.returncode != 0:
|
|
827
827
|
print(f"Command Error: {result.stderr}")
|
|
828
|
-
return result.stdout.strip()
|
|
828
|
+
return result.stdout.strip() or result.stderr.strip()
|
|
829
829
|
except Exception as e:
|
|
830
830
|
raise RuntimeError(f"Failed to run command: {e}")
|
|
831
831
|
def builtin_read(self, path):
|
|
@@ -1496,7 +1496,7 @@ class Interpreter:
|
|
|
1496
1496
|
if interpreter_ref.web.stack:
|
|
1497
1497
|
pass
|
|
1498
1498
|
if isinstance(result, Tag): response_body = str(result)
|
|
1499
|
-
elif result: response_body = str(result)
|
|
1499
|
+
elif result is not None: response_body = str(result)
|
|
1500
1500
|
else: response_body = "OK"
|
|
1501
1501
|
self.send_response(200)
|
|
1502
1502
|
self.send_header('Content-Type', 'text/html')
|
|
@@ -1519,7 +1519,7 @@ class Interpreter:
|
|
|
1519
1519
|
self.wfile.write(str(e).encode())
|
|
1520
1520
|
except: pass
|
|
1521
1521
|
server = HTTPServer(('0.0.0.0', port_val), ShellLiteHandler)
|
|
1522
|
-
print(f"\n ShellLite Server v0.04.
|
|
1522
|
+
print(f"\n ShellLite Server v0.04.3 is running!")
|
|
1523
1523
|
print(f" \u001b[1;36m➜\u001b[0m Local: \u001b[1;4;36mhttp://localhost:{port_val}/\u001b[0m\n")
|
|
1524
1524
|
try: server.serve_forever()
|
|
1525
1525
|
except KeyboardInterrupt:
|
|
@@ -1708,3 +1708,72 @@ if __name__ == '__main__':
|
|
|
1708
1708
|
print(f"Error: {e}")
|
|
1709
1709
|
import traceback
|
|
1710
1710
|
traceback.print_exc()
|
|
1711
|
+
|
|
1712
|
+
def _builtin_upper(self, s, only_letters=False):
|
|
1713
|
+
if not only_letters:
|
|
1714
|
+
return s.upper()
|
|
1715
|
+
# "UPPER words ONLY LETTERS" -> Uppercase normal letters, leave others?
|
|
1716
|
+
# Or maybe it means "Only extract uppercase letters"?
|
|
1717
|
+
# User output shows: "HELLO WORLD 123" -> "HELLO WORLD 123" (normal)
|
|
1718
|
+
# Wait, user screenshot says:
|
|
1719
|
+
# text = "hello world 123"
|
|
1720
|
+
# words = split text
|
|
1721
|
+
# say upper words only letters
|
|
1722
|
+
# Error: Variable 'only' is not defined.
|
|
1723
|
+
# So maybe they want to UPPERCASE ONLY LETTERS? digits remain same? .upper() does that.
|
|
1724
|
+
# But maybe they mean "remove non-letters"?
|
|
1725
|
+
# "upper words only letters" -> "HELLO WORLD".
|
|
1726
|
+
# If "only letters" means filter?
|
|
1727
|
+
# Let's assume it means "uppercase only the letters" which is standard behavior?
|
|
1728
|
+
# Or maybe "uppercase, and keep only letters".
|
|
1729
|
+
# Let's look at user intent. "upper words only letters".
|
|
1730
|
+
# Likely: Uppercase and remove numbers/symbols?
|
|
1731
|
+
# If input is "hello world 123", output might be "HELLO WORLD".
|
|
1732
|
+
if only_letters:
|
|
1733
|
+
import re
|
|
1734
|
+
return re.sub(r'[^a-zA-Z\s]', '', s).upper()
|
|
1735
|
+
return s.upper()
|
|
1736
|
+
|
|
1737
|
+
def _builtin_sum_range(self, start, end, condition=None):
|
|
1738
|
+
# condition is a string, e.g. "even", "odd", "prime", "digits"
|
|
1739
|
+
total = 0
|
|
1740
|
+
s = int(start)
|
|
1741
|
+
e = int(end)
|
|
1742
|
+
for i in range(s, e + 1):
|
|
1743
|
+
include = True
|
|
1744
|
+
if condition == 'even' and i % 2 != 0: include = False
|
|
1745
|
+
elif condition == 'odd' and i % 2 == 0: include = False
|
|
1746
|
+
elif condition == 'prime':
|
|
1747
|
+
if i < 2: include = False
|
|
1748
|
+
else:
|
|
1749
|
+
for k in range(2, int(i ** 0.5) + 1):
|
|
1750
|
+
if i % k == 0:
|
|
1751
|
+
include = False; break
|
|
1752
|
+
elif condition == 'digits':
|
|
1753
|
+
# sum of digits? Or sum of numbers that are single digits?
|
|
1754
|
+
# "sum of numbers from 1 to 10 when digits" -> unclear.
|
|
1755
|
+
# Assuming "digits" meant specific property.
|
|
1756
|
+
pass
|
|
1757
|
+
|
|
1758
|
+
if include:
|
|
1759
|
+
total += i
|
|
1760
|
+
return total
|
|
1761
|
+
|
|
1762
|
+
def _builtin_range_list(self, start, end, condition=None):
|
|
1763
|
+
res = []
|
|
1764
|
+
s = int(start)
|
|
1765
|
+
e = int(end)
|
|
1766
|
+
for i in range(s, e + 1):
|
|
1767
|
+
include = True
|
|
1768
|
+
if condition == 'even' and i % 2 != 0: include = False
|
|
1769
|
+
elif condition == 'odd' and i % 2 == 0: include = False
|
|
1770
|
+
elif condition == 'prime':
|
|
1771
|
+
if i < 2: include = False
|
|
1772
|
+
else:
|
|
1773
|
+
for k in range(2, int(i ** 0.5) + 1):
|
|
1774
|
+
if i % k == 0:
|
|
1775
|
+
include = False; break
|
|
1776
|
+
|
|
1777
|
+
if include:
|
|
1778
|
+
res.append(i)
|
|
1779
|
+
return res
|