c++解释器修改

This commit is contained in:
sxg
2026-08-31 10:24:13 +08:00
parent a699896116
commit 74b983c74e

View File

@@ -821,8 +821,8 @@ export class CppCodeExecutor {
statements.push(whileLoop);
i = whileLoop.endIndex;
} else {
// 检查是否是break或continue语句
if (line === 'break;' || line === 'continue;') {
// 检查是否是break或continue或return语句
if (line === 'break;' || line === 'continue;' || line.startsWith('return')) {
statements.push({
type: 'control',
subtype: line === 'break;' ? 'break' : 'continue',
@@ -866,21 +866,27 @@ export class CppCodeExecutor {
let braceCount = 0;
let bodyStart = startIndex + 1;
let bodyEnd = startIndex + 1;
let hasBrace = false;
for (let i = startIndex; i < lines.length; i++) {
const line = lines[i];
debugLog(`🔍 检查行 ${i}: "${line.trim()}" (大括号计数: ${braceCount})`);
if (line.includes('{')) braceCount++;
if (line.includes('{')) { braceCount++; hasBrace = true; }
if (line.includes('}')) braceCount--;
if (braceCount === 0 && i > startIndex) {
if (hasBrace && braceCount === 0 && i > startIndex) {
bodyEnd = i;
debugLog(`🔍 找到循环体结束位置: ${bodyEnd}`);
break;
}
if (!hasBrace && i > startIndex && line.trim() && !line.trim().startsWith('//')) {
bodyEnd = i + 1;
debugLog(`🔍 找到无大括号循环体结束位置: ${bodyEnd}`);
break;
}
}
// 如果没有找到结束大括号,可能是格式问题
if (bodyEnd === startIndex + 1) {
if (hasBrace && bodyEnd === startIndex + 1) {
debugLog(`⚠️ 警告:没有找到循环体结束大括号,检查代码格式`);
debugLog(`⚠️ 当前所有行内容:`);
lines.forEach((line, index) => {
@@ -914,7 +920,7 @@ export class CppCodeExecutor {
increment,
body: bodyStatements,
lineNumber: isMainFunction ? this.getActualLineNumber(startIndex) : startIndex + 1,
endIndex: bodyEnd + 1
endIndex: hasBrace ? bodyEnd + 1 : bodyEnd
};
}
@@ -935,11 +941,26 @@ export class CppCodeExecutor {
const condition = ifMatch[1];
// 最小化修改如果if同行包含执行语句把它拆分拆到下一行
const afterIf = ifLine.substring(ifMatch.index + ifMatch[0].length).trim();
if (afterIf && afterIf !== '{') {
if (afterIf.startsWith('{')) {
lines[startIndex] = ifLine.substring(0, ifLine.lastIndexOf(afterIf)) + '{';
const afterBrace = afterIf.substring(1).trim();
if (afterBrace) lines.splice(startIndex + 1, 0, afterBrace);
} else {
lines[startIndex] = ifLine.substring(0, ifLine.lastIndexOf(afterIf)).trim();
lines.splice(startIndex + 1, 0, afterIf);
}
}
// 找到if语句体
let braceCount = 0;
let bodyStart = startIndex + 1;
let bodyEnd = startIndex + 1;
let ifClosingLine = ''; // 保存if语句的结束行可能包含else
let hasBrace = false;
for (let i = startIndex; i < lines.length; i++) {
const line = lines[i];
@@ -954,15 +975,31 @@ export class CppCodeExecutor {
break;
}
if (line.includes('{')) braceCount++;
if (line.includes('{')) { braceCount++; hasBrace = true; }
if (line.includes('}')) braceCount--;
if (braceCount === 0 && i > startIndex) {
if (hasBrace && braceCount === 0 && i > startIndex) {
// 普通的}结束
bodyEnd = i;
ifClosingLine = trimmedLine;
debugLog(`🔍 if语句结束位置: 行${i}, 内容: "${ifClosingLine}", 是否包含else: ${ifClosingLine.includes('else')}`);
break;
}
if (!hasBrace && i > startIndex && trimmedLine && !trimmedLine.startsWith('//')) {
bodyEnd = i + 1;
// 尝试寻找后续的else
for (let j = i + 1; j < lines.length; j++) {
const nextLine = lines[j].trim();
if (!nextLine || nextLine.startsWith('//')) continue;
if (nextLine.startsWith('else')) {
ifClosingLine = nextLine;
debugLog(`🔍 无大括号单行语句后发现else: 行${j}, 内容: "${ifClosingLine}"`);
}
break;
}
break;
}
}
let bodyLines = lines.slice(bodyStart, bodyEnd);
@@ -984,7 +1021,7 @@ export class CppCodeExecutor {
// 解析else if 和 else 分支
const elseIfBranches = [];
let elseStatements = [];
let currentIndex = bodyEnd + 1;
let currentIndex = hasBrace ? bodyEnd + 1 : bodyEnd;
// 首先检查if结束行是否包含else处理 } else { 的情况)
if (ifClosingLine.includes('else')) {
@@ -1110,15 +1147,20 @@ export class CppCodeExecutor {
let elseIfBraceCount = 0;
let elseIfBodyStart = currentIndex + 1;
let elseIfBodyEnd = currentIndex + 1;
let elseIfHasBrace = false;
for (let i = currentIndex; i < lines.length; i++) {
const line = lines[i];
if (line.includes('{')) elseIfBraceCount++;
if (line.includes('{')) { elseIfBraceCount++; elseIfHasBrace = true; }
if (line.includes('}')) elseIfBraceCount--;
if (elseIfBraceCount === 0 && i > currentIndex) {
if (elseIfHasBrace && elseIfBraceCount === 0 && i > currentIndex) {
elseIfBodyEnd = i;
break;
}
if (!elseIfHasBrace && i > currentIndex && line.trim() && !line.trim().startsWith('//')) {
elseIfBodyEnd = i + 1;
break;
}
}
const elseIfBodyLines = lines.slice(elseIfBodyStart, elseIfBodyEnd);
@@ -1131,7 +1173,7 @@ export class CppCodeExecutor {
debugLog(`🔍 解析else if语句体条件: ${elseIfCondition}, 行数: ${elseIfBodyLines.length}, 语句数: ${elseIfStatements.length}`);
currentIndex = elseIfBodyEnd + 1;
currentIndex = elseIfHasBrace ? elseIfBodyEnd + 1 : elseIfBodyEnd;
continue;
}
@@ -1143,15 +1185,20 @@ export class CppCodeExecutor {
let elseBraceCount = 0;
let elseBodyStart = currentIndex + 1;
let elseBodyEnd = currentIndex + 1;
let elseHasBrace = false;
for (let i = currentIndex; i < lines.length; i++) {
const line = lines[i];
if (line.includes('{')) elseBraceCount++;
if (line.includes('{')) { elseBraceCount++; elseHasBrace = true; }
if (line.includes('}')) elseBraceCount--;
if (elseBraceCount === 0 && i > currentIndex) {
if (elseHasBrace && elseBraceCount === 0 && i > currentIndex) {
elseBodyEnd = i;
break;
}
if (!elseHasBrace && i > currentIndex && line.trim() && !line.trim().startsWith('//')) {
elseBodyEnd = i + 1;
break;
}
}
let elseBodyLines = lines.slice(elseBodyStart, elseBodyEnd);
@@ -1173,7 +1220,7 @@ export class CppCodeExecutor {
debugLog(`🔍 解析else语句体行数: ${elseBodyLines.length}, 语句数: ${elseStatements.length}`);
currentIndex = elseBodyEnd + 1;
currentIndex = elseHasBrace ? elseBodyEnd + 1 : elseBodyEnd;
break; // else分支是最后一个不再继续
}
@@ -1208,15 +1255,20 @@ export class CppCodeExecutor {
let braceCount = 0;
let bodyStart = startIndex + 1;
let bodyEnd = startIndex + 1;
let hasBrace = false;
for (let i = startIndex; i < lines.length; i++) {
const line = lines[i];
if (line.includes('{')) braceCount++;
if (line.includes('{')) { braceCount++; hasBrace = true; }
if (line.includes('}')) braceCount--;
if (braceCount === 0 && i > startIndex) {
if (hasBrace && braceCount === 0 && i > startIndex) {
bodyEnd = i;
break;
}
if (!hasBrace && i > startIndex && line.trim() && !line.trim().startsWith('//')) {
bodyEnd = i + 1;
break;
}
}
let bodyLines = lines.slice(bodyStart, bodyEnd);
@@ -1239,7 +1291,7 @@ export class CppCodeExecutor {
condition,
body: bodyStatements,
lineNumber: isMainFunction ? this.getActualLineNumber(startIndex) : startIndex + 1,
endIndex: bodyEnd + 1
endIndex: hasBrace ? bodyEnd + 1 : bodyEnd
};
}
@@ -1259,7 +1311,7 @@ export class CppCodeExecutor {
// 高亮当前执行行
if (this.setHighlightedLine) {
// this.setHighlightedLine(statement.lineNumber);
this.setHighlightedLine(statement.lineNumber);
}
await new Promise(resolve => setTimeout(resolve, 0));
@@ -1282,6 +1334,9 @@ export class CppCodeExecutor {
await this.executeFunctionCall(statement);
break;
case 'control':
if (statement.content.startsWith('return')) {
throw new Error('RETURN_INTERRUPT');
}
// break和continue在各自的循环中处理这里只记录
debugLog(`🔄 控制语句: ${statement.subtype}`);
break;
@@ -1792,8 +1847,12 @@ export class CppCodeExecutor {
});
try {
// 创建函数作用域(保存当前变量状态)
const savedVariables = new Map(this.variables);
// 最小改动:防递归数据污染,只备份会被覆盖的同名参数变量
const savedParams = new Map();
for (let i = 0; i < functionInfo.parameters.length; i++) {
const pName = functionInfo.parameters[i].name;
if (this.variables.has(pName)) savedParams.set(pName, this.variables.get(pName));
}
// 设置函数参数变量
for (let i = 0; i < functionInfo.parameters.length; i++) {
@@ -1808,32 +1867,42 @@ export class CppCodeExecutor {
}
// 执行函数体中的所有语句
for (const functionStatement of functionInfo.body) {
if (this.shouldStop()) break;
// 使用预先计算好的精确行号,如果没有则计算行号
let adjustedStatement;
if (functionStatement.exactLineNumber) {
adjustedStatement = {
...functionStatement,
lineNumber: functionStatement.exactLineNumber
};
console.log(`🎯 使用函数内精确行号: "${functionStatement.content}" -> 第${functionStatement.exactLineNumber}行 (函数: ${functionName})`);
} else {
// 需要更精确地计算函数内语句的实际行号
const actualLineNumber = this.calculateActualLineNumber(functionName, functionStatement);
adjustedStatement = {
...functionStatement,
lineNumber: actualLineNumber
};
try {
for (const functionStatement of functionInfo.body) {
if (this.shouldStop()) break;
// 使用预先计算好的精确行号,如果没有则计算行号
let adjustedStatement;
if (functionStatement.exactLineNumber) {
adjustedStatement = {
...functionStatement,
lineNumber: functionStatement.exactLineNumber
};
console.log(`🎯 使用函数内精确行号: "${functionStatement.content}" -> 第${functionStatement.exactLineNumber}行 (函数: ${functionName})`);
} else {
// 需要更精确地计算函数内语句的实际行号
const actualLineNumber = this.calculateActualLineNumber(functionName, functionStatement);
adjustedStatement = {
...functionStatement,
lineNumber: actualLineNumber
};
}
await this.executeStatement(adjustedStatement);
}
await this.executeStatement(adjustedStatement);
} catch (e) {
if (e.message !== 'RETURN_INTERRUPT') throw e;
}
// 恢复函数调用前的变量状态(简单的作用域实现)
// 注意这是简化版本实际C++的作用域更复杂
this.variables = savedVariables;
// 最小改动:仅恢复递归调用前的参数状态,保留全局变量的修改
for (let i = 0; i < functionInfo.parameters.length; i++) {
const pName = functionInfo.parameters[i].name;
if (savedParams.has(pName)) {
this.variables.set(pName, savedParams.get(pName));
} else {
this.variables.delete(pName);
}
}
console.log(`✅ 函数${functionName}执行完成`);
@@ -2332,28 +2401,10 @@ export class CppCodeExecutor {
// 处理一元运算符(负号)
expr = this.handleUnaryOperators(expr);
// 按运算优先级解析:乘法、除法和模运算优先
if (expr.includes('*') || expr.includes('/') || expr.includes('%')) {
return this.parseMultiplicationDivision(expr);
}
// 然后处理加法和减法
if (expr.includes('+') || expr.includes('-')) {
return this.parseAdditionSubtraction(expr);
}
// 如果是单个值
if (/^-?\d+$/.test(expr)) {
return parseInt(expr);
}
// 变量查找
if (this.variables.has(expr)) {
return this.variables.get(expr);
}
debugLog(`⚠️ 无法识别的表达式: ${expr}, 返回默认值 0`);
return 0;
// 按正确的运算优先级解析:
// 加法和减法是最低优先级,因此在此处最先切分。
// 切分后的每一项将交给 parseAdditionSubtraction在其中处理更高级别的乘除法。
return this.parseAdditionSubtraction(expr);
} catch (error) {
debugLog(`⚠️ 表达式解析错误: ${expr}, 错误: ${error.message}`);
@@ -2490,20 +2541,49 @@ export class CppCodeExecutor {
// 计算单个标记的值
evaluateToken(token) {
token = token.trim();
if (!token) return 0;
// 如果包含乘除法或模运算,交给乘除法解析器处理
if (token.includes('*') || token.includes('/') || token.includes('%')) {
return this.parseMultiplicationDivision(token);
}
// 布尔常量
if (token === 'true') return 1;
if (token === 'false') return 0;
// 数字
if (/^-?\d+$/.test(token)) {
return parseInt(token);
}
// 变量
// 变量查找
if (this.variables.has(token)) {
return this.variables.get(token);
}
// 如果包含乘除法或模运算,递归处理
if (token.includes('*') || token.includes('/') || token.includes('%')) {
return this.parseMultiplicationDivision(token);
// 对象属性访问 (如 pos.x, pos.y, pos.z)
if (token.includes('.')) {
const [objName, propName] = token.split('.');
if (this.variables.has(objName)) {
const obj = this.variables.get(objName);
if (obj && typeof obj === 'object' && obj[propName] !== undefined) {
return obj[propName];
}
}
}
// 游戏API调用
if (token.includes('player_data(')) {
const match = token.match(/player_data\s*\(\s*"(.+?)"\s*\)/);
if (match) return window.cppGameAPI.player_data(match[1]);
}
if (token.includes('player_position(')) {
const match = token.match(/player_position\s*\(\s*"(.+?)"\s*\)/);
if (match) return window.cppGameAPI.player_position(match[1]);
}
if (token.includes('vehicle_position()')) {
return window.cppGameAPI.vehicle_position();
}
debugLog(`⚠️ 无法解析标记: ${token}`);