shell-lite 0.4.4__tar.gz → 0.4.5__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.
- {shell_lite-0.4.4/shell_lite.egg-info → shell_lite-0.4.5}/PKG-INFO +1 -1
- {shell_lite-0.4.4 → shell_lite-0.4.5}/pyproject.toml +1 -1
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/interpreter.py +45 -26
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/main.py +5 -6
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/parser.py +1 -1
- {shell_lite-0.4.4 → shell_lite-0.4.5/shell_lite.egg-info}/PKG-INFO +1 -1
- {shell_lite-0.4.4 → shell_lite-0.4.5}/LICENSE +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/README.md +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/setup.cfg +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/__init__.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/ast_nodes.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/cli.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/compiler.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/lexer.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite/runtime.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite.egg-info/SOURCES.txt +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite.egg-info/dependency_links.txt +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite.egg-info/entry_points.txt +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite.egg-info/requires.txt +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/shell_lite.egg-info/top_level.txt +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/tests/test_interpreter.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/tests/test_lexer.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/tests/test_parser.py +0 -0
- {shell_lite-0.4.4 → shell_lite-0.4.5}/tests/test_stdlib.py +0 -0
|
@@ -3,6 +3,7 @@ from .ast_nodes import *
|
|
|
3
3
|
from .lexer import Token, Lexer
|
|
4
4
|
from .parser import Parser
|
|
5
5
|
import importlib
|
|
6
|
+
import types
|
|
6
7
|
import operator
|
|
7
8
|
import re
|
|
8
9
|
import os
|
|
@@ -128,7 +129,7 @@ class WebBuilder:
|
|
|
128
129
|
pass
|
|
129
130
|
class Interpreter:
|
|
130
131
|
def __init__(self):
|
|
131
|
-
print('DEBUG: ShellLite v0.04.
|
|
132
|
+
# print('DEBUG: ShellLite v0.04.5')
|
|
132
133
|
self.global_env = Environment()
|
|
133
134
|
self.global_env.set('str', str)
|
|
134
135
|
self.global_env.set('int', int)
|
|
@@ -776,7 +777,12 @@ class Interpreter:
|
|
|
776
777
|
if node.path in self.std_modules:
|
|
777
778
|
self.current_env.set(node.path, self.std_modules[node.path])
|
|
778
779
|
return
|
|
780
|
+
|
|
781
|
+
# 1. Check File System (ShellLite modules)
|
|
779
782
|
import os
|
|
783
|
+
import importlib
|
|
784
|
+
target_path = None
|
|
785
|
+
|
|
780
786
|
if os.path.exists(node.path):
|
|
781
787
|
target_path = node.path
|
|
782
788
|
else:
|
|
@@ -789,32 +795,45 @@ class Interpreter:
|
|
|
789
795
|
global_path_ext = global_path + ".shl"
|
|
790
796
|
if os.path.exists(global_path_ext):
|
|
791
797
|
target_path = global_path_ext
|
|
792
|
-
|
|
793
|
-
|
|
798
|
+
|
|
799
|
+
# 2. If found on FS, load as ShellLite
|
|
800
|
+
if target_path:
|
|
801
|
+
if os.path.isdir(target_path):
|
|
802
|
+
main_shl = os.path.join(target_path, "main.shl")
|
|
803
|
+
pkg_shl = os.path.join(target_path, f"{os.path.basename(target_path)}.shl")
|
|
804
|
+
if os.path.exists(main_shl):
|
|
805
|
+
target_path = main_shl
|
|
806
|
+
elif os.path.exists(pkg_shl):
|
|
807
|
+
target_path = pkg_shl
|
|
794
808
|
else:
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
809
|
+
raise FileNotFoundError(f"Package '{node.path}' is a folder but has no 'main.shl' or '{os.path.basename(target_path)}.shl'.")
|
|
810
|
+
|
|
811
|
+
try:
|
|
812
|
+
with open(target_path, 'r', encoding='utf-8') as f:
|
|
813
|
+
code = f.read()
|
|
814
|
+
except FileNotFoundError:
|
|
815
|
+
raise FileNotFoundError(f"Could not find imported file: {node.path}")
|
|
816
|
+
|
|
817
|
+
from .lexer import Lexer
|
|
818
|
+
from .parser import Parser
|
|
819
|
+
lexer = Lexer(code)
|
|
820
|
+
tokens = lexer.tokenize()
|
|
821
|
+
parser = Parser(tokens)
|
|
822
|
+
statements = parser.parse()
|
|
823
|
+
for stmt in statements:
|
|
824
|
+
self.visit(stmt)
|
|
825
|
+
return
|
|
826
|
+
|
|
827
|
+
# 3. BRIDGE: Try importing as a raw Python module
|
|
805
828
|
try:
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
parser = Parser(tokens)
|
|
815
|
-
statements = parser.parse()
|
|
816
|
-
for stmt in statements:
|
|
817
|
-
self.visit(stmt)
|
|
829
|
+
py_module = importlib.import_module(node.path)
|
|
830
|
+
self.current_env.set(node.path, py_module)
|
|
831
|
+
return
|
|
832
|
+
except ImportError:
|
|
833
|
+
pass # Fall through to error
|
|
834
|
+
|
|
835
|
+
raise FileNotFoundError(f"Could not find module '{node.path}'. Searched:\n - ShellLite Local/Global\n - Python Site-Packages (The Bridge)")
|
|
836
|
+
|
|
818
837
|
def _get_class_properties(self, class_def: ClassDef) -> List[tuple[str, Optional[Node]]]:
|
|
819
838
|
if not hasattr(class_def, 'properties'): return []
|
|
820
839
|
# Support both old string list and new tuple list for backward compat if needed, though we updated AST
|
|
@@ -1540,7 +1559,7 @@ class Interpreter:
|
|
|
1540
1559
|
self.wfile.write(str(e).encode())
|
|
1541
1560
|
except: pass
|
|
1542
1561
|
server = HTTPServer(('0.0.0.0', port_val), ShellLiteHandler)
|
|
1543
|
-
print(f"\n ShellLite Server v0.04.
|
|
1562
|
+
print(f"\n ShellLite Server v0.04.5 is running!")
|
|
1544
1563
|
print(f" \u001b[1;36m➜\u001b[0m Local: \u001b[1;4;36mhttp://localhost:{port_val}/\u001b[0m\n")
|
|
1545
1564
|
try: server.serve_forever()
|
|
1546
1565
|
except KeyboardInterrupt:
|
|
@@ -58,10 +58,9 @@ def run_file(filename: str):
|
|
|
58
58
|
print(f"Error: File '{filename}' not found.")
|
|
59
59
|
return
|
|
60
60
|
import sys
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
from .
|
|
64
|
-
print(f"DEBUG: Interpreter class: {Interpreter}")
|
|
61
|
+
|
|
62
|
+
# Debug prints removed for production
|
|
63
|
+
from .interpreter import Interpreter
|
|
65
64
|
|
|
66
65
|
with open(filename, 'r', encoding='utf-8') as f:
|
|
67
66
|
source = f.read()
|
|
@@ -72,7 +71,7 @@ def run_repl():
|
|
|
72
71
|
print("\n" + "="*40)
|
|
73
72
|
print(" ShellLite REPL - English Syntax")
|
|
74
73
|
print("="*40)
|
|
75
|
-
print("Version: v0.04.
|
|
74
|
+
print("Version: v0.04.5 | Made by Shrey Naithani")
|
|
76
75
|
print("Commands: Type 'exit' to quit, 'help' for examples.")
|
|
77
76
|
print("Note: Terminal commands (like 'shl install') must be run in CMD/PowerShell, not here.")
|
|
78
77
|
|
|
@@ -203,7 +202,7 @@ def install_globally():
|
|
|
203
202
|
ps_cmd = f'$oldPath = [Environment]::GetEnvironmentVariable("Path", "User"); if ($oldPath -notlike "*ShellLite*") {{ [Environment]::SetEnvironmentVariable("Path", "$oldPath;{install_dir}", "User") }}'
|
|
204
203
|
subprocess.run(["powershell", "-Command", ps_cmd], capture_output=True)
|
|
205
204
|
|
|
206
|
-
print(f"\n[SUCCESS] ShellLite (v0.04.
|
|
205
|
+
print(f"\n[SUCCESS] ShellLite (v0.04.5) is installed!")
|
|
207
206
|
print(f"Location: {install_dir}")
|
|
208
207
|
print("\nIMPORTANT STEP REQUIRED:")
|
|
209
208
|
print("1. Close ALL open terminal windows (CMD, PowerShell, VS Code).")
|
|
@@ -80,7 +80,7 @@ class Parser:
|
|
|
80
80
|
return self.parse_make()
|
|
81
81
|
elif self.check('INPUT'):
|
|
82
82
|
next_t = self.peek(1)
|
|
83
|
-
if next_t.type in ('ID', 'TYPE', 'STRING', 'NAME', 'VALUE', 'CLASS', 'STYLE', 'ONCLICK', 'SRC', 'HREF', 'ACTION', 'METHOD'):
|
|
83
|
+
if next_t.type in ('ID', 'TYPE', 'STRING', 'NAME', 'VALUE', 'CLASS', 'STYLE', 'ONCLICK', 'SRC', 'HREF', 'ACTION', 'METHOD', 'PLACEHOLDER'):
|
|
84
84
|
input_token = self.consume()
|
|
85
85
|
return self.parse_id_start_statement(passed_name_token=input_token)
|
|
86
86
|
return self.parse_expression_stmt()
|
|
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
|