123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- package checker
- import (
- "reflect"
- "kumachan/interpreter/lang/common/source"
- "kumachan/interpreter/compiler/checker/typsys"
- "kumachan/interpreter/compiler/checker/checked"
- )
- func (cc *checkContext) typeConsContext() TypeConsContext {
- return TypeConsContext {
- ModInfo: cc.exprContext.ModuleInfo,
- TypeReg: cc.exprContext.Registry.Types,
- ParamVec: cc.exprContext.ParameterList,
- }
- }
- func (cc *checkContext) getType(t nominalType) typsys.Type {
- return t(cc.exprContext.Types)
- }
- func (cc *checkContext) describeType(t typsys.Type) string {
- return typsys.DescribeType(t, cc.inferring)
- }
- func (cc *checkContext) describeTypeOf(expr *checked.Expr) string {
- return cc.describeType(expr.Type)
- }
- func (cc *checkContext) assignType(to typsys.Type, from typsys.Type) *source.Error {
- var a = typsys.MakeAssignContext(cc.exprContext.ModName, cc.inferring)
- var ok, s = typsys.Assign(to, from, a)
- if ok {
- cc.inferring = s
- return nil
- } else {
- return source.MakeError(cc.location, E_NotAssignable {
- From: cc.describeType(from),
- To: cc.describeType(to),
- })
- }
- }
- func (cc *checkContext) requireCertainOrInferredType(t typsys.Type) (typsys.Type, *source.Error) {
- var certain_t, ok = cc.getCertainType(t)
- if ok {
- return certain_t, nil
- } else {
- var inferred_t, ok = cc.getInferredType(t)
- if ok {
- return inferred_t, nil
- } else {
- return nil, source.MakeError(cc.location,
- E_ExplicitTypeRequired {})
- }
- }
- }
- func (cc *checkContext) getCertainType(t typsys.Type) (typsys.Type, bool) {
- if t == nil {
- return nil, false
- } else {
- if cc.inferring == nil {
- return t, true
- } else {
- return typsys.TypeOpGetCertainType(t, cc.inferring)
- }
- }
- }
- func (cc *checkContext) getInferredType(t typsys.Type) (typsys.Type, bool) {
- if t == nil {
- panic("something went wrong")
- } else {
- if cc.inferring == nil {
- panic("something went wrong")
- } else {
- return typsys.TypeOpGetInferredType(t, cc.inferring)
- }
- }
- }
- func (cc *checkContext) getExpectedCertainOrInferred(t typsys.Type) (typsys.Type, bool) {
- return typsys.TypeOpGetInferredExpectedType(t, cc.inferring)
- }
- func (cc *checkContext) getExpectedTuple(t typsys.Type) (typsys.Tuple, bool) {
- var get = func(t typsys.Type) (typsys.Tuple, bool) {
- return obtainIsoTuple(t, cc.exprContext.ModName)
- }
- var v, ok = cc.getExpectedTypeComponent(t, reflect.ValueOf(get))
- if ok {
- return v.(typsys.Tuple), true
- } else {
- return typsys.Tuple {}, false
- }
- }
- func (cc *checkContext) getExpectedRecord(t typsys.Type) (typsys.Record, bool) {
- var get = func(t typsys.Type) (typsys.Record, bool) {
- return obtainIsoRecord(t, cc.exprContext.ModName)
- }
- var v, ok = cc.getExpectedTypeComponent(t, reflect.ValueOf(get))
- if ok {
- return v.(typsys.Record), true
- } else {
- return typsys.Record {}, false
- }
- }
- func (cc *checkContext) getExpectedListItemType(t typsys.Type) (typsys.Type, bool) {
- var get func(typsys.Type) (typsys.Type, bool)
- get = func(t typsys.Type) (typsys.Type, bool) {
- var item_t, ok = coreList_(t)
- if ok {
- return item_t, true
- } else {
- var inner, box, is_box = typsys.Unbox(t, cc.exprContext.ModName)
- if is_box && box.BoxKind == typsys.Isomorphic {
- return get(inner)
- } else {
- return nil, false
- }
- }
- }
- var v, ok = cc.getExpectedTypeComponent(t, reflect.ValueOf(coreList_))
- if ok {
- return v.(typsys.Type), true
- } else {
- return nil, false
- }
- }
- func (cc *checkContext) getExpectedTypeComponent(t typsys.Type, get_ reflect.Value) (interface{}, bool) {
- var get = func(t typsys.Type) (interface{}, bool) {
- if t == nil {
- return nil, false
- }
- var ret = get_.Call([] reflect.Value { reflect.ValueOf(t) })
- var v, ok = ret[0].Interface(), ret[1].Interface()
- if ok.(bool) {
- return v, true
- } else {
- return nil, false
- }
- }
- var v, ok = get(t)
- if ok {
- return v, true
- } else {
- var t_, ok = typsys.TypeOpGetInferredExpectedType(t, cc.inferring)
- if ok {
- return get(t_)
- } else {
- return nil, false
- }
- }
- }
- func (cc *checkContext) getExpectedLambda(t typsys.Type, loc source.Location) (typsys.Lambda, *source.Error) {
- var get = func(t typsys.Type) (typsys.Lambda, bool) {
- return obtainIsoLambda(t, cc.exprContext.ModName)
- }
- var io, ok = get(t)
- if ok {
- var s = cc.inferring
- var in, ok = typsys.TypeOpGetInferredLambdaInputType(io.Input, s)
- if !(ok) { return typsys.Lambda {}, source.MakeError(loc,
- E_ExplicitTypeRequired {}) }
- var out = io.Output
- return typsys.Lambda {
- Input: in,
- Output: out,
- }, nil
- } else {
- var t_, ok = typsys.TypeOpGetInferredExpectedType(t, cc.inferring)
- if ok {
- var io, ok = get(t_)
- if ok {
- return io, nil
- }
- }
- if t == nil {
- return typsys.Lambda {}, source.MakeError(loc,
- E_ExplicitTypeRequired {})
- } else {
- return typsys.Lambda {}, source.MakeError(loc,
- E_LambdaAssignedToIncompatible {
- TypeName: typsys.DescribeType(t, cc.inferring),
- })
- }
- }
- }
- func (cc *checkContext) unboxInterface(expr *checked.Expr) (*typsys.Interface, *typsys.TypeDef, ([] typsys.Type), bool) {
- return cc.unboxInterfaceFromType(expr.Type)
- }
- func (cc *checkContext) unboxInterfaceFromType(t typsys.Type) (*typsys.Interface, *typsys.TypeDef, ([] typsys.Type), bool) {
- return unboxInterface(t, cc.exprContext.ModName)
- }
- func (cc *checkContext) unboxEnum(expr *checked.Expr) (*typsys.Enum, *typsys.TypeDef, ([] typsys.Type), bool) {
- return cc.unboxEnumFromType(expr.Type)
- }
- func (cc *checkContext) unboxEnumFromType(t typsys.Type) (*typsys.Enum, *typsys.TypeDef, ([] typsys.Type), bool) {
- return unboxEnum(t, cc.exprContext.ModName)
- }
- func (cc *checkContext) unboxRecord(expr *checked.Expr) (typsys.Record, bool) {
- return cc.unboxRecordFromType(expr.Type)
- }
- func (cc *checkContext) unboxRecordFromType(t typsys.Type) (typsys.Record, bool) {
- return unboxRecord(t, cc.exprContext.ModName)
- }
- func (cc *checkContext) unboxLambda(expr *checked.Expr) (typsys.Lambda, bool) {
- return cc.unboxLambdaFromType(expr.Type)
- }
- func (cc *checkContext) unboxLambdaFromType(t typsys.Type) (typsys.Lambda, bool) {
- return unboxLambda(t, cc.exprContext.ModName)
- }
- func (cc *checkContext) unboxInteriorReferableRecord(expr *checked.Expr) (typsys.Record, checked.InteriorRefOperand, typsys.Type, bool) {
- var record, ok = cc.unboxRecord(expr)
- if ok {
- var base_t = &typsys.NestedType { Content: record }
- return record, checked.RO_Record, base_t, true
- } else {
- var base_t, field_t, ok = coreProjRef_(expr.Type)
- if ok {
- var record, ok = cc.unboxRecordFromType(field_t)
- if ok {
- return record, checked.RO_ProjRef, base_t, true
- }
- }
- return typsys.Record {}, -1, nil, false
- }
- }
- func (cc *checkContext) unboxInteriorReferableEnum(expr *checked.Expr) (*typsys.Enum, ([] typsys.Type), checked.InteriorRefOperand, typsys.Type, bool) {
- var enum, enum_def, enum_args, ok = cc.unboxEnum(expr)
- if ok {
- var base_t = &typsys.NestedType { Content:
- typsys.Ref {
- Def: enum_def,
- Args: enum_args,
- } }
- return enum, enum_args, checked.RO_EnumOrInterface, base_t, true
- } else {
- { var base_t, field_t, ok = coreProjRef_(expr.Type)
- if ok {
- var enum, _, enum_args, ok = cc.unboxEnumFromType(field_t)
- if ok {
- return enum, enum_args, checked.RO_ProjRef, base_t, true
- }
- } }
- { var base_t, case_t, ok = coreCaseRef_(expr.Type)
- if ok {
- var enum, _, enum_args, ok = cc.unboxEnumFromType(case_t)
- if ok {
- return enum, enum_args, checked.RO_CaseRef, base_t, true
- }
- }}
- return nil, nil, -1, nil, false
- }
- }
- func (cc *checkContext) unboxInteriorReferableInterfaceDef(expr *checked.Expr) (*typsys.TypeDef, ([] typsys.Type), checked.InteriorRefOperand, typsys.Type, bool) {
- var _, def, t_args, ok = cc.unboxInterface(expr)
- if ok {
- var base_t = &typsys.NestedType { Content:
- typsys.Ref {
- Def: def,
- Args: t_args,
- } }
- return def, t_args, checked.RO_EnumOrInterface, base_t, true
- } else {
- { var base_t, field_t, ok = coreProjRef_(expr.Type)
- if ok {
- var _, def, t_args, ok = cc.unboxInterfaceFromType(field_t)
- if ok {
- return def, t_args, checked.RO_ProjRef, base_t, true
- }
- } }
- { var base_t, case_t, ok = coreCaseRef_(expr.Type)
- if ok {
- var _, def, t_args, ok = cc.unboxInterfaceFromType(case_t)
- if ok {
- return def, t_args, checked.RO_CaseRef, base_t, true
- }
- }}
- return nil, nil, -1, nil, false
- }
- }
|