c++bug修复
This commit is contained in:
71
scratch-gui/scripts/diagnose-cpp.cjs
Normal file
71
scratch-gui/scripts/diagnose-cpp.cjs
Normal file
@@ -0,0 +1,71 @@
|
||||
// Read-only diagnostic: exercise the current editor interpreter with mocked game APIs.
|
||||
// Run from scratch-gui: node scripts/diagnose-cpp.cjs
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
const babel = require('@babel/core');
|
||||
const filename = path.resolve(__dirname, '../src/components/stage-cpp/cpp-parser.js');
|
||||
const transformed = babel.transformSync(fs.readFileSync(filename, 'utf8'), {
|
||||
filename, configFile: false, babelrc: false,
|
||||
plugins: ['@babel/plugin-transform-modules-commonjs']
|
||||
}).code;
|
||||
const context = {
|
||||
exports: {}, require, setTimeout,
|
||||
console: {log() {}, warn() {}, error() {}}, window: {}
|
||||
};
|
||||
vm.runInNewContext(transformed, context, {filename});
|
||||
const {CppCodeExecutor, validateCppSyntax} = context.exports;
|
||||
const main = body => `int main() {\n${body}\n}`;
|
||||
const customer = `void test() {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
}
|
||||
}
|
||||
int main() {
|
||||
turnLeft(-1);
|
||||
for (int i = 0; i < 1; i++) {
|
||||
test();
|
||||
playerMove(i);
|
||||
}
|
||||
}`;
|
||||
const cases = [
|
||||
['customer_local_i', customer, {moves: [0]}],
|
||||
['customer_renamed_inner_j', customer.replace('int i = 0; i < 2; i++', 'int j = 0; j < 2; j++'), {moves: [0]}],
|
||||
['cout_literal', main('cout << "Hello" << endl;'), {output: ['Hello\n']}],
|
||||
['cout_variable', main('int i = 7;\ncout << "i=" << i << endl;'), {output: ['i=7\n']}],
|
||||
['cout_string_assignment_shape', main('cout << "value=42" << endl;'), {output: ['value=42\n']}],
|
||||
['cout_increment_expression', main('int i = 0;\ncout << i++ << endl;\nplayerMove(i);'), {output: ['0\n'], moves: [1]}],
|
||||
['cout_increment_literal', main('cout << "C++" << endl;'), {output: ['C++\n']}],
|
||||
['cout_std_qualified', main('std::cout << "Hello" << std::endl;'), {output: ['Hello\n']}],
|
||||
['main_return_zero', main('return 0;'), {error: null}],
|
||||
['legal_space_before_call', main('playerMove (1);'), {valid: true, moves: [1]}],
|
||||
['nested_loop_shadowing', main('for (int i = 0; i < 2; i++) {\nfor (int i = 0; i < 2; i++) {\n}\nplayerMove(i);\n}'), {moves: [0, 1]}],
|
||||
['negative_integer_division', main('int a = -3;\na /= 2;\nplayerMove(a);'), {moves: [-1]}],
|
||||
['function_return_value', 'int answer() {\nreturn 7;\n}\n' + main('int n = answer();\nplayerMove(n);'), {moves: [7]}],
|
||||
['nested_if_break', main('for (int i = 0; i < 3; i++) {\nif (i == 1) {\nbreak;\n}\nplayerMove(i);\n}'), {moves: [0]}],
|
||||
['floating_point', main('double x = 1.5;\ncout << x << endl;'), {output: ['1.5\n']}],
|
||||
['array_index', main('int a[2] = {3, 7};\nplayerMove(a[1]);'), {moves: [7]}],
|
||||
['unknown_variable', main('playerMove(missing);'), {valid: false}],
|
||||
['early_return_zero', 'int stop() {\nreturn 0;\nplayerMove(9);\n}\n' + main('stop();'), {moves: []}]
|
||||
];
|
||||
(async () => {
|
||||
const results = [];
|
||||
for (const [name, code, expected] of cases) {
|
||||
const actual = {valid: false, moves: [], turns: [], output: [], error: null};
|
||||
context.window = {isScriptRunOver: false, cppGameAPI: {
|
||||
playerMove: async n => actual.moves.push(n),
|
||||
turnLeft: async n => actual.turns.push(n),
|
||||
cmdPrint: text => actual.output.push(text)
|
||||
}};
|
||||
const validation = await validateCppSyntax(code);
|
||||
actual.valid = validation.isValid;
|
||||
if (!actual.valid) actual.validationErrors = validation.errors;
|
||||
const executor = new CppCodeExecutor(code, null);
|
||||
if (actual.valid) {
|
||||
try { await executor.run(); } catch (error) {actual.error = error.message;}
|
||||
}
|
||||
const matchesExpected = Object.entries(expected).every(([key, value]) =>
|
||||
JSON.stringify(actual[key]) === JSON.stringify(value));
|
||||
results.push({name, expected, actual, matchesExpected});
|
||||
}
|
||||
process.stdout.write(JSON.stringify(results, null, 2) + '\n');
|
||||
})().catch(error => {console.error(error); process.exitCode = 1;});
|
||||
Reference in New Issue
Block a user