UNPKG

python2igcse

Version:

Convert Python code to IGCSE Pseudocode format

369 lines 13.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Converter = void 0; exports.convertPythonToIGCSE = convertPythonToIGCSE; exports.convertFileToIGCSE = convertFileToIGCSE; exports.convertFilesToIGCSE = convertFilesToIGCSE; // Python to IGCSE Pseudocode Converter const parser_1 = require("./parser"); const emitter_1 = require("./emitter"); /** * Python to IGCSE Pseudocode Converter */ class Converter { constructor(options = {}) { this.options = this.mergeDefaultOptions(options); // パーサーの初期化 const parserOptions = { strictMode: this.options.strictMode ?? false, includeComments: this.options.includeComments ?? true, preserveWhitespace: this.options.preserveWhitespace ?? false, maxErrors: this.options.maxErrors ?? 100, timeout: this.options.timeout ?? 30000 }; this.parser = new parser_1.PythonParser(parserOptions); // エミッターの初期化 const emitterOptions = { format: this.options.outputFormat ?? 'plain', indentSize: this.options.indentSize ?? 2, indentChar: ' ', indentType: this.options.indentType ?? 'spaces', lineEnding: this.options.lineEnding ?? '\n', maxLineLength: this.options.maxLineLength ?? 80, beautify: this.options.beautify ?? true, includeComments: this.options.includeComments ?? true, includeLineNumbers: this.options.includeLineNumbers ?? false, includeDebugInfo: false }; this.textEmitter = new emitter_1.TextEmitter(emitterOptions); this.markdownEmitter = new emitter_1.MarkdownEmitter({ ...emitterOptions, format: 'markdown' }); } /** * Python コードを IGCSE Pseudocode に変換 */ convert(pythonCode) { const startTime = Date.now(); try { // パース処理 const parseResult = this.parser.parse(pythonCode); if (parseResult.errors.length > 0 && this.options.strictMode) { return this.createErrorResult('Parse errors occurred in strict mode', parseResult.errors, parseResult.warnings, startTime); } // エミット処理 const emitter = this.options.outputFormat === 'markdown' ? this.markdownEmitter : this.textEmitter; // すべてのIRノードを処理するため、compound IRを作成 const compoundIR = { kind: 'compound', text: '', children: parseResult.ir }; const emitResult = emitter.emit(compoundIR); // 結果の作成 const endTime = Date.now(); const stats = this.createConversionStats(parseResult, emitResult, startTime, endTime); const result = { code: emitResult.code, parseResult, emitResult, stats, ast: parseResult.ir, ir: Array.isArray(parseResult.ir) ? parseResult.ir : [parseResult.ir] }; return result; } catch (error) { const errorResult = this.createErrorResult(error instanceof Error ? error.message : 'Unknown error occurred', [], [], startTime); return errorResult; } } /** * バッチ変換(複数ファイル) */ async convertBatch(files) { const results = []; for (const file of files) { try { const result = await this.convert(file.content); results.push({ name: file.name, result }); } catch (error) { const errorResult = { code: '', parseResult: { ir: [{ kind: 'comment', text: '', children: [] }], errors: [{ message: error instanceof Error ? error.message : 'Unknown error', type: 'syntax_error', line: 1, column: 1, severity: 'error' }], warnings: [], stats: { parseTime: 0, linesProcessed: 0, nodesGenerated: 0, functionsFound: 0, classesFound: 0, variablesFound: 0 } }, emitResult: { code: '', errors: [], warnings: [], stats: { emitTime: 0, linesGenerated: 0, lineCount: 0, charactersGenerated: 0, characterCount: 0, nodesProcessed: 0, processingTime: 0, maxNestingDepth: 0, maxLineLength: 0 } }, stats: { parseTime: 0, emitTime: 0, conversionTime: 0, inputLines: 0, outputLines: 0, errorCount: 1, warningCount: 0 } }; results.push({ name: file.name, result: errorResult }); } } return results; } /** * 変換オプションの更新 */ updateOptions(newOptions) { this.options = this.mergeDefaultOptions({ ...this.options, ...newOptions }); // パーサーオプションの更新(必要に応じて実装) // エミッターオプションの更新 const emitterOptions = { format: this.options.outputFormat ?? 'plain', indentSize: this.options.indentSize ?? 2, indentChar: ' ', indentType: this.options.indentType ?? 'spaces', lineEnding: this.options.lineEnding ?? '\n', maxLineLength: this.options.maxLineLength ?? 80, beautify: this.options.beautify ?? true, includeComments: this.options.includeComments ?? true, includeLineNumbers: this.options.includeLineNumbers ?? false, includeDebugInfo: false }; this.textEmitter.updateOptions(emitterOptions); this.markdownEmitter.updateOptions({ ...emitterOptions, format: 'markdown' }); } /** * 現在のオプションを取得 */ getOptions() { return { ...this.options }; } /** * 変換統計の取得 */ getStats() { // 実装では統計を追跡する必要がある // 現在は仮の値を返す return { totalConversions: 0, successfulConversions: 0, averageParseTime: 0, averageEmitTime: 0, averageTotalTime: 0 }; } /** * IRの検証 */ validateIR(ir) { const errors = []; const warnings = []; // 基本的な検証 if (!ir.kind) { errors.push('IR node missing kind property'); } if (!ir.children) { errors.push('IR node missing children property'); } // 再帰的な検証 for (const child of ir.children || []) { const childValidation = this.validateIR(child); errors.push(...childValidation.errors); warnings.push(...childValidation.warnings); } return { isValid: errors.length === 0, errors, warnings }; } /** * デフォルトオプションとのマージ */ mergeDefaultOptions(options) { const defaults = { outputFormat: 'plain', indentSize: 2, indentType: 'spaces', lineEnding: '\n', maxLineLength: 80, beautify: true, strictMode: false, includeComments: true, includeLineNumbers: false, preserveWhitespace: false, uppercaseKeywords: true, spaceAroundOperators: true, spaceAfterCommas: true, maxErrors: 10, timeout: 30000 }; return { ...defaults, ...options }; } /** * エラー結果の作成 */ createErrorResult(message, parseErrors, parseWarnings, startTime) { const endTime = Date.now(); return { code: '', parseResult: { ir: [{ kind: 'comment', text: '', children: [] }], errors: [ { type: 'conversion', severity: 'error', message, location: { line: 1, column: 1 } }, ...parseErrors ], warnings: parseWarnings, stats: { parseTime: 0, linesProcessed: 0, nodesGenerated: 0, functionsFound: 0, classesFound: 0, variablesFound: 0 } }, emitResult: { code: '', errors: [], warnings: [], stats: { emitTime: 0, linesGenerated: 0, lineCount: 0, charactersGenerated: 0, characterCount: 0, nodesProcessed: 0, processingTime: 0, maxNestingDepth: 0, maxLineLength: 0 } }, stats: { parseTime: 0, emitTime: 0, conversionTime: endTime - startTime, inputLines: 0, outputLines: 0, errorCount: parseErrors.length + 1, warningCount: parseWarnings.length }, ast: undefined }; } /** * 変換統計の作成 */ createConversionStats(parseResult, emitResult, startTime, endTime) { return { parseTime: parseResult.stats.parseTime, emitTime: emitResult.stats.emitTime, conversionTime: endTime - startTime, inputLines: parseResult.stats.linesProcessed, outputLines: emitResult.stats.linesGenerated, errorCount: parseResult.errors.length, warningCount: parseResult.warnings.length }; } } exports.Converter = Converter; /** * 便利な関数:簡単な変換 */ async function convertPythonToIGCSE(pythonCode, options = {}) { const converter = new Converter(options); return converter.convert(pythonCode); } /** * 便利な関数:ファイルからの変換 */ async function convertFileToIGCSE(filePath, options = {}) { const fs = await Promise.resolve().then(() => __importStar(require('fs/promises'))); const pythonCode = await fs.readFile(filePath, 'utf-8'); return convertPythonToIGCSE(pythonCode, options); } /** * 便利な関数:複数ファイルの変換 */ async function convertFilesToIGCSE(filePaths, options = {}) { const converter = new Converter(options); const fs = await Promise.resolve().then(() => __importStar(require('fs/promises'))); const files = await Promise.all(filePaths.map(async (filePath) => { const content = await fs.readFile(filePath, 'utf-8'); return { name: filePath, content }; })); return converter.convertBatch(files); } //# sourceMappingURL=converter.js.map