openc3-cosmos-script-engine-cstol 1.2.0 → 1.3.2

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cstol_script_engine.py +61 -10
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09b27bfb1b01bd2a21ff41078e7d25e2112d9024d9dfb2ab4663a2bd1b419780'
4
- data.tar.gz: 8fd1660731f16948ea44cd2539408b100f34018534d8e7df47bb045d18ff2984
3
+ metadata.gz: d0dfd6b3382cbfb7f4b73349047d0694aeab39e52ac67c0606b55a14afb2c814
4
+ data.tar.gz: 59d7c0c79e2f1d8cfc9a17466d6deb3d6d60cfa0912f255074f5307509026f1b
5
5
  SHA512:
6
- metadata.gz: ee0cf899dd95e9c5aa305a9e228bef5cbaad1d41d357cc76a7eba36b51cdaf16777bf43ac7f7fbea875853319b9b34bedd73c798779a8746056079c047e6e844
7
- data.tar.gz: 4d3600530bec3d984aeb07529ba87d67314254a4233c6bb7bec010a78ac6fce08d5e5c49193af70a50f182e8b95c23b3a5928eeb2e7f44698b0bab34c3f19336
6
+ metadata.gz: 97127866fe1b94549e7ea10513f047228df0dcbdff6ed03353ed7f50b9587e89244d00ea771c056138faef11c998eb9292dc95bd2a7c6428da7fabcb47d72fa2
7
+ data.tar.gz: c222c13292265034cca2f091e04da0e1f32bfefdb5f6e39118ddb4845287aac8edca27feee42fbcd4aeb5bf706c2d86e12d0468da386dcf09037f4bde7dcb1f4
@@ -123,6 +123,14 @@ class CstolVariables:
123
123
  """
124
124
  return self.local_variables.get(name.upper(), None)
125
125
 
126
+ def has_local_variable(self, name):
127
+ """
128
+ Returns True if the local variable has been set (case insensitive).
129
+ Note this is different from get_local_variable returning None because
130
+ a variable can be legitimately set to None.
131
+ """
132
+ return name.upper() in self.local_variables
133
+
126
134
  def set_special_variable(self, name, value):
127
135
  """
128
136
  Sets a special variable, which is a variable that starts with '$$'.
@@ -442,10 +450,10 @@ class CstolScriptEngine(ScriptEngine):
442
450
  # Use regex to extract the numeric part (including scientific notation)
443
451
  # This pattern matches:
444
452
  # - Optional sign (+/-)
445
- # - Digits, optional decimal point and more digits
453
+ # - Digits with an optional decimal point, or a leading-dot fraction
446
454
  # - Optional scientific notation (e/E followed by optional sign and digits)
447
455
  # - Ignores any alphabetic characters that follow
448
- matches = re.match(r"^([+-]?\d*\.?\d+(?:[eE][+-]?\d+)?)", token)
456
+ matches = re.match(r"^([+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?)", token)
449
457
  if matches is not None:
450
458
  final_tokens.append(str(matches.group(1)))
451
459
  previous_number = True
@@ -765,9 +773,13 @@ class CstolScriptEngine(ScriptEngine):
765
773
  success = False
766
774
  fail_message = f"not equal to {vs_value}"
767
775
  else:
768
- # No VS - Just a print check
776
+ # No VS but could be a relational or logical expression
769
777
  source = " ".join(expr)
770
778
  value = self.evaluate_expression(expr)
779
+ # Relational/logical expressions evaluate to a bool and must be True
780
+ if value is False:
781
+ success = False
782
+ fail_message = "expression is false"
771
783
 
772
784
  formatted_value = self.apply_format(format_spec, value)
773
785
 
@@ -922,7 +934,18 @@ class CstolScriptEngine(ScriptEngine):
922
934
  raise ValueError(
923
935
  f"Expected '=' after variable name in DECLARE command at line {line_no}"
924
936
  )
