package main import "fmt" type Type interface { Equal(Type) bool } type PrimitiveType string type ListType struct{ t Type } type QuotedType struct{ t Type } type FunctionType struct { ret Type params []Type } // type VariadicListType ListType type TypeEnvironment map[Id]Type var ( PrimVoid PrimitiveType = "void" PrimAny PrimitiveType = "any" PrimBoolean PrimitiveType = "boolean" PrimInteger PrimitiveType = "integer" PrimFloat PrimitiveType = "float" ) func (a *PrimitiveType) Equal(b Type) bool { switch b := b.(type) { case *PrimitiveType: return a == b default: return false } } func (p PrimitiveType) String() string { return string(p) } func (a *ListType) Equal(b Type) bool { switch b := b.(type) { case *ListType: return a.t.Equal(b.t) default: return false } } func (l ListType) String() string { return fmt.Sprintf("[list %v]", l.t) } func (a *QuotedType) Equal(b Type) bool { switch b := b.(type) { case *QuotedType: return a.t.Equal(b.t) default: return false } } func (q QuotedType) String() string { return fmt.Sprintf("[quote %v]", q.t) } func (fa *FunctionType) Equal(b Type) bool { fb, ok := b.(*FunctionType) if !ok { return false } if len(fa.params) != len(fb.params) { return false } for i := range fa.params { if !fa.params[i].Equal(fb.params[i]) { return false } } return fa.ret.Equal(fb.ret) } // func (fa *VariadicListType) Equal(b Type) bool { // return false // } // // func isVariadic(t Type) bool { // _, ok := t.(*VariadicListType) // return ok // }