solpl 2.7.0__tar.gz → 3.0.0__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.7.0
3
+ Version: 3.0.0
4
4
  Summary: A lightweight, multi-threaded interpreter for the Sol programming language
5
5
  Author-email: stefand-0 <stefand-0@users.noreply.github.com>
6
6
  License-Expression: Apache-2.0
@@ -41,7 +41,6 @@ class SolInterpreter:
41
41
  return False
42
42
 
43
43
  def _split_on_op(self, string, op):
44
- """Split on first occurrence of op outside quotes. Returns (left, right) or (None, None)."""
45
44
  in_quote = False
46
45
  quote_char = None
47
46
  for i, char in enumerate(string):
@@ -106,7 +105,6 @@ class SolInterpreter:
106
105
  start_idx = expr.rfind('(', 0, end_idx)
107
106
  if start_idx == -1:
108
107
  break
109
- # Skip function calls
110
108
  if start_idx > 0 and (expr[start_idx - 1].isalnum() or expr[start_idx - 1] == '_'):
111
109
  idx = end_idx + 1
112
110
  continue
@@ -115,7 +113,7 @@ class SolInterpreter:
115
113
  expr = expr[:start_idx] + str(inner_result) + expr[end_idx + 1:]
116
114
  idx = 0
117
115
 
118
- # Handle string concatenation with +
116
+ # String concatenation with +
119
117
  plus_parts = self._split_outside_quotes(expr, '+')
120
118
  if len(plus_parts) > 1:
121
119
  is_string_concat = False
@@ -131,7 +129,7 @@ class SolInterpreter:
131
129
  result += str(val) if val is not None else ""
132
130
  return result
133
131
 
134
- # Check for equality (=) - comparison operator
132
+ # Equality comparison (=)
135
133
  left, right = self._split_on_op(expr, '=')
136
134
  if left is not None:
137
135
  r1 = self._resolve(left.strip())
@@ -139,7 +137,7 @@ class SolInterpreter:
139
137
  if r1 is not None and r2 is not None:
140
138
  return 1 if r1 == r2 else 0
141
139
 
142
- # Level 1: + and -
140
+ # + and -
143
141
  for op in ['+', '-']:
144
142
  idx = self._find_last_op(expr, op)
145
143
  if idx != -1:
@@ -154,7 +152,7 @@ class SolInterpreter:
154
152
  if op == '+': return val1 + val2
155
153
  if op == '-': return val1 - val2
156
154
 
157
- # Level 2: * and :
155
+ # * and :
158
156
  last_idx = -1
159
157
  last_op = None
160
158
  for op in ['*', ':']:
@@ -215,9 +213,14 @@ class SolInterpreter:
215
213
  if isinstance(container, list): return container[idx]
216
214
  except (ValueError, IndexError, KeyError): pass
217
215
  if "." in val:
218
- obj_name, prop = val.split(".", 1)
219
- obj = self._lookup(obj_name)
220
- if isinstance(obj, dict): return obj.get(prop, 0)
216
+ parts = val.split(".")
217
+ obj = self._lookup(parts[0])
218
+ for part in parts[1:]:
219
+ if isinstance(obj, dict):
220
+ obj = obj.get(part, 0)
221
+ else:
222
+ return 0
223
+ return obj
221
224
 
222
225
  for scope in reversed(self.scope_stack):
223
226
  if val in scope: return scope[val]
@@ -253,15 +256,12 @@ class SolInterpreter:
253
256
  self.threads.append(t)
254
257
 
255
258
  def _evaluate_condition(self, cond):
256
- # Equality comparison uses =
257
259
  left, right = self._split_on_op(cond, "=")
258
260
  if left is not None:
259
- return self._compute(cond) # _compute handles =
260
- # Less than
261
+ return self._compute(cond)
261
262
  left, right = self._split_on_op(cond, "<")
262
263
  if left is not None:
263
264
  return self._compute(left.strip()) < self._compute(right.strip())
264
- # Greater than
265
265
  left, right = self._split_on_op(cond, ">")
266
266
  if left is not None:
267
267
  return self._compute(left.strip()) > self._compute(right.strip())
@@ -279,6 +279,36 @@ class SolInterpreter:
279
279
  pc += 1
280
280
  return pc
281
281
 
282
+ def _import_file(self, filename):
283
+ if not os.path.exists(filename):
284
+ print(f"Error: Module '{filename}' not found.")
285
+ return
286
+
287
+ with open(filename, "r") as f:
288
+ code = f.read()
289
+ module_name = os.path.splitext(os.path.basename(filename))[0]
290
+
291
+ lines = []
292
+ for l in code.split('\n'):
293
+ l = l.strip()
294
+ if not l: continue
295
+ if l.startswith(';'):
296
+ continue
297
+ if l.startswith('//'):
298
+ continue
299
+ if ';' in l:
300
+ l = l.split(';', 1)[0].strip()
301
+ if l:
302
+ lines.append(l)
303
+
304
+ for pc, line in enumerate(lines):
305
+ if "(" in line and ")" in line and "main" not in line and "end" not in line and "->" not in line and ">>" not in line and "?" not in line and not line.startswith(("if ", "while ", "for ", "elseif", "else")):
306
+ parts = line.split("(")
307
+ name = parts[0].strip()
308
+ params_str = parts[1].replace(")", "").strip()
309
+ params = [p.strip() for p in params_str.split(",")] if params_str else []
310
+ self.functions[f"{module_name}.{name}"] = {"start_pc": pc + 1, "params": params, "source_lines": lines}
311
+
282
312
  def execute(self, code):
283
313
  raw_lines = code.split('\n')
284
314
  self.lines = []
@@ -325,7 +355,7 @@ class SolInterpreter:
325
355
  fields[key] = self._resolve(val)
326
356
  pc += 1
327
357
  self.struct_blueprints[struct_name] = fields
328
- self._assign(struct_name, fields.copy())
358
+ self.variables[struct_name] = fields.copy()
329
359
  return pc
330
360
 
331
361
  def _call_function(self, name, args):
@@ -436,9 +466,17 @@ class SolInterpreter:
436
466
  if "->" in line:
437
467
  var, val = [x.strip() for x in line.split("->", 1)]
438
468
  if "." in var:
439
- obj, prop = var.split(".", 1)
440
- target = self._lookup(obj)
441
- if isinstance(target, dict): target[prop] = self._compute(val)
469
+ parts = var.split(".")
470
+ target = self._lookup(parts[0])
471
+ if isinstance(target, dict):
472
+ for part in parts[1:-1]:
473
+ if isinstance(target, dict) and part in target:
474
+ target = target[part]
475
+ else:
476
+ target = None
477
+ break
478
+ if target is not None and isinstance(target, dict):
479
+ target[parts[-1]] = self._compute(val)
442
480
  else:
443
481
  computed = self._compute(val)
444
482
  self._assign(var, computed)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "solpl"
7
- version = "2.7.0"
7
+ version = "3.0.0"
8
8
  authors = [
9
9
  { name = "stefand-0", email = "stefand-0@users.noreply.github.com" }
10
10
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solpl
3
- Version: 2.7.0
3
+ Version: 3.0.0
4
4
  Summary: A lightweight, multi-threaded interpreter for the Sol programming language
5
5
  Author-email: stefand-0 <stefand-0@users.noreply.github.com>
6
6
  License-Expression: Apache-2.0
File without changes
File without changes
File without changes
File without changes