925
- default_value = self.evaluate_tokens([tokens[4]])[0]
937
+ default_end = 6 if tokens[4] in ("+", "-") else 5
938
+ default_tokens = tokens[4:default_end]
939
+ scientific_default = "".join(tokens[4 : default_end + 2])
940
+ if re.fullmatch(
941
+ r"[+-]?(?:\d+(?:\.\d*)?|\.\d+)[eE][+-]\d+(?:[A-Za-z]+)?", scientific_default
942
+ ):
943
+ default_tokens = [scientific_default]
944
+ default_value = self.evaluate_expression(default_tokens)
945
+ if mode == "INPUT" and self.variables.has_local_variable(variable_name):
946
+ # INPUT variables are passed in by the PROC argument list, so the
947
+ # default value is only applied when an argument wasn't given
948
+ return
926
949
  self.variables.set_local_variable(variable_name, default_value)
927
950
 
928
951
  def handle_display(self, tokens, line_no):
@@ -1170,13 +1193,42 @@ class CstolScriptEngine(ScriptEngine):
1170
1193
  if token == ",":
1171
1194
  continue
1172
1195
  elif token.startswith("$"):
1173
- self.variables.set_local_variable(token, os.getenv(f"CSTOL_ARG_{index}"))
1196
+ value = os.getenv(f"CSTOL_ARG_{index}")
1197
+ if value is not None:
1198
+ # START stores the type alongside the value so the local
1199
+ # variable gets the type the caller passed rather than a string
1200
+ value = self.convert_arg(value, os.getenv(f"CSTOL_ARG_{index}_TYPE"))
1201
+ self.variables.set_local_variable(token, value)
1174
1202
  index += 1
1175
1203
  else:
1176
1204
  raise ValueError(
1177
1205
  f"Invalid variable '{token}' in PROC command at line {line_no}"
1178
1206
  )
1179
1207
 
1208
+ @staticmethod
1209
+ def convert_arg(value, type_name):
1210
+ """
1211
+ Converts a CSTOL_ARG environment variable string back into the type it
1212
+ had when START was called. Returns the string unchanged if the type is
1213
+ unknown or the value can't be converted.
1214
+ """
1215
+ try:
1216
+ match type_name:
1217
+ case "int":
1218
+ return int(value)
1219
+ case "float":
1220
+ return float(value)
1221
+ case "complex":
1222
+ return complex(value)
1223
+ case "bool":
1224
+ return value == "True"
1225
+ case "NoneType":
1226
+ return None
1227
+ case _:
1228
+ return value
1229
+ except ValueError:
1230
+ return value
1231
+
1180
1232
  def handle_return(self, tokens, lines, line_no):
1181
1233
  if len(tokens) > 1 and tokens[1].upper() == "ALL":
1182
1234
  raise StopScriptError
@@ -1216,15 +1268,14 @@ class CstolScriptEngine(ScriptEngine):
1216
1268
  # Remove quotes
1217
1269
  proc_name = proc_name[1:-1]
1218
1270
 
1219
- args = []
1220
1271
  if len(tokens) > 2:
1221
1272
  # Handle argument list
1222
1273
  expressions = self.extract_expressions(tokens[2:], ",")
1223
1274
  results = self.evaluate_expressions(expressions)
1224
- args = [str(result) for result in results]
1225
- for index, arg in enumerate(args):
1226
- # Set the environment variable for the argument
1227
- os.environ[f"CSTOL_ARG_{index}"] = arg
1275
+ for index, result in enumerate(results):
1276
+ # Set the environment variables for the argument and its type
1277
+ os.environ[f"CSTOL_ARG_{index}"] = str(result)
1278
+ os.environ[f"CSTOL_ARG_{index}_TYPE"] = type(result).__name__
1228
1279
  start(proc_name, bind_variables=False)
1229
1280
 
1230
1281
  def handle_switch(self, tokens, line_no):
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openc3-cosmos-script-engine-cstol
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenC3, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-17 00:00:00.000000000 Z
11
+ date: 2026-11-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " This plugin provides a script engine to support CSTOL in Script Runner\n"
14
14
  email: