added type resolver
This commit is contained in:
@@ -5,6 +5,7 @@ import TraitChecker from "../types/trait_checker";
|
||||
import { TypeAliasResolver } from "../types/type_alias_resolution";
|
||||
import { TypeSystem } from "../types/type_system";
|
||||
import { TypeChecker } from "../types/type_checker";
|
||||
import { TypeResolver } from "../types/type_resolver";
|
||||
|
||||
export const run = defineCommand({
|
||||
name: "run",
|
||||
@@ -28,9 +29,11 @@ export const run = defineCommand({
|
||||
const aliasResolvedAst = new TypeAliasResolver().withModule(ast);
|
||||
const typeSystem = new TypeSystem();
|
||||
const typeChecker = new TypeChecker();
|
||||
const typeResolver = new TypeResolver();
|
||||
typeChecker.withModule(aliasResolvedAst, typeSystem);
|
||||
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));
|
||||
} else {
|
||||
|
||||
211
packages/boringlang/src/types/type_resolver.ts
Normal file
211
packages/boringlang/src/types/type_resolver.ts
Normal 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;
|
||||
};
|
||||
}
|
||||
@@ -100,8 +100,11 @@ export class TypeSystem {
|
||||
comparison.left.name.text,
|
||||
comparison.operation.name,
|
||||
);
|
||||
this.result[comparison.right.name] = attrType;
|
||||
comparison.right = attrType;
|
||||
const [result, found] = this.equateTypes(attrType, comparison.right);
|
||||
if (found) {
|
||||
comparison.right = result;
|
||||
foundUpdate = true;
|
||||
}
|
||||
}
|
||||
// check
|
||||
if (comparison.right.typeUsage !== "UnknownTypeUsage") {
|
||||
|
||||
Reference in New Issue
Block a user