Skip to content

Commit

Permalink
Semantic: qualified call stub
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Apr 1, 2024
1 parent 8eb8d76 commit ac66c4e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 13 deletions.
25 changes: 21 additions & 4 deletions src/semantic/expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,17 @@ export const checkResolvedClosureExpr = (
}
}

export const checkQualifiedMethodCall = (
def: MethodDef,
ctx: Context,
operand: Operand,
inferredType: VirtualFnType
): VirtualType => {
const genericMaps = [instanceGenericMap(def.rel.instanceDef, ctx)]
const fnType = def.fn.type!
return resolveType(fnType, genericMaps, ctx)
}

export const checkCall = (unaryExpr: UnaryExpr, ctx: Context): void => {
const call = <CallOp>unaryExpr.op
const operand = unaryExpr.operand
Expand Down Expand Up @@ -536,7 +547,7 @@ export const checkVariantCall = (

export const checkCall_ = (call: CallOp, operand: Operand, args: Expr[], ctx: Context): VirtualType => {
if (operand.type?.kind === 'malleable-type') {
const closureType: VirtualFnType = {
const inferredType: VirtualFnType = {
kind: 'fn-type',
generics: [],
paramTypes: args.map(arg => arg.type ?? unknownType),
Expand All @@ -545,10 +556,16 @@ export const checkCall_ = (call: CallOp, operand: Operand, args: Expr[], ctx: Co
switch (operand.type.operand.kind) {
case 'closure-expr':
const closure = operand.type.operand
operand.type = checkResolvedClosureExpr(closure, ctx, operand, closureType)
operand.type = checkResolvedClosureExpr(closure, ctx, operand, inferredType)
break
case 'identifier':
// TODO: properly
const ref = operand.type!.operand.ref
if (ref?.def.kind !== 'method-def') return unreachable()
operand.type = checkQualifiedMethodCall(ref.def, ctx, operand, inferredType)
break
default:
unreachable()
unreachable(operand.type.operand.kind)
}
}
if (operand.type?.kind === 'unknown-type') {
Expand Down Expand Up @@ -698,7 +715,7 @@ export const makeFnGenericMaps = (
): Map<string, VirtualType>[] => {
const fnTypeArgMap = makeFnTypeArgGenericMap(fnType, typeArgs)
const instScope = instanceScope(ctx)
const instanceMap = instScope ? instanceGenericMap(instScope, ctx) : new Map()
const instanceMap = instScope ? instanceGenericMap(instScope.def, ctx) : new Map()
const fnMap = makeFnGenericMap(fnType, args)
return [instanceMap, fnTypeArgMap, fnMap]
}
Expand Down
18 changes: 12 additions & 6 deletions src/semantic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
unspecifiedParamTypeError,
vidResolveToModuleError
} from './error'
import { checkExpr, checkResolvedClosureExpr } from './expr'
import { checkExpr, checkQualifiedMethodCall, checkResolvedClosureExpr } from './expr'
import { checkPattern } from './match'
import { typeNames } from './type-def'
import { Upcast, UpcastFn, makeUpcast, upcast } from './upcast'
Expand Down Expand Up @@ -345,7 +345,7 @@ const checkFnDef = (fnDef: FnDef, ctx: Context): void => {
}

const instScope = instanceScope(ctx)
const genericMaps = instScope ? [instanceGenericMap(instScope, ctx)] : []
const genericMaps = instScope ? [instanceGenericMap(instScope.def, ctx)] : []
const returnTypeResolved = resolveType(returnType, genericMaps, ctx)

if (ctx.check && !module.compiled) {
Expand Down Expand Up @@ -605,7 +605,7 @@ const checkVarDef = (varDef: VarDef, ctx: Context): void => {
const instScope = instanceScope(ctx)
varType = resolveType(
typeToVirtual(varDef.varType, ctx),
instScope ? [instanceGenericMap(instScope, ctx)] : [],
instScope ? [instanceGenericMap(instScope.def, ctx)] : [],
ctx
)
}
Expand Down Expand Up @@ -688,7 +688,11 @@ export const checkIdentifier = (identifier: Identifier, ctx: Context): void => {
}
if (name.type === selfType) {
const instScope = instanceScope(ctx)
identifier.type = resolveType(name.type, instScope ? [instanceGenericMap(instScope, ctx)] : [], ctx)
identifier.type = resolveType(
name.type,
instScope ? [instanceGenericMap(instScope.def, ctx)] : [],
ctx
)
} else {
identifier.type = name.type
}
Expand Down Expand Up @@ -775,8 +779,10 @@ export const resolveMallebleType = (arg: Operand, paramType: VirtualType, ctx: C
arg.type! = checkResolvedClosureExpr(closure, ctx, arg, paramType)
break
case 'identifier':
// TODO
arg.type! = unknownType
// TODO: properly
const ref = arg.type!.operand.ref
if (ref?.def.kind !== 'method-def') return unreachable()
arg.type = checkQualifiedMethodCall(ref.def, ctx, arg, paramType)
break
default:
unreachable()
Expand Down
7 changes: 4 additions & 3 deletions src/typecheck/generic.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Context, InstanceScope } from '../scope'
import { ImplDef, TraitDef } from '../ast/statement'
import { Context } from '../scope'
import { getInstanceForType } from '../scope/trait'
import { merge } from '../util/map'
import { assert } from '../util/todo'
Expand Down Expand Up @@ -145,8 +146,8 @@ export const getTypeParams = (virtualType: VirtualType): VirtualType[] => {
}
}

export const instanceGenericMap = (instScope: InstanceScope, ctx: Context): Map<string, VirtualType> => {
return new Map([[selfType.key, getInstanceForType(instScope.def, ctx)]])
export const instanceGenericMap = (def: ImplDef | TraitDef, ctx: Context): Map<string, VirtualType> => {
return new Map([[selfType.key, getInstanceForType(def, ctx)]])
}

/**
Expand Down

0 comments on commit ac66c4e

Please sign in to comment.