UNPKG

python2igcse

Version:

Convert Python code to IGCSE Pseudocode format

290 lines 8.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseParser = void 0; // Base parser class const ir_1 = require("../types/ir"); const parser_1 = require("../types/parser"); /** * Base parser class * Provides common parsing functionality */ class BaseParser { constructor(options = {}) { this.startTime = 0; this.options = this.getDefaultOptions(options); this.context = this.createInitialContext(); } /** * Get default options */ getDefaultOptions(options) { return { debug: options.debug ?? false, strictTypes: options.strictTypes ?? true, strictMode: options.strictMode ?? false, preserveComments: options.preserveComments ?? true, includeComments: options.includeComments ?? true, preserveWhitespace: options.preserveWhitespace ?? false, indentSize: options.indentSize ?? 3, maxDepth: options.maxDepth ?? 50, maxNestingDepth: options.maxNestingDepth ?? 50, maxErrors: options.maxErrors ?? 100, timeout: options.timeout ?? 30000, allowExperimentalSyntax: options.allowExperimentalSyntax ?? false, }; } /** * Create initial context */ createInitialContext() { const globalScope = { name: 'global', variables: new Map(), functions: new Map(), type: 'global', }; const context = { currentScope: globalScope, scopeStack: [globalScope], indentLevel: 0, errors: [], warnings: [], arrayInfo: {}, parameterMapping: {}, startTime: Date.now(), isClass: (name) => { return !!(context.classDefinitions && context.classDefinitions[name] !== undefined); }, }; return context; } /** * Add error */ addError(message, type, line, column) { const error = (0, parser_1.createParseError)(message, type, line, column); this.context.errors.push(error); if (this.options.debug) { console.error(`Parse Error: ${message} at line ${line}:${column}`); } } /** * Add warning */ addWarning(message, type, line, column) { const warning = (0, parser_1.createParseWarning)(message, type, line, column); this.context.warnings.push(warning); if (this.options.debug) { console.warn(`Parse Warning: ${message} at line ${line}:${column}`); } } /** * Start new scope */ enterScope(name, type) { const newScope = { name, parent: this.context.currentScope, variables: new Map(), functions: new Map(), type, }; this.context.scopeStack.push(newScope); this.context.currentScope = newScope; } /** * End scope */ exitScope() { if (this.context.scopeStack.length > 1) { this.context.scopeStack.pop(); this.context.currentScope = this.context.scopeStack[this.context.scopeStack.length - 1]; } } /** * Get current loop type */ getCurrentLoopType() { // Search scope stack in reverse order and return first found loop scope for (let i = this.context.scopeStack.length - 1; i >= 0; i--) { const scope = this.context.scopeStack[i]; if (scope.type === 'while' || scope.type === 'for') { return scope.type; } } return null; } /** * Register variable */ registerVariable(name, type, line) { const variable = { name, type, scope: this.context.currentScope.name, initialized: false, definedAt: line, }; this.context.currentScope.variables.set(name, variable); } /** * Register function */ registerFunction(name, parameters, returnType, line) { const func = { name, parameters, returnType, isFunction: returnType !== undefined, hasReturn: returnType !== undefined, definedAt: line, }; this.context.currentScope.functions.set(name, func); this.context.currentFunction = func; } /** * Find variable */ findVariable(name) { // Search from current scope to parent scopes in order let scope = this.context.currentScope; while (scope) { const variable = scope.variables.get(name); if (variable) { return variable; } scope = scope.parent; } return undefined; } /** * 関数の検索 */ findFunction(name) { // Search from current scope to parent scopes in order let scope = this.context.currentScope; while (scope) { const func = scope.functions.get(name); if (func) { return func; } scope = scope.parent; } return undefined; } /** * クラスの登録 */ registerClass(name, line) { // クラス情報を現在のスコープに登録 // 実装は簡略化し、デバッグ出力のみ if (this.options.debug) { console.log(`Registering class: ${name} at line ${line}`); } } /** * インデントレベルの増加 */ increaseIndent() { this.context.indentLevel++; if (this.context.indentLevel > this.options.maxDepth) { this.addError(`Maximum nesting depth (${this.options.maxDepth}) exceeded`, 'validation_error'); } } /** * インデントレベルの減少 */ decreaseIndent() { if (this.context.indentLevel > 0) { this.context.indentLevel--; } } /** * IRノードの作成(ヘルパー) */ createIRNode(kind, text, children = [], meta) { return (0, ir_1.createIR)(kind, text, children, meta); } /** * パース結果の作成 */ createParseResult(ir) { const endTime = Date.now(); const parseTime = endTime - this.startTime; return { ir, errors: [...this.context.errors], warnings: [...this.context.warnings], stats: { linesProcessed: 0, // 実装時に設定 nodesGenerated: ir.reduce((sum, node) => sum + this.countNodes(node), 0), parseTime, functionsFound: this.countFunctions(), classesFound: this.context.classDefinitions ? Object.keys(this.context.classDefinitions).length : 0, variablesFound: this.countVariables(), }, success: this.context.errors.length === 0, parseTime, }; } /** * IRノード数のカウント */ countNodes(ir) { return 1 + ir.children.reduce((sum, child) => sum + this.countNodes(child), 0); } /** * 関数数のカウント */ countFunctions() { let count = 0; for (const scope of this.context.scopeStack) { count += scope.functions.size; } return count; } /** * 変数数のカウント */ countVariables() { let count = 0; for (const scope of this.context.scopeStack) { count += scope.variables.size; } return count; } /** * パースの開始時刻を記録 */ startParsing() { this.startTime = Date.now(); } /** * デバッグ情報の出力 */ debug(_message) { // Debug logging disabled } /** * コンテキストのリセット */ resetContext() { this.context = this.createInitialContext(); } /** * エラーの取得 */ getErrors() { return this.context.errors; } /** * 警告の取得 */ getWarnings() { return this.context.warnings; } } exports.BaseParser = BaseParser; //# sourceMappingURL=base-parser.js.map