solpl 2.2.0__tar.gz → 2.2.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.
- {solpl-2.2.0/solpl.egg-info → solpl-2.2.5}/PKG-INFO +1 -1
- {solpl-2.2.0 → solpl-2.2.5}/interpreter/sol.py +34 -13
- {solpl-2.2.0 → solpl-2.2.5}/pyproject.toml +1 -1
- {solpl-2.2.0 → solpl-2.2.5/solpl.egg-info}/PKG-INFO +1 -1
- {solpl-2.2.0 → solpl-2.2.5}/LICENSE +0 -0
- {solpl-2.2.0 → solpl-2.2.5}/README.md +0 -0
- {solpl-2.2.0 → solpl-2.2.5}/setup.cfg +0 -0
- {solpl-2.2.0 → solpl-2.2.5}/solpl.egg-info/SOURCES.txt +0 -0
- {solpl-2.2.0 → solpl-2.2.5}/solpl.egg-info/dependency_links.txt +0 -0
- {solpl-2.2.0 → solpl-2.2.5}/solpl.egg-info/entry_points.txt +0 -0
- {solpl-2.2.0 → solpl-2.2.5}/solpl.egg-info/top_level.txt +0 -0
|
@@ -18,6 +18,7 @@ class SolInterpreter:
|
|
|
18
18
|
self.struct_blueprints = {}
|
|
19
19
|
self.lines = []
|
|
20
20
|
self.threads = []
|
|
21
|
+
self._server_started = False
|
|
21
22
|
|
|
22
23
|
@property
|
|
23
24
|
def scope_stack(self):
|
|
@@ -27,27 +28,36 @@ class SolInterpreter:
|
|
|
27
28
|
|
|
28
29
|
def _compute(self, expr):
|
|
29
30
|
expr = str(expr).strip()
|
|
30
|
-
|
|
31
|
+
|
|
32
|
+
# Handle string concatenation first
|
|
31
33
|
if "+" in expr and any(c.isalpha() or c in ['"', "'"] for c in expr):
|
|
32
34
|
parts = expr.split("+")
|
|
33
35
|
result = ""
|
|
34
36
|
for p in parts:
|
|
35
|
-
val =
|
|
36
|
-
result += val
|
|
37
|
+
val = self._resolve(p.strip())
|
|
38
|
+
result += str(val) if val is not None else ""
|
|
37
39
|
return result
|
|
38
40
|
|
|
41
|
+
# Handle math operations safely
|
|
39
42
|
ops = ['+', '-', '*', ':']
|
|
40
43
|
for op in ops:
|
|
41
44
|
if op in expr:
|
|
42
45
|
try:
|
|
43
46
|
left, right = expr.split(op, 1)
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
r1 = self._resolve(left)
|
|
48
|
+
r2 = self._resolve(right)
|
|
49
|
+
|
|
50
|
+
# SAFETY FIX: Skip if values are not numeric
|
|
51
|
+
if r1 is None or r2 is None:
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
val1 = float(r1)
|
|
55
|
+
val2 = float(r2)
|
|
46
56
|
if op == '+': return val1 + val2
|
|
47
57
|
if op == '-': return val1 - val2
|
|
48
58
|
if op == '*': return val1 * val2
|
|
49
59
|
if op == ':': return val1 / val2
|
|
50
|
-
except ValueError:
|
|
60
|
+
except (ValueError, TypeError):
|
|
51
61
|
continue
|
|
52
62
|
return self._resolve(expr)
|
|
53
63
|
|
|
@@ -63,6 +73,9 @@ class SolInterpreter:
|
|
|
63
73
|
def _resolve(self, val):
|
|
64
74
|
val = str(val).strip()
|
|
65
75
|
|
|
76
|
+
if (val.startswith('"') and val.endswith('"')) or (val.startswith("'") and val.endswith("'")):
|
|
77
|
+
return val[1:-1]
|
|
78
|
+
|
|
66
79
|
if val.startswith("_fetch(") and val.endswith(")"):
|
|
67
80
|
url_expr = val[7:-1].strip()
|
|
68
81
|
url = str(self._compute(url_expr))
|
|
@@ -93,7 +106,7 @@ class SolInterpreter:
|
|
|
93
106
|
existing_val = self._lookup(val)
|
|
94
107
|
if existing_val is not None: return existing_val
|
|
95
108
|
try: return float(val) if '.' in val else int(val)
|
|
96
|
-
except: return
|
|
109
|
+
except: return None
|
|
97
110
|
|
|
98
111
|
def _async_worker(self, expr, action):
|
|
99
112
|
result = self._compute(expr)
|
|
@@ -111,12 +124,15 @@ class SolInterpreter:
|
|
|
111
124
|
def _native_fetch(self, url):
|
|
112
125
|
try:
|
|
113
126
|
with urllib.request.urlopen(url, timeout=5) as response:
|
|
114
|
-
# Fix: Added errors='replace' to handle non-UTF-8 bytes safely
|
|
115
127
|
return response.read().decode('utf-8', errors='replace')
|
|
116
128
|
except Exception as e:
|
|
117
129
|
return f"Error fetching URL: {str(e)}"
|
|
118
130
|
|
|
119
131
|
def _native_listen(self, port, handler_name):
|
|
132
|
+
if self._server_started:
|
|
133
|
+
return
|
|
134
|
+
self._server_started = True
|
|
135
|
+
|
|
120
136
|
interpreter_instance = self
|
|
121
137
|
class SolHTTPHandler(http.server.BaseHTTPRequestHandler):
|
|
122
138
|
def do_GET(self):
|
|
@@ -240,7 +256,6 @@ class SolInterpreter:
|
|
|
240
256
|
if len(parts) == 3 and parts[1] == "_input":
|
|
241
257
|
prompt_string = str(self._compute(parts[0]))
|
|
242
258
|
target_variable = parts[2]
|
|
243
|
-
|
|
244
259
|
t = threading.Thread(target=self._async_input_worker, args=(prompt_string, target_variable))
|
|
245
260
|
t.start()
|
|
246
261
|
self.threads.append(t)
|
|
@@ -270,8 +285,10 @@ class SolInterpreter:
|
|
|
270
285
|
else:
|
|
271
286
|
var_name = line.split("->")[1].strip()
|
|
272
287
|
prompt = f"[INPUT REQUIRED FOR %s]: " % var_name
|
|
273
|
-
|
|
274
|
-
|
|
288
|
+
|
|
289
|
+
sys.stdout.write(prompt + " ")
|
|
290
|
+
sys.stdout.flush()
|
|
291
|
+
user_val = sys.stdin.readline().strip()
|
|
275
292
|
try:
|
|
276
293
|
if '.' in user_val: user_val = float(user_val)
|
|
277
294
|
else: user_val = int(user_val)
|
|
@@ -296,8 +313,12 @@ class SolInterpreter:
|
|
|
296
313
|
port = self._compute(port_expr)
|
|
297
314
|
self._native_listen(port, handler_expr)
|
|
298
315
|
elif "_out" in line:
|
|
299
|
-
|
|
300
|
-
|
|
316
|
+
val_raw = line.split("->")[1].strip()
|
|
317
|
+
val = self._compute(val_raw)
|
|
318
|
+
if val is not None:
|
|
319
|
+
print(val)
|
|
320
|
+
else:
|
|
321
|
+
print(f"Error: Undefined variable or invalid data: {val_raw}")
|
|
301
322
|
|
|
302
323
|
elif "mylist<" in line and ">" in line:
|
|
303
324
|
var_name = line.split("<")[1].split(">")[0]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|