added type resolver

This commit is contained in:
2025-08-30 22:11:19 -06:00
parent 66c7864df0
commit dd4f5b9ee6
3 changed files with 220 additions and 3 deletions

View File

@@ -5,6 +5,7 @@ import TraitChecker from "../types/trait_checker";
import { TypeAliasResolver } from "../types/type_alias_resolution"; import { TypeAliasResolver } from "../types/type_alias_resolution";
import { TypeSystem } from "../types/type_system"; import { TypeSystem } from "../types/type_system";
import { TypeChecker } from "../types/type_checker"; import { TypeChecker } from "../types/type_checker";
import { TypeResolver } from "../types/type_resolver";
export const run = defineCommand({ export const run = defineCommand({
name: "run", name: "run",
@@ -28,9 +29,11 @@ export const run = defineCommand({
const aliasResolvedAst = new TypeAliasResolver().withModule(ast); const aliasResolvedAst = new TypeAliasResolver().withModule(ast);
const typeSystem = new TypeSystem(); const typeSystem = new TypeSystem();
const typeChecker = new TypeChecker(); const typeChecker = new TypeChecker();
const typeResolver = new TypeResolver();
typeChecker.withModule(aliasResolvedAst, typeSystem); typeChecker.withModule(aliasResolvedAst, typeSystem);
typeSystem.solve(); typeSystem.solve();
console.log(JSON.stringify(typeSystem, null, 2)); const typeResolvedAst = typeResolver.withModule(aliasResolvedAst, typeSystem);
console.log(JSON.stringify(typeResolvedAst, null, 2));
// console.log(JSON.stringify(aliasResolvedAst, null, 2)); // console.log(JSON.stringify(aliasResolvedAst, null, 2));
} else { } else {

View File

@@ -0,0 +1,211 @@
import {
AssignmentStatement,
Block,
containsReturn,
Expression,
Function,
FunctionCall,
FunctionDeclaration,
functionToType,
IfExpression,
Impl,
LetStatement,
LiteralStruct,
Module,
newVoid,
Operation,
ReturnStatement,
StructGetter,
StructTypeDeclaration,
TraitTypeDeclaration,
TypeUsage,
VariableUsage,
} from "../parse/ast";
import { newContext } from "./builtins";
import { Context, deepCopy, typeExists } from "./context";
import { TypeSystem } from "./type_system";
export class TypeResolver {
withModule = (module: Module, typeSystem: TypeSystem) => {
const result = deepCopy(module);
// environment set up, actually recurse.
for (const [i, item] of module.items.entries()) {
if (item.moduleItem === "Function") {
result.items[i] = this.withFunction(item, typeSystem);
}
if (item.moduleItem === "Impl") {
result.items[i] = this.withImpl(item, typeSystem);
}
if (item.moduleItem === "StructTypeDeclaration") {
result.items[i] = this.withStructDeclaration(item, typeSystem);
}
if (item.moduleItem === "TraitTypeDeclaration") {
result.items[i] = this.withTrait(item, typeSystem);
}
}
return result;
};
withFunction = (fn: Function, typeSystem: TypeSystem) => {
const result = deepCopy(fn);
result.declaration = this.withFunctionDeclaration(fn.declaration, typeSystem);
result.block = this.withBlock(fn.block, typeSystem);
return result;
};
withFunctionDeclaration = (def: FunctionDeclaration, typeSystem: TypeSystem) => {
const result = deepCopy(def);
result.arguments = def.arguments.map((arg) => {
const resultArg = deepCopy(arg);
resultArg.type = typeSystem.resolveType(arg.type);
return resultArg;
});
return result;
};
withImpl = (impl: Impl, typeSystem: TypeSystem) => {
const result = deepCopy(impl);
for (const [i, fn] of impl.functions.entries()) {
result.functions[i] = this.withFunction(fn, typeSystem);
}
return result;
};
withStructDeclaration = (struct: StructTypeDeclaration, typeSystem: TypeSystem) => {
const result = deepCopy(struct);
for (const [i, field] of struct.fields.entries()) {
result.fields[i] = { name: field.name, type: typeSystem.resolveType(field.type) };
}
return result;
};
withTrait = (trait: TraitTypeDeclaration, typeSystem: TypeSystem) => {
const result = deepCopy(trait);
for (const [i, method] of trait.functions.entries()) {
result.functions[i] = this.withFunctionDeclaration(method, typeSystem);
}
return result;
};
withBlock = (block: Block, typeSystem: TypeSystem) => {
const result = deepCopy(block);
for (const [i, statement] of block.statements.entries()) {
if (statement.statementType === "AssignmentStatement") {
result.statements[i] = this.withAssignmentStatement(statement, typeSystem);
}
if (statement.statementType === "LetStatement") {
result.statements[i] = this.withLetStatement(statement, typeSystem);
}
if (statement.statementType === "Expression") {
result.statements[i] = this.withExpression(statement, typeSystem);
}
if (statement.statementType === "ReturnStatement") {
result.statements[i] = this.withReturnStatement(statement, typeSystem);
}
result.type = typeSystem.resolveType(block.type);
}
return result;
};
withAssignmentStatement = (statement: AssignmentStatement, typeSystem: TypeSystem) => {
const result = deepCopy(statement);
if (statement.source.expressionType == "StructGetter") {
result.source = this.withStructGetter(statement.source, typeSystem);
}
if (statement.source.expressionType == "VariableUsage") {
result.source = this.withVariableUsage(statement.source, typeSystem);
}
result.expression = this.withExpression(statement.expression, typeSystem);
return result;
};
withLetStatement = (statement: LetStatement, typeSystem: TypeSystem) => {
const result = deepCopy(statement);
result.expression = this.withExpression(statement.expression, typeSystem);
result.type = typeSystem.resolveType(statement.type);
return result;
};
withReturnStatement = (statement: ReturnStatement, typeSystem: TypeSystem) => {
const result = deepCopy(statement);
result.source = this.withExpression(statement.source, typeSystem);
return result;
};
withExpression = (expression: Expression, typeSystem: TypeSystem) => {
const result = deepCopy(expression);
result.type = typeSystem.resolveType(expression.type);
if (expression.subExpression.expressionType === "LiteralStruct") {
result.subExpression = this.withLiteralStruct(expression.subExpression, typeSystem);
}
if (expression.subExpression.expressionType === "FunctionCall") {
result.subExpression = this.withFunctionCall(expression.subExpression, typeSystem);
}
if (expression.subExpression.expressionType === "VariableUsage") {
result.subExpression = this.withVariableUsage(expression.subExpression, typeSystem);
}
if (expression.subExpression.expressionType === "IfExpression") {
result.subExpression = this.withIfExpression(expression.subExpression, typeSystem);
}
if (expression.subExpression.expressionType === "StructGetter") {
result.subExpression = this.withStructGetter(expression.subExpression, typeSystem);
}
if (expression.subExpression.expressionType === "Block") {
result.subExpression = this.withBlock(expression.subExpression, typeSystem);
}
if (expression.subExpression.expressionType === "Operation") {
result.subExpression = this.withOperation(expression.subExpression, typeSystem);
}
return result;
};
withLiteralStruct = (literal: LiteralStruct, typeSystem: TypeSystem) => {
const result = deepCopy(literal);
for (const [i, field] of literal.fields.entries()) {
result.fields[i].expression = this.withExpression(field.expression, typeSystem);
}
result.type = typeSystem.resolveType(literal.type);
return result;
};
withFunctionCall = (fnCall: FunctionCall, typeSystem: TypeSystem) => {
const result = deepCopy(fnCall);
result.type = typeSystem.resolveType(fnCall.type);
result.source = this.withExpression(fnCall.source, typeSystem);
for (const [i, arg] of fnCall.arguments.entries()) {
result.arguments[i] = this.withExpression(arg, typeSystem);
}
return result;
};
withVariableUsage = (usage: VariableUsage, typeSystem: TypeSystem) => {
const result = deepCopy(usage);
result.type = typeSystem.resolveType(usage.type);
return result;
};
withIfExpression = (ifExpression: IfExpression, typeSystem: TypeSystem) => {
const result = deepCopy(ifExpression);
result.type = typeSystem.resolveType(ifExpression.type);
result.condition = this.withExpression(ifExpression.condition, typeSystem);
result.block = this.withBlock(ifExpression.block, typeSystem);
result.else = ifExpression.else ? this.withBlock(ifExpression.else, typeSystem) : null;
return result;
};
withStructGetter = (structGetter: StructGetter, typeSystem: TypeSystem) => {
const result = deepCopy(structGetter);
result.type = typeSystem.resolveType(structGetter.type);
result.source = this.withExpression(structGetter.source, typeSystem);
return result;
};
withOperation = (op: Operation, typeSystem: TypeSystem) => {
const result = deepCopy(op);
result.type = typeSystem.resolveType(op.type);
result.left = this.withExpression(op.left, typeSystem);
result.right = this.withExpression(op.right, typeSystem);
return result;
};
}

View File

@@ -100,8 +100,11 @@ export class TypeSystem {
comparison.left.name.text, comparison.left.name.text,
comparison.operation.name, comparison.operation.name,
); );
this.result[comparison.right.name] = attrType; const [result, found] = this.equateTypes(attrType, comparison.right);
comparison.right = attrType; if (found) {
comparison.right = result;
foundUpdate = true;
}
} }
// check // check
if (comparison.right.typeUsage !== "UnknownTypeUsage") { if (comparison.right.typeUsage !== "UnknownTypeUsage") {