package muesli /* ParametersPerSignature is the amount of parameters that will be checked when type checking a signature. Limited mosty to allow hashability, that is, Signature is a map key. */ const ParametersPerSignature = 32 /* Parameter describes the name and type of a parameter of a command. */ type Parameter struct { Name WordValue Type TypeValue } // Signature describes the types of the arguments that a callable takes. */ type Signature struct { Parameters [ParametersPerSignature]Parameter } func (s Signature) String() string { res := "[" sep := "" for _, param := range s.Parameters { typ := param.Type if typ != ZeroTypeValue { res = res + sep + typ.String() sep = " " } } res = res + "]" return res } func NewSignature(types ... TypeValue) Signature { signature := Signature{} for i := 0 ; i < len(types) && i < len(signature.Parameters) ; i ++ { signature.Parameters[i].Type = types[i] } return signature } // NoSignature is the default signature which means the VM will not do // any argument type checking when the callable is called. func NoSignature() Signature { return Signature{} } func CalculateSignature(arguments ...Value) Signature { signature := Signature{} for i := 0; i < len(signature.Parameters); i++ { if i < len(arguments) { signature.Parameters[i].Type = arguments[i].Type() } else { signature.Parameters[i].Type = AnyTypeValue } } return signature } func (tv TypeValue) IsMatch(other TypeValue) bool { if tv == AnyTypeValue || other == AnyTypeValue { return true } if tv == ZeroTypeValue || other == ZeroTypeValue { return true } return tv == other } func (signature Signature) IsMatch(other Signature) bool { for i, param := range signature.Parameters { t1 := param.Type t2 := other.Parameters[i].Type if !t1.IsMatch(t2) { return false } } return true }