signature.go 1.7 KB

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