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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solpl
3
- Version: 2.2.0
3
+ Version: 2.2.5
4
4
  Summary: Sol Programming Language Interpreter
5
5
  Requires-Python: >=3.7
6
6
  License-File: LICENSE
@@ -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 = str(self._resolve(p.strip()))
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
- val1 = float(self._resolve(left))
45
- val2 = float(self._resolve(right))
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 val.replace('"', '').replace("'", "")
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
- user_val = input(prompt + " ")
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
- val = line.split("->")[1].strip()
300
- print(self._compute(val))
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]
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "solpl"
7
- version = "2.2.0"
7
+ version = "2.2.5"
8
8
  description = "Sol Programming Language Interpreter"
9
9
  requires-python = ">=3.7"
10
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solpl
3
- Version: 2.2.0
3
+ Version: 2.2.5
4
4
  Summary: Sol Programming Language Interpreter
5
5
  Requires-Python: >=3.7
6
6
  License-File: LICENSE
File without changes
File without changes
File without changes
File without changes