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 { 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 {
|
||||||
|
|||||||
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.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") {
|
||||||
|
|||||||
Reference in New Issue
Block a user