signature.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package muesli
  2. /*
  3. ParametersPerSignature is the amount of parameters that will be
  4. checked when type checking a signature. Limited mosty to allow hashability,
  5. that is, Signature is a map key.
  6. */
  7. const ParametersPerSignature = 32
  8. /* Parameter describes the name and type of a parameter of a command. */
  9. type Parameter struct {
  10. Name WordValue
  11. Type TypeValue
  12. }
  13. // Signature describes the types of the arguments that a callable takes. */
  14. type Signature struct {
  15. Parameters [ParametersPerSignature]Parameter
  16. }
  17. func (s Signature) String() string {
  18. res := "["
  19. sep := ""
  20. for _, param := range s.Parameters {
  21. typ := param.Type
  22. if typ != ZeroTypeValue {
  23. res = res + sep + typ.String()
  24. sep = " "
  25. }
  26. }
  27. res = res + "]"
  28. return res
  29. }
  30. func NewSignature(types ... TypeValue) Signature {
  31. signature := Signature{}
  32. for i := 0 ; i < len(types) && i < len(signature.Parameters) ; i ++ {
  33. signature.Parameters[i].Type = types[i]
  34. }
  35. return signature
  36. }
  37. // NoSignature is the default signature which means the VM will not do
  38. // any argument type checking when the callable is called.
  39. func NoSignature() Signature {
  40. return Signature{}
  41. }
  42. func CalculateSignature(arguments ...Value) Signature {
  43. signature := Signature{}
  44. for i := 0; i < len(signature.Parameters); i++ {
  45. if i < len(arguments) {
  46. signature.Parameters[i].Type = arguments[i].Type()
  47. } else {
  48. signature.Parameters[i].Type = AnyTypeValue
  49. }
  50. }
  51. return signature
  52. }
  53. func (tv TypeValue) IsMatch(other TypeValue) bool {
  54. if tv == AnyTypeValue || other == AnyTypeValue {
  55. return true
  56. }
  57. if tv == ZeroTypeValue || other == ZeroTypeValue {
  58. return true
  59. }
  60. return tv == other
  61. }
  62. func (signature Signature) IsMatch(other Signature) bool {
  63. for i, param := range signature.Parameters {
  64. t1 := param.Type
  65. t2 := other.Parameters[i].Type
  66. if !t1.IsMatch(t2) {
  67. return false
  68. }
  69. }
  70. return true
  71. }