Update scl.py
这个提交包含在:
@@ -12,13 +12,62 @@ import tkinter as tk
|
|||||||
|
|
||||||
class SCLInterpreter:
|
class SCLInterpreter:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.variables = {}
|
self.variables = {} # 变量存储
|
||||||
self.functions = {}
|
self.functions = {} # 函数存储
|
||||||
self.plugins = {}
|
self.plugins = {} # 插件存储
|
||||||
self.loaded_plugins = set()
|
self.loaded_plugins = set() # 已加载插件
|
||||||
self.debug_mode = False # 默认为false,不开启debug模式
|
self.debug_mode = False # 默认为false,不开启debug模式
|
||||||
|
|
||||||
|
# 缓存管理 - 限制缓存大小
|
||||||
self.expression_cache = {} # 缓存表达式求值结果
|
self.expression_cache = {} # 缓存表达式求值结果
|
||||||
self.token_cache = {} # 缓存tokenize结果
|
self.token_cache = {} # 缓存tokenize结果
|
||||||
|
self.code_block_cache = {} # 缓存代码块执行结果
|
||||||
|
self.statement_cache = {} # 缓存语句解析结果
|
||||||
|
|
||||||
|
# 缓存大小限制
|
||||||
|
self.MAX_CACHE_SIZE = 1000
|
||||||
|
|
||||||
|
# 预编译正则表达式
|
||||||
|
import re
|
||||||
|
self.comment_pattern = re.compile(r'^\s*(#|//)')
|
||||||
|
self.empty_pattern = re.compile(r'^\s*$')
|
||||||
|
|
||||||
|
# 预定义常量
|
||||||
|
self.multi_line_starts = {
|
||||||
|
'sif ', 'swhile :', 'swhile |', 'swhi ', 'srg', 'sdef <', 'sclass <'
|
||||||
|
}
|
||||||
|
|
||||||
|
# 操作符优先级映射
|
||||||
|
self.operator_precedence = {
|
||||||
|
'*': 3,
|
||||||
|
'/': 3,
|
||||||
|
'+': 2,
|
||||||
|
'-': 2,
|
||||||
|
'>': 1,
|
||||||
|
'<': 1,
|
||||||
|
'==': 1,
|
||||||
|
'!=': 1,
|
||||||
|
'>=': 1,
|
||||||
|
'<=': 1,
|
||||||
|
'&': 0,
|
||||||
|
'|': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 快速操作映射
|
||||||
|
self.operation_map = {
|
||||||
|
'+': lambda a, b: str(a) + str(b) if isinstance(a, str) or isinstance(b, str) else a + b,
|
||||||
|
'-': lambda a, b: a - b,
|
||||||
|
'*': lambda a, b: a * b,
|
||||||
|
'/': lambda a, b: a / b if b != 0 else 0,
|
||||||
|
'>': lambda a, b: a > b,
|
||||||
|
'<': lambda a, b: a < b,
|
||||||
|
'==': lambda a, b: a == b,
|
||||||
|
'!=': lambda a, b: a != b,
|
||||||
|
'>=': lambda a, b: a >= b,
|
||||||
|
'<=': lambda a, b: a <= b,
|
||||||
|
'&': lambda a, b: a and b,
|
||||||
|
'|': lambda a, b: a or b
|
||||||
|
}
|
||||||
|
|
||||||
def _find_plugin_class(self, plugin_module):
|
def _find_plugin_class(self, plugin_module):
|
||||||
"""Find the plugin class in a module"""
|
"""Find the plugin class in a module"""
|
||||||
@@ -27,6 +76,13 @@ class SCLInterpreter:
|
|||||||
return name
|
return name
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _manage_cache(self, cache):
|
||||||
|
"""管理缓存大小,防止内存过度使用"""
|
||||||
|
if len(cache) > self.MAX_CACHE_SIZE:
|
||||||
|
# 删除最旧的缓存项
|
||||||
|
for key in list(cache.keys())[:len(cache) - self.MAX_CACHE_SIZE]:
|
||||||
|
del cache[key]
|
||||||
|
|
||||||
def _register_plugin_instance(self, plugin_name, plugin_instance, is_web=False, url=None):
|
def _register_plugin_instance(self, plugin_name, plugin_instance, is_web=False, url=None):
|
||||||
"""Register a plugin instance"""
|
"""Register a plugin instance"""
|
||||||
self.plugins[plugin_name] = plugin_instance
|
self.plugins[plugin_name] = plugin_instance
|
||||||
@@ -184,6 +240,9 @@ class SCLInterpreter:
|
|||||||
code = code.strip()
|
code = code.strip()
|
||||||
i = 0
|
i = 0
|
||||||
n = len(code)
|
n = len(code)
|
||||||
|
if n == 0:
|
||||||
|
self.token_cache[code_hash] = []
|
||||||
|
return []
|
||||||
|
|
||||||
# 预定义常量
|
# 预定义常量
|
||||||
whitespace_chars = {' ', '\t', '\n', '\r'}
|
whitespace_chars = {' ', '\t', '\n', '\r'}
|
||||||
@@ -191,7 +250,7 @@ class SCLInterpreter:
|
|||||||
paren_chars = {'(', ')', '[', ']', '{', '}'}
|
paren_chars = {'(', ')', '[', ']', '{', '}'}
|
||||||
|
|
||||||
# 预分配空间,减少列表扩展开销
|
# 预分配空间,减少列表扩展开销
|
||||||
tokens = [None] * (n // 2) # 预估令牌数量
|
tokens = []
|
||||||
token_count = 0
|
token_count = 0
|
||||||
|
|
||||||
while i < n:
|
while i < n:
|
||||||
@@ -207,23 +266,18 @@ class SCLInterpreter:
|
|||||||
if char == '"':
|
if char == '"':
|
||||||
# 字符串处理
|
# 字符串处理
|
||||||
j = i + 1
|
j = i + 1
|
||||||
string_content = []
|
# 快速查找字符串结束位置
|
||||||
while j < n and code[j] != '"':
|
while j < n:
|
||||||
if code[j] == '\\' and j + 1 < n:
|
if code[j] == '\\' and j + 1 < n:
|
||||||
j += 1
|
j += 2
|
||||||
if code[j] == 'n':
|
elif code[j] == '"':
|
||||||
string_content.append('\n')
|
break
|
||||||
elif code[j] == '\\':
|
|
||||||
string_content.append('\\')
|
|
||||||
else:
|
else:
|
||||||
string_content.append(code[j])
|
|
||||||
else:
|
|
||||||
string_content.append(code[j])
|
|
||||||
j += 1
|
j += 1
|
||||||
if token_count >= len(tokens):
|
# 处理转义字符
|
||||||
tokens.extend([None] * (n // 2))
|
string_content = code[i+1:j]
|
||||||
tokens[token_count] = ('STRING', ''.join(string_content))
|
string_content = string_content.replace('\\n', '\n').replace('\\\\', '\\')
|
||||||
token_count += 1
|
tokens.append(('STRING', string_content))
|
||||||
i = j + 1 if j < n else n
|
i = j + 1 if j < n else n
|
||||||
|
|
||||||
elif char.isdigit():
|
elif char.isdigit():
|
||||||
@@ -231,10 +285,7 @@ class SCLInterpreter:
|
|||||||
j = i
|
j = i
|
||||||
while j < n and (code[j].isdigit() or code[j] == '.'):
|
while j < n and (code[j].isdigit() or code[j] == '.'):
|
||||||
j += 1
|
j += 1
|
||||||
if token_count >= len(tokens):
|
tokens.append(('NUMBER', code[i:j]))
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('NUMBER', code[i:j])
|
|
||||||
token_count += 1
|
|
||||||
i = j
|
i = j
|
||||||
|
|
||||||
elif char.isalpha() or char == '_':
|
elif char.isalpha() or char == '_':
|
||||||
@@ -242,24 +293,15 @@ class SCLInterpreter:
|
|||||||
j = i
|
j = i
|
||||||
while j < n and (code[j].isalnum() or code[j] == '_'):
|
while j < n and (code[j].isalnum() or code[j] == '_'):
|
||||||
j += 1
|
j += 1
|
||||||
if token_count >= len(tokens):
|
tokens.append(('IDENTIFIER', code[i:j]))
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('IDENTIFIER', code[i:j])
|
|
||||||
token_count += 1
|
|
||||||
i = j
|
i = j
|
||||||
|
|
||||||
elif char == '|':
|
elif char == '|':
|
||||||
if token_count >= len(tokens):
|
tokens.append(('SEPARATOR', char))
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('SEPARATOR', char)
|
|
||||||
token_count += 1
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
elif char == ':':
|
elif char == ':':
|
||||||
if token_count >= len(tokens):
|
tokens.append(('ASSIGN', char))
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('ASSIGN', char)
|
|
||||||
token_count += 1
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
elif char in operator_chars:
|
elif char in operator_chars:
|
||||||
@@ -267,94 +309,74 @@ class SCLInterpreter:
|
|||||||
j = i
|
j = i
|
||||||
while j < n and code[j] in operator_chars:
|
while j < n and code[j] in operator_chars:
|
||||||
j += 1
|
j += 1
|
||||||
if token_count >= len(tokens):
|
tokens.append(('OPERATOR', code[i:j]))
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('OPERATOR', code[i:j])
|
|
||||||
token_count += 1
|
|
||||||
i = j
|
i = j
|
||||||
|
|
||||||
elif char in paren_chars:
|
elif char in paren_chars:
|
||||||
if token_count >= len(tokens):
|
tokens.append(('PAREN', char))
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('PAREN', char)
|
|
||||||
token_count += 1
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
elif char == '#':
|
elif char == '#' or (char == '/' and i + 1 < n and code[i + 1] == '/'):
|
||||||
# 注释处理
|
# 注释处理
|
||||||
j = i
|
j = i
|
||||||
while j < n and code[j] != '\n':
|
while j < n and code[j] != '\n':
|
||||||
j += 1
|
j += 1
|
||||||
if token_count >= len(tokens):
|
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('COMMENT', code[i:j])
|
|
||||||
token_count += 1
|
|
||||||
i = j
|
|
||||||
|
|
||||||
elif char == '/' and i + 1 < n and code[i + 1] == '/':
|
|
||||||
# 注释处理
|
|
||||||
j = i
|
|
||||||
while j < n and code[j] != '\n':
|
|
||||||
j += 1
|
|
||||||
if token_count >= len(tokens):
|
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('COMMENT', code[i:j])
|
|
||||||
token_count += 1
|
|
||||||
i = j
|
i = j
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if token_count >= len(tokens):
|
tokens.append(('UNKNOWN', char))
|
||||||
tokens.extend([None] * (n // 2))
|
|
||||||
tokens[token_count] = ('UNKNOWN', char)
|
|
||||||
token_count += 1
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# 截断到实际使用的长度
|
|
||||||
result = tokens[:token_count]
|
|
||||||
|
|
||||||
# 缓存结果
|
# 缓存结果
|
||||||
self.token_cache[code_hash] = result
|
self.token_cache[code_hash] = tokens
|
||||||
|
# 管理缓存大小
|
||||||
|
self._manage_cache(self.token_cache)
|
||||||
|
|
||||||
return result
|
return tokens
|
||||||
|
|
||||||
def parse_expression(self, tokens, pos):
|
def parse_expression(self, tokens, pos):
|
||||||
"""Parse an expression from the tokens (optimized with precedence handling)"""
|
"""Parse an expression from the tokens (optimized with precedence handling)"""
|
||||||
# 简单表达式解析器,支持二元运算
|
# 检查缓存
|
||||||
if pos >= len(tokens):
|
cache_key = (tuple(tokens), pos)
|
||||||
return None, pos
|
if cache_key in self.statement_cache:
|
||||||
|
return self.statement_cache[cache_key]
|
||||||
|
|
||||||
# 解析左操作数
|
if pos >= len(tokens):
|
||||||
left, pos = self.parse_primary(tokens, pos)
|
result = (None, pos)
|
||||||
|
self.statement_cache[cache_key] = result
|
||||||
|
return result
|
||||||
|
|
||||||
|
# 递归下降解析器,支持运算符优先级
|
||||||
|
def parse_level(level, pos):
|
||||||
|
if level == 4: # 最高优先级:括号和基本表达式
|
||||||
|
return self.parse_primary(tokens, pos)
|
||||||
|
|
||||||
|
left, pos = parse_level(level + 1, pos)
|
||||||
if left is None:
|
if left is None:
|
||||||
return None, pos
|
return None, pos
|
||||||
|
|
||||||
# 解析运算符和右操作数
|
|
||||||
# 优先级: * / > + -
|
|
||||||
while pos < len(tokens) and tokens[pos][0] == 'OPERATOR':
|
while pos < len(tokens) and tokens[pos][0] == 'OPERATOR':
|
||||||
op = tokens[pos][1]
|
op = tokens[pos][1]
|
||||||
if op not in '+-*/':
|
op_prec = self.operator_precedence.get(op, -1)
|
||||||
|
|
||||||
|
if op_prec != level:
|
||||||
break
|
break
|
||||||
|
|
||||||
# 处理优先级
|
|
||||||
if op in '*/':
|
|
||||||
# 高优先级,直接解析右操作数
|
|
||||||
pos += 1
|
pos += 1
|
||||||
right, pos = self.parse_primary(tokens, pos)
|
right, pos = parse_level(level + 1, pos)
|
||||||
if right is None:
|
|
||||||
return None, pos
|
|
||||||
# 构建二元表达式
|
|
||||||
left = [left, tokens[pos-1], right]
|
|
||||||
else: # op in '+-'
|
|
||||||
# 低优先级,检查下一个运算符
|
|
||||||
pos += 1
|
|
||||||
right, pos = self.parse_primary(tokens, pos)
|
|
||||||
if right is None:
|
if right is None:
|
||||||
return None, pos
|
return None, pos
|
||||||
|
|
||||||
# 构建二元表达式
|
# 构建二元表达式
|
||||||
left = [left, tokens[pos-1], right]
|
left = [left, tokens[pos-1], right]
|
||||||
|
|
||||||
return left, pos
|
return left, pos
|
||||||
|
|
||||||
|
# 从最低优先级开始解析
|
||||||
|
result = parse_level(0, pos)
|
||||||
|
self.statement_cache[cache_key] = result
|
||||||
|
return result
|
||||||
|
|
||||||
def parse_primary(self, tokens, pos):
|
def parse_primary(self, tokens, pos):
|
||||||
"""Parse a primary expression"""
|
"""Parse a primary expression"""
|
||||||
if pos >= len(tokens):
|
if pos >= len(tokens):
|
||||||
@@ -665,26 +687,21 @@ class SCLInterpreter:
|
|||||||
result = 0
|
result = 0
|
||||||
if isinstance(expr, list):
|
if isinstance(expr, list):
|
||||||
if len(expr) == 3 and expr[1][0] == 'OPERATOR':
|
if len(expr) == 3 and expr[1][0] == 'OPERATOR':
|
||||||
|
# 递归评估左右操作数
|
||||||
left = self.evaluate_expression(expr[0])
|
left = self.evaluate_expression(expr[0])
|
||||||
op = expr[1][1]
|
op = expr[1][1]
|
||||||
right = self.evaluate_expression(expr[2])
|
right = self.evaluate_expression(expr[2])
|
||||||
|
|
||||||
# 使用预定义的操作映射
|
# 使用快速操作映射
|
||||||
if op == '+':
|
if op in self.operation_map:
|
||||||
result = str(left) + str(right) if isinstance(left, str) or isinstance(right, str) else left + right
|
result = self.operation_map[op](left, right)
|
||||||
elif op == '-':
|
|
||||||
result = left - right
|
|
||||||
elif op == '*':
|
|
||||||
result = left * right
|
|
||||||
elif op == '/':
|
|
||||||
result = left / right if right != 0 else 0
|
|
||||||
|
|
||||||
elif expr[0] == 'STRING':
|
elif expr[0] == 'STRING':
|
||||||
result = expr[1]
|
result = expr[1]
|
||||||
elif expr[0] == 'NUMBER':
|
elif expr[0] == 'NUMBER':
|
||||||
# 缓存数字转换结果
|
# 快速数字转换
|
||||||
try:
|
|
||||||
num_str = expr[1]
|
num_str = expr[1]
|
||||||
|
try:
|
||||||
if '.' in num_str:
|
if '.' in num_str:
|
||||||
result = float(num_str)
|
result = float(num_str)
|
||||||
else:
|
else:
|
||||||
@@ -700,10 +717,13 @@ class SCLInterpreter:
|
|||||||
args = expr[2]
|
args = expr[2]
|
||||||
|
|
||||||
# 评估参数
|
# 评估参数
|
||||||
evaluated_args = [self.evaluate_expression(arg) for arg in args]
|
evaluated_args = []
|
||||||
|
for arg in args:
|
||||||
|
evaluated_args.append(self.evaluate_expression(arg))
|
||||||
|
|
||||||
# 检查是否有插件处理函数调用
|
# 快速插件查找
|
||||||
for plugin in self.plugins.values():
|
for plugin in self.plugins.values():
|
||||||
|
if hasattr(plugin, 'execute_statement'):
|
||||||
plugin_result = plugin.execute_statement(('FUNCTION_CALL', func_name, evaluated_args))
|
plugin_result = plugin.execute_statement(('FUNCTION_CALL', func_name, evaluated_args))
|
||||||
# 检查结果是否不是布尔值 - 这意味着函数返回了一个值
|
# 检查结果是否不是布尔值 - 这意味着函数返回了一个值
|
||||||
if not isinstance(plugin_result, bool):
|
if not isinstance(plugin_result, bool):
|
||||||
@@ -711,8 +731,9 @@ class SCLInterpreter:
|
|||||||
break
|
break
|
||||||
|
|
||||||
# 缓存结果
|
# 缓存结果
|
||||||
if not isinstance(expr, list) or (len(expr) == 3 and expr[1][0] == 'OPERATOR'):
|
|
||||||
self.expression_cache[expr_key] = result
|
self.expression_cache[expr_key] = result
|
||||||
|
# 管理缓存大小
|
||||||
|
self._manage_cache(self.expression_cache)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -880,59 +901,49 @@ class SCLInterpreter:
|
|||||||
"""Execute the given SCL code (optimized with caching and efficient processing)"""
|
"""Execute the given SCL code (optimized with caching and efficient processing)"""
|
||||||
# 检查缓存
|
# 检查缓存
|
||||||
code_hash = hash(code)
|
code_hash = hash(code)
|
||||||
if code_hash in self.token_cache:
|
if code_hash in self.code_block_cache:
|
||||||
# 直接使用缓存的token结果
|
return self.code_block_cache[code_hash]
|
||||||
pass
|
|
||||||
|
|
||||||
def smart_split(code):
|
def smart_split(code):
|
||||||
"""Optimized line splitting that handles strings correctly"""
|
"""Optimized line splitting that handles strings correctly"""
|
||||||
|
# 快速处理
|
||||||
|
code_len = len(code)
|
||||||
|
if code_len == 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 预分配空间
|
||||||
lines = []
|
lines = []
|
||||||
current_line = []
|
current_line = []
|
||||||
in_string = False
|
in_string = False
|
||||||
|
|
||||||
# 预分配空间,减少列表扩展开销
|
|
||||||
code_len = len(code)
|
|
||||||
current_line = [''] * code_len
|
|
||||||
line_pos = 0
|
|
||||||
|
|
||||||
for char in code:
|
for char in code:
|
||||||
if char == '"':
|
if char == '"':
|
||||||
in_string = not in_string
|
in_string = not in_string
|
||||||
current_line[line_pos] = char
|
current_line.append(char)
|
||||||
line_pos += 1
|
|
||||||
elif char == '\n' and not in_string:
|
elif char == '\n' and not in_string:
|
||||||
lines.append(''.join(current_line[:line_pos]))
|
lines.append(''.join(current_line))
|
||||||
current_line = [''] * code_len
|
current_line = []
|
||||||
line_pos = 0
|
|
||||||
else:
|
else:
|
||||||
current_line[line_pos] = char
|
current_line.append(char)
|
||||||
line_pos += 1
|
|
||||||
|
|
||||||
if line_pos > 0:
|
if current_line:
|
||||||
lines.append(''.join(current_line[:line_pos]))
|
lines.append(''.join(current_line))
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
lines = smart_split(code)
|
lines = smart_split(code)
|
||||||
|
if not lines:
|
||||||
|
self.code_block_cache[code_hash] = True
|
||||||
|
return True
|
||||||
|
|
||||||
# 用于处理多行语句
|
# 用于处理多行语句
|
||||||
multi_line_buffer = []
|
multi_line_buffer = []
|
||||||
in_multi_line = False
|
in_multi_line = False
|
||||||
nested_level = 0 # 用于跟踪嵌套级别
|
nested_level = 0 # 用于跟踪嵌套级别
|
||||||
|
|
||||||
# 预定义常量(使用集合提高查找速度)
|
|
||||||
multi_line_starts = {
|
|
||||||
'sif ', 'swhile :', 'swhile |', 'swhi ', 'srg', 'sdef <', 'sclass <'
|
|
||||||
}
|
|
||||||
|
|
||||||
# 预编译正则表达式,用于快速检查注释和空行
|
|
||||||
import re
|
|
||||||
comment_pattern = re.compile(r'^\s*(#|//)')
|
|
||||||
empty_pattern = re.compile(r'^\s*$')
|
|
||||||
|
|
||||||
for line_num, line in enumerate(lines, 1):
|
for line_num, line in enumerate(lines, 1):
|
||||||
# 快速跳过空行和注释
|
# 快速跳过空行和注释
|
||||||
if empty_pattern.match(line) or comment_pattern.match(line):
|
if self.empty_pattern.match(line) or self.comment_pattern.match(line):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 处理插件导入和SCL文件导入
|
# 处理插件导入和SCL文件导入
|
||||||
@@ -943,19 +954,21 @@ class SCLInterpreter:
|
|||||||
if import_content.startswith('scl :'):
|
if import_content.startswith('scl :'):
|
||||||
scl_path = import_content[5:].strip()
|
scl_path = import_content[5:].strip()
|
||||||
if not self.import_scl_file(scl_path, line_num):
|
if not self.import_scl_file(scl_path, line_num):
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
# 插件导入
|
# 插件导入
|
||||||
if not self.load_plugin(import_content):
|
if not self.load_plugin(import_content):
|
||||||
print(f"Error at line {line_num}: Failed to load plugin {import_content}")
|
print(f"Error at line {line_num}: Failed to load plugin {import_content}")
|
||||||
print(f"Code: {line}")
|
print(f"Code: {line}")
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 检查是否是多行语句的开始
|
# 检查是否是多行语句的开始
|
||||||
is_multi_line_start = False
|
is_multi_line_start = False
|
||||||
for prefix in multi_line_starts:
|
for prefix in self.multi_line_starts:
|
||||||
if line.startswith(prefix):
|
if line.startswith(prefix):
|
||||||
is_multi_line_start = True
|
is_multi_line_start = True
|
||||||
break
|
break
|
||||||
@@ -965,60 +978,36 @@ class SCLInterpreter:
|
|||||||
is_multi_line_start = True
|
is_multi_line_start = True
|
||||||
|
|
||||||
if is_multi_line_start:
|
if is_multi_line_start:
|
||||||
# 打印调试信息
|
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Found multi-line statement start: {line}")
|
|
||||||
multi_line_buffer.append(line)
|
multi_line_buffer.append(line)
|
||||||
if not in_multi_line:
|
if not in_multi_line:
|
||||||
in_multi_line = True
|
in_multi_line = True
|
||||||
nested_level = 1 # 开始一个新的多行语句,嵌套级别为1
|
nested_level = 1 # 开始一个新的多行语句,嵌套级别为1
|
||||||
# 打印调试信息
|
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Started new multi-line statement, nested_level = {nested_level}")
|
|
||||||
else:
|
else:
|
||||||
nested_level += 1 # 遇到新的嵌套语句,嵌套级别加1
|
nested_level += 1 # 遇到新的嵌套语句,嵌套级别加1
|
||||||
# 打印调试信息
|
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Found nested statement, nested_level = {nested_level}")
|
|
||||||
# 检查是否是多行语句的结束
|
# 检查是否是多行语句的结束
|
||||||
elif line == 'end' and in_multi_line:
|
elif line == 'end' and in_multi_line:
|
||||||
# 打印调试信息
|
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Found multi-line statement end: {line}")
|
|
||||||
multi_line_buffer.append(line)
|
multi_line_buffer.append(line)
|
||||||
nested_level -= 1 # 遇到end,嵌套级别减1
|
nested_level -= 1 # 遇到end,嵌套级别减1
|
||||||
# 打印调试信息
|
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Decreased nested_level to {nested_level}")
|
|
||||||
if nested_level == 0:
|
if nested_level == 0:
|
||||||
# 嵌套级别为0,说明是外部语句的结束
|
# 嵌套级别为0,说明是外部语句的结束
|
||||||
in_multi_line = False
|
in_multi_line = False
|
||||||
# 处理完整的多行语句
|
# 处理完整的多行语句
|
||||||
multi_line_code = '\n'.join(multi_line_buffer)
|
multi_line_code = '\n'.join(multi_line_buffer)
|
||||||
multi_line_buffer = []
|
multi_line_buffer = []
|
||||||
# 打印调试信息
|
# 处理多行语句
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Processing complete multi-line statement:\n{multi_line_code}")
|
|
||||||
# 这里我们需要特殊处理多行语句
|
|
||||||
# 简单起见,我们将多行语句作为一个整体进行tokenize和parse
|
|
||||||
# 注意:这种方法可能不是最优的,但是可以解决当前的问题
|
|
||||||
tokens = self.tokenize(multi_line_code)
|
tokens = self.tokenize(multi_line_code)
|
||||||
# 打印调试信息
|
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Tokens: {tokens}")
|
|
||||||
if tokens:
|
if tokens:
|
||||||
stmt, _ = self.parse_statement(tokens, 0)
|
stmt, _ = self.parse_statement(tokens, 0)
|
||||||
# 打印调试信息
|
|
||||||
if self.debug_mode:
|
|
||||||
print(f"Debug: Parsed statement: {stmt}")
|
|
||||||
if stmt:
|
if stmt:
|
||||||
if not self.execute_statement(stmt):
|
if not self.execute_statement(stmt):
|
||||||
print(f"Error at line {line_num}: Failed to execute statement")
|
print(f"Error at line {line_num}: Failed to execute statement")
|
||||||
print(f"Code: {multi_line_code}")
|
print(f"Code: {multi_line_code}")
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print(f"Error at line {line_num}: Invalid syntax")
|
print(f"Error at line {line_num}: Invalid syntax")
|
||||||
print(f"Code: {multi_line_code}")
|
print(f"Code: {multi_line_code}")
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
# 处理多行语句的中间部分
|
# 处理多行语句的中间部分
|
||||||
elif in_multi_line:
|
elif in_multi_line:
|
||||||
@@ -1036,24 +1025,33 @@ class SCLInterpreter:
|
|||||||
if not self.execute_statement(stmt):
|
if not self.execute_statement(stmt):
|
||||||
print(f"Error at line {line_num}: Failed to execute statement")
|
print(f"Error at line {line_num}: Failed to execute statement")
|
||||||
print(f"Code: {line}")
|
print(f"Code: {line}")
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print(f"Error at line {line_num}: Invalid syntax")
|
print(f"Error at line {line_num}: Invalid syntax")
|
||||||
print(f"Code: {line}")
|
print(f"Code: {line}")
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error at line {line_num}: {e}")
|
print(f"Error at line {line_num}: {e}")
|
||||||
print(f"Code: {line}")
|
print(f"Code: {line}")
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 检查是否有未完成的多行语句
|
# 检查是否有未完成的多行语句
|
||||||
if in_multi_line:
|
if in_multi_line:
|
||||||
print(f"Error at line {line_num}: Unclosed multi-line statement")
|
print(f"Error at line {line_num}: Unclosed multi-line statement")
|
||||||
print(f"Code: {''.join(multi_line_buffer)}")
|
print(f"Code: {''.join(multi_line_buffer)}")
|
||||||
|
self.code_block_cache[code_hash] = False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# 缓存结果
|
||||||
|
self.code_block_cache[code_hash] = True
|
||||||
|
# 管理缓存大小
|
||||||
|
self._manage_cache(self.code_block_cache)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def nano_editor(file_path=None):
|
def nano_editor(file_path=None):
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户