zignet
Version:
MCP server for Zig — AI-powered code analysis, validation, and documentation with fine-tuned LLM
1 lines • 32.7 kB
Source Map (JSON)
{"version":3,"file":"type-checker.cjs","names":["parent?: Scope","line?: number","column?: number","varType: Type"],"sources":["../src/type-checker.ts"],"sourcesContent":["/**\n * Type Checker for ZigNet\n * Performs semantic analysis and type validation on the AST\n */\n\nimport type {\n Program,\n Declaration,\n FunctionDeclaration,\n VariableDeclaration,\n StructDeclaration,\n Statement,\n BlockStatement,\n ReturnStatement,\n IfStatement,\n WhileStatement,\n ExpressionStatement,\n Expression,\n BinaryExpression,\n UnaryExpression,\n CallExpression,\n MemberExpression,\n IndexExpression,\n AssignmentExpression,\n Identifier,\n TypeAnnotation,\n PrimitiveType,\n IdentifierType,\n} from './ast.js';\n\n/**\n * Type information\n */\nexport interface Type {\n kind: 'primitive' | 'struct' | 'function' | 'void' | 'unknown';\n name: string;\n fields?: Map<string, Type>; // For structs\n parameters?: Type[]; // For functions\n returnType?: Type; // For functions\n}\n\n/**\n * Symbol information\n */\nexport interface Symbol {\n name: string;\n type: Type;\n kind: 'variable' | 'function' | 'parameter' | 'struct';\n isConst: boolean;\n declared: boolean;\n}\n\n/**\n * Scope for symbol management\n */\nexport class Scope {\n private symbols = new Map<string, Symbol>();\n\n constructor(private parent?: Scope) {}\n\n /**\n * Define a symbol in this scope\n */\n define(name: string, symbol: Symbol): void {\n if (this.symbols.has(name)) {\n throw new TypeError(`Symbol '${name}' already defined in this scope`);\n }\n this.symbols.set(name, symbol);\n }\n\n /**\n * Resolve a symbol by name (checks parent scopes)\n */\n resolve(name: string): Symbol | undefined {\n const symbol = this.symbols.get(name);\n if (symbol) {\n return symbol;\n }\n if (this.parent) {\n return this.parent.resolve(name);\n }\n return undefined;\n }\n\n /**\n * Check if symbol exists in current scope only\n */\n has(name: string): boolean {\n return this.symbols.has(name);\n }\n\n /**\n * Get parent scope\n */\n getParent(): Scope | undefined {\n return this.parent;\n }\n}\n\n/**\n * Type error class\n */\nexport class TypeError extends Error {\n constructor(\n message: string,\n public line?: number,\n public column?: number\n ) {\n super(message);\n this.name = 'TypeError';\n }\n\n toString(): string {\n if (this.line && this.column) {\n return `${this.name} at ${this.line}:${this.column}: ${this.message}`;\n }\n return `${this.name}: ${this.message}`;\n }\n}\n\n/**\n * Type Checker class\n */\nexport class TypeChecker {\n private currentScope: Scope;\n private globalScope: Scope;\n private errors: TypeError[] = [];\n private currentFunction?: FunctionDeclaration;\n\n constructor() {\n this.globalScope = new Scope();\n this.currentScope = this.globalScope;\n this.initializeBuiltinTypes();\n }\n\n /**\n * Initialize built-in types\n */\n private initializeBuiltinTypes(): void {\n // Built-in primitive types are implicitly available\n // No need to register them in the symbol table\n }\n\n /**\n * Check the entire program\n */\n check(program: Program): TypeError[] {\n this.errors = [];\n\n try {\n // First pass: collect all declarations\n for (const declaration of program.body) {\n this.collectDeclaration(declaration);\n }\n\n // Second pass: type check all declarations\n for (const declaration of program.body) {\n this.checkDeclaration(declaration);\n }\n } catch (error) {\n if (error instanceof TypeError) {\n this.errors.push(error);\n } else {\n throw error;\n }\n }\n\n return this.errors;\n }\n\n /**\n * Collect declaration (first pass)\n */\n private collectDeclaration(declaration: Declaration): void {\n if (declaration.type === 'FunctionDeclaration') {\n const type = this.createFunctionType(declaration);\n this.currentScope.define(declaration.name, {\n name: declaration.name,\n type,\n kind: 'function',\n isConst: true,\n declared: true,\n });\n } else if (declaration.type === 'VariableDeclaration') {\n // Will be checked in second pass\n } else if (declaration.type === 'StructDeclaration') {\n const type = this.createStructType(declaration);\n this.currentScope.define(declaration.name, {\n name: declaration.name,\n type,\n kind: 'struct',\n isConst: true,\n declared: true,\n });\n }\n }\n\n /**\n * Create function type\n */\n private createFunctionType(fn: FunctionDeclaration): Type {\n const parameters = fn.parameters.map((param) =>\n this.typeAnnotationToType(param.typeAnnotation)\n );\n const returnType = this.typeAnnotationToType(fn.returnType);\n\n return {\n kind: 'function',\n name: fn.name,\n parameters,\n returnType,\n };\n }\n\n /**\n * Create struct type\n */\n private createStructType(struct: StructDeclaration): Type {\n const fields = new Map<string, Type>();\n for (const field of struct.fields) {\n fields.set(field.name, this.typeAnnotationToType(field.typeAnnotation));\n }\n\n return {\n kind: 'struct',\n name: struct.name,\n fields,\n };\n }\n\n /**\n * Convert type annotation to Type\n */\n private typeAnnotationToType(typeAnnotation: TypeAnnotation): Type {\n if (typeAnnotation.type === 'PrimitiveType') {\n return {\n kind: 'primitive',\n name: typeAnnotation.name,\n };\n } else if (typeAnnotation.type === 'IdentifierType') {\n // Look up custom type\n const symbol = this.currentScope.resolve(typeAnnotation.name);\n if (symbol && symbol.type) {\n return symbol.type;\n }\n return {\n kind: 'unknown',\n name: typeAnnotation.name,\n };\n }\n\n return {\n kind: 'unknown',\n name: 'unknown',\n };\n }\n\n /**\n * Check declaration (second pass)\n */\n private checkDeclaration(declaration: Declaration): void {\n if (declaration.type === 'FunctionDeclaration') {\n this.checkFunctionDeclaration(declaration);\n } else if (declaration.type === 'VariableDeclaration') {\n this.checkVariableDeclaration(declaration);\n }\n }\n\n /**\n * Check function declaration\n */\n private checkFunctionDeclaration(fn: FunctionDeclaration): void {\n this.currentFunction = fn;\n\n // Create new scope for function\n this.enterScope();\n\n // Add parameters to scope\n for (const param of fn.parameters) {\n const paramType = this.typeAnnotationToType(param.typeAnnotation);\n this.currentScope.define(param.name, {\n name: param.name,\n type: paramType,\n kind: 'parameter',\n isConst: true,\n declared: true,\n });\n }\n\n // Check function body\n this.checkBlockStatement(fn.body);\n\n // Check return type consistency\n const returnType = this.typeAnnotationToType(fn.returnType);\n if (returnType.name !== 'void') {\n // Verify all paths return a value (simplified check)\n if (!this.blockHasReturn(fn.body)) {\n this.addError(\n `Function '${fn.name}' must return a value of type '${returnType.name}'`,\n fn.line,\n fn.column\n );\n }\n }\n\n this.exitScope();\n this.currentFunction = undefined;\n }\n\n /**\n * Check if block has a return statement\n */\n private blockHasReturn(block: BlockStatement): boolean {\n for (const stmt of block.statements) {\n if (stmt.type === 'ReturnStatement') {\n return true;\n }\n if (stmt.type === 'IfStatement') {\n // Check both branches\n if ('consequent' in stmt && 'alternate' in stmt && stmt.alternate) {\n const hasReturnInConsequent = this.statementHasReturn(stmt.consequent);\n const hasReturnInAlternate = this.statementHasReturn(stmt.alternate);\n if (hasReturnInConsequent && hasReturnInAlternate) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Check if statement has a return\n */\n private statementHasReturn(stmt: Statement): boolean {\n if (stmt.type === 'ReturnStatement') {\n return true;\n }\n if (stmt.type === 'BlockStatement') {\n return this.blockHasReturn(stmt);\n }\n return false;\n }\n\n /**\n * Check variable declaration\n */\n private checkVariableDeclaration(varDecl: VariableDeclaration): void {\n let varType: Type;\n\n // Determine type\n if (varDecl.typeAnnotation) {\n varType = this.typeAnnotationToType(varDecl.typeAnnotation);\n } else if (varDecl.initializer) {\n // Infer type from initializer\n varType = this.checkExpression(varDecl.initializer);\n } else {\n this.addError(\n `Variable '${varDecl.name}' must have either a type annotation or initializer`,\n varDecl.line,\n varDecl.column\n );\n return;\n }\n\n // Check initializer type matches declared type\n if (varDecl.initializer && varDecl.typeAnnotation) {\n const initType = this.checkExpression(varDecl.initializer);\n if (!this.typesCompatible(varType, initType)) {\n this.addError(\n `Cannot assign value of type '${initType.name}' to variable of type '${varType.name}'`,\n varDecl.line,\n varDecl.column\n );\n }\n }\n\n // Add to scope\n try {\n this.currentScope.define(varDecl.name, {\n name: varDecl.name,\n type: varType,\n kind: 'variable',\n isConst: varDecl.isConst,\n declared: true,\n });\n } catch (error) {\n if (error instanceof TypeError) {\n this.addError(error.message, varDecl.line, varDecl.column);\n }\n }\n }\n\n /**\n * Check block statement\n */\n private checkBlockStatement(block: BlockStatement): void {\n this.enterScope();\n\n for (const stmt of block.statements) {\n this.checkStatement(stmt);\n }\n\n this.exitScope();\n }\n\n /**\n * Check statement\n */\n private checkStatement(stmt: Statement): void {\n switch (stmt.type) {\n case 'VariableDeclaration':\n this.checkVariableDeclaration(stmt);\n break;\n case 'ReturnStatement':\n this.checkReturnStatement(stmt);\n break;\n case 'IfStatement':\n this.checkIfStatement(stmt);\n break;\n case 'WhileStatement':\n this.checkWhileStatement(stmt);\n break;\n case 'ExpressionStatement':\n this.checkExpressionStatement(stmt);\n break;\n case 'BlockStatement':\n this.checkBlockStatement(stmt);\n break;\n case 'BreakStatement':\n case 'ContinueStatement':\n // No type checking needed\n break;\n case 'ComptimeStatement':\n this.checkBlockStatement(stmt.body);\n break;\n }\n }\n\n /**\n * Check return statement\n */\n private checkReturnStatement(stmt: ReturnStatement): void {\n if (!this.currentFunction) {\n this.addError('Return statement outside function', stmt.line, stmt.column);\n return;\n }\n\n const expectedType = this.typeAnnotationToType(this.currentFunction.returnType);\n\n if (stmt.value) {\n const returnType = this.checkExpression(stmt.value);\n if (!this.typesCompatible(expectedType, returnType)) {\n this.addError(\n `Return type '${returnType.name}' does not match function return type '${expectedType.name}'`,\n stmt.line,\n stmt.column\n );\n }\n } else {\n if (expectedType.name !== 'void') {\n this.addError(\n `Function must return a value of type '${expectedType.name}'`,\n stmt.line,\n stmt.column\n );\n }\n }\n }\n\n /**\n * Check if statement\n */\n private checkIfStatement(stmt: IfStatement): void {\n const conditionType = this.checkExpression(stmt.condition);\n if (conditionType.name !== 'bool') {\n this.addError(\n `If condition must be of type 'bool', got '${conditionType.name}'`,\n stmt.line,\n stmt.column\n );\n }\n\n this.checkStatement(stmt.consequent);\n if (stmt.alternate) {\n this.checkStatement(stmt.alternate);\n }\n }\n\n /**\n * Check while statement\n */\n private checkWhileStatement(stmt: WhileStatement): void {\n const conditionType = this.checkExpression(stmt.condition);\n if (conditionType.name !== 'bool') {\n this.addError(\n `While condition must be of type 'bool', got '${conditionType.name}'`,\n stmt.line,\n stmt.column\n );\n }\n\n this.checkStatement(stmt.body);\n }\n\n /**\n * Check expression statement\n */\n private checkExpressionStatement(stmt: ExpressionStatement): void {\n this.checkExpression(stmt.expression);\n }\n\n /**\n * Check expression and return its type\n */\n private checkExpression(expr: Expression): Type {\n switch (expr.type) {\n case 'NumberLiteral':\n return { kind: 'primitive', name: 'i32' }; // Default to i32\n case 'StringLiteral':\n return { kind: 'primitive', name: 'string' };\n case 'BooleanLiteral':\n return { kind: 'primitive', name: 'bool' };\n case 'Identifier':\n return this.checkIdentifier(expr);\n case 'BinaryExpression':\n return this.checkBinaryExpression(expr);\n case 'UnaryExpression':\n return this.checkUnaryExpression(expr);\n case 'CallExpression':\n return this.checkCallExpression(expr);\n case 'MemberExpression':\n return this.checkMemberExpression(expr);\n case 'IndexExpression':\n return this.checkIndexExpression(expr);\n case 'AssignmentExpression':\n return this.checkAssignmentExpression(expr);\n default:\n return { kind: 'unknown', name: 'unknown' };\n }\n }\n\n /**\n * Check identifier\n */\n private checkIdentifier(ident: Identifier): Type {\n const symbol = this.currentScope.resolve(ident.name);\n if (!symbol) {\n this.addError(`Undefined variable '${ident.name}'`, ident.line, ident.column);\n return { kind: 'unknown', name: 'unknown' };\n }\n return symbol.type;\n }\n\n /**\n * Check binary expression\n */\n private checkBinaryExpression(expr: BinaryExpression): Type {\n const leftType = this.checkExpression(expr.left);\n const rightType = this.checkExpression(expr.right);\n\n // Arithmetic operators\n if (['+', '-', '*', '/', '%'].includes(expr.operator)) {\n if (!this.isNumericType(leftType) || !this.isNumericType(rightType)) {\n this.addError(\n `Operator '${expr.operator}' requires numeric operands`,\n expr.line,\n expr.column\n );\n }\n return leftType; // Result has same type as operands\n }\n\n // Comparison operators\n if (['<', '>', '<=', '>=', '==', '!='].includes(expr.operator)) {\n if (!this.typesCompatible(leftType, rightType)) {\n this.addError(\n `Cannot compare values of type '${leftType.name}' and '${rightType.name}'`,\n expr.line,\n expr.column\n );\n }\n return { kind: 'primitive', name: 'bool' };\n }\n\n // Logical operators\n if (['&&', '||'].includes(expr.operator)) {\n if (leftType.name !== 'bool' || rightType.name !== 'bool') {\n this.addError(\n `Operator '${expr.operator}' requires boolean operands`,\n expr.line,\n expr.column\n );\n }\n return { kind: 'primitive', name: 'bool' };\n }\n\n return { kind: 'unknown', name: 'unknown' };\n }\n\n /**\n * Check unary expression\n */\n private checkUnaryExpression(expr: UnaryExpression): Type {\n const operandType = this.checkExpression(expr.operand);\n\n if (expr.operator === '-') {\n if (!this.isNumericType(operandType)) {\n this.addError(`Operator '-' requires numeric operand`, expr.line, expr.column);\n }\n return operandType;\n }\n\n if (expr.operator === '!') {\n if (operandType.name !== 'bool') {\n this.addError(`Operator '!' requires boolean operand`, expr.line, expr.column);\n }\n return { kind: 'primitive', name: 'bool' };\n }\n\n return { kind: 'unknown', name: 'unknown' };\n }\n\n /**\n * Check call expression\n */\n private checkCallExpression(expr: CallExpression): Type {\n const calleeType = this.checkExpression(expr.callee);\n\n if (calleeType.kind !== 'function') {\n this.addError('Expression is not callable', expr.line, expr.column);\n return { kind: 'unknown', name: 'unknown' };\n }\n\n // Check argument count\n const expectedParams = calleeType.parameters || [];\n if (expr.arguments.length !== expectedParams.length) {\n this.addError(\n `Expected ${expectedParams.length} arguments, got ${expr.arguments.length}`,\n expr.line,\n expr.column\n );\n }\n\n // Check argument types\n for (let i = 0; i < Math.min(expr.arguments.length, expectedParams.length); i++) {\n const argType = this.checkExpression(expr.arguments[i]);\n const paramType = expectedParams[i];\n if (!this.typesCompatible(paramType, argType)) {\n this.addError(\n `Argument ${i + 1}: expected '${paramType.name}', got '${argType.name}'`,\n expr.line,\n expr.column\n );\n }\n }\n\n return calleeType.returnType || { kind: 'void', name: 'void' };\n }\n\n /**\n * Check member expression\n */\n private checkMemberExpression(expr: MemberExpression): Type {\n const objectType = this.checkExpression(expr.object);\n\n if (objectType.kind !== 'struct') {\n this.addError(`Type '${objectType.name}' has no members`, expr.line, expr.column);\n return { kind: 'unknown', name: 'unknown' };\n }\n\n const field = objectType.fields?.get(expr.property);\n if (!field) {\n this.addError(\n `Struct '${objectType.name}' has no field '${expr.property}'`,\n expr.line,\n expr.column\n );\n return { kind: 'unknown', name: 'unknown' };\n }\n\n return field;\n }\n\n /**\n * Check index expression\n */\n private checkIndexExpression(expr: IndexExpression): Type {\n const objectType = this.checkExpression(expr.object);\n const indexType = this.checkExpression(expr.index);\n\n if (!this.isNumericType(indexType)) {\n this.addError('Array index must be numeric', expr.line, expr.column);\n }\n\n // For now, return unknown type\n return { kind: 'unknown', name: 'unknown' };\n }\n\n /**\n * Check assignment expression\n */\n private checkAssignmentExpression(expr: AssignmentExpression): Type {\n const leftType = this.checkExpression(expr.left);\n const rightType = this.checkExpression(expr.right);\n\n // Check if left side is assignable (identifier)\n if (expr.left.type === 'Identifier') {\n const symbol = this.currentScope.resolve(expr.left.name);\n if (symbol && symbol.isConst) {\n this.addError(\n `Cannot assign to const variable '${expr.left.name}'`,\n expr.line,\n expr.column\n );\n }\n }\n\n if (!this.typesCompatible(leftType, rightType)) {\n this.addError(\n `Cannot assign value of type '${rightType.name}' to '${leftType.name}'`,\n expr.line,\n expr.column\n );\n }\n\n return leftType;\n }\n\n /**\n * Check if types are compatible\n */\n private typesCompatible(expected: Type, actual: Type): boolean {\n if (expected.kind === 'unknown' || actual.kind === 'unknown') {\n return true; // Allow unknown types (for incomplete implementation)\n }\n return expected.name === actual.name;\n }\n\n /**\n * Check if type is numeric\n */\n private isNumericType(type: Type): boolean {\n return type.kind === 'primitive' && ['i32', 'i64', 'u32', 'f32', 'f64'].includes(type.name);\n }\n\n /**\n * Enter a new scope\n */\n private enterScope(): void {\n this.currentScope = new Scope(this.currentScope);\n }\n\n /**\n * Exit current scope\n */\n private exitScope(): void {\n const parent = this.currentScope.getParent();\n if (parent) {\n this.currentScope = parent;\n }\n }\n\n /**\n * Add an error\n */\n private addError(message: string, line?: number, column?: number): void {\n this.errors.push(new TypeError(message, line, column));\n }\n\n /**\n * Get all errors\n */\n getErrors(): TypeError[] {\n return this.errors;\n }\n}\n"],"mappings":"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"}