diff options
Diffstat (limited to 'go/src/types/types.go')
| -rw-r--r-- | go/src/types/types.go | 320 |
1 files changed, 182 insertions, 138 deletions
diff --git a/go/src/types/types.go b/go/src/types/types.go index 54e4176..3fac06d 100644 --- a/go/src/types/types.go +++ b/go/src/types/types.go @@ -1,258 +1,302 @@ package types import ( - "reflect" - "errors" - "fmt" - "strings" + "errors" + "fmt" + "reflect" + "strings" ) // Errors/Exceptions type MalError struct { - Obj MalType + Obj MalType } func (e MalError) Error() string { - return fmt.Sprintf("%#v", e.Obj) + return fmt.Sprintf("%#v", e.Obj) } - // General types type MalType interface { } type EnvType interface { - Find(key Symbol) EnvType - Set(key Symbol, value MalType) MalType - Get(key Symbol) (MalType, error) + Find(key Symbol) EnvType + Set(key Symbol, value MalType) MalType + Get(key Symbol) (MalType, error) } // Scalars func Nil_Q(obj MalType) bool { - if obj == nil { return true } else { return false } + if obj == nil { + return true + } else { + return false + } } func True_Q(obj MalType) bool { - switch tobj := obj.(type) { - case bool: return tobj == true - default: return false - } + switch tobj := obj.(type) { + case bool: + return tobj == true + default: + return false + } } func False_Q(obj MalType) bool { - switch tobj := obj.(type) { - case bool: return tobj == false - default: return false - } + switch tobj := obj.(type) { + case bool: + return tobj == false + default: + return false + } } // Symbols type Symbol struct { - Val string + Val string } func Symbol_Q(obj MalType) bool { - if obj == nil { return false } - return reflect.TypeOf(obj).Name() == "Symbol" + if obj == nil { + return false + } + return reflect.TypeOf(obj).Name() == "Symbol" } - // Keywords func NewKeyword(s string) (MalType, error) { - return "\u029e" + s, nil; + return "\u029e" + s, nil } func Keyword_Q(obj MalType) bool { - if obj == nil { return false } - switch s := obj.(type) { - case string: return strings.HasPrefix(s, "\u029e") - default: return false - } + if obj == nil { + return false + } + switch s := obj.(type) { + case string: + return strings.HasPrefix(s, "\u029e") + default: + return false + } } - // Strings func String_Q(obj MalType) bool { - if obj == nil { return false } - return reflect.TypeOf(obj).Name() == "string" + if obj == nil { + return false + } + return reflect.TypeOf(obj).Name() == "string" } - // Functions type Func struct { - Fn func([]MalType) (MalType, error) - Meta MalType + Fn func([]MalType) (MalType, error) + Meta MalType } func Func_Q(obj MalType) bool { - if obj == nil { return false } - return reflect.TypeOf(obj).Name() == "Func" + if obj == nil { + return false + } + return reflect.TypeOf(obj).Name() == "Func" } type MalFunc struct { - Eval func(MalType, EnvType) (MalType, error) - Exp MalType - Env EnvType - Params MalType - IsMacro bool - GenEnv func(EnvType, MalType, MalType) (EnvType, error) - Meta MalType + Eval func(MalType, EnvType) (MalType, error) + Exp MalType + Env EnvType + Params MalType + IsMacro bool + GenEnv func(EnvType, MalType, MalType) (EnvType, error) + Meta MalType } func MalFunc_Q(obj MalType) bool { - if obj == nil { return false } - return reflect.TypeOf(obj).Name() == "MalFunc" + if obj == nil { + return false + } + return reflect.TypeOf(obj).Name() == "MalFunc" } func (f MalFunc) SetMacro() MalType { - f.IsMacro = true - return f + f.IsMacro = true + return f } func (f MalFunc) GetMacro() bool { - return f.IsMacro + return f.IsMacro } // Take either a MalFunc or regular function and apply it to the // arguments func Apply(f_mt MalType, a []MalType) (MalType, error) { - switch f := f_mt.(type) { - case MalFunc: - env, e := f.GenEnv(f.Env, f.Params, List{a,nil}) - if e != nil { return nil, e } - return f.Eval(f.Exp, env) - case Func: - return f.Fn(a) - case func([]MalType)(MalType, error): - return f(a) - default: - return nil, errors.New("Invalid function to Apply") - } + switch f := f_mt.(type) { + case MalFunc: + env, e := f.GenEnv(f.Env, f.Params, List{a, nil}) + if e != nil { + return nil, e + } + return f.Eval(f.Exp, env) + case Func: + return f.Fn(a) + case func([]MalType) (MalType, error): + return f(a) + default: + return nil, errors.New("Invalid function to Apply") + } } - // Lists type List struct { - Val []MalType - Meta MalType + Val []MalType + Meta MalType } func NewList(a ...MalType) MalType { - return List{a,nil} + return List{a, nil} } func List_Q(obj MalType) bool { - if obj == nil { return false } - return reflect.TypeOf(obj).Name() == "List" + if obj == nil { + return false + } + return reflect.TypeOf(obj).Name() == "List" } // Vectors type Vector struct { - Val []MalType - Meta MalType + Val []MalType + Meta MalType } func Vector_Q(obj MalType) bool { - if obj == nil { return false } - return reflect.TypeOf(obj).Name() == "Vector" + if obj == nil { + return false + } + return reflect.TypeOf(obj).Name() == "Vector" } func GetSlice(seq MalType) ([]MalType, error) { - switch obj := seq.(type) { - case List: return obj.Val, nil - case Vector: return obj.Val, nil - default: return nil, errors.New("GetSlice called on non-sequence") - } + switch obj := seq.(type) { + case List: + return obj.Val, nil + case Vector: + return obj.Val, nil + default: + return nil, errors.New("GetSlice called on non-sequence") + } } // Hash Maps type HashMap struct { - Val map[string]MalType - Meta MalType + Val map[string]MalType + Meta MalType } func NewHashMap(seq MalType) (MalType, error) { - lst, e := GetSlice(seq) - if e != nil { return nil, e } - if len(lst) % 2 == 1 { - return nil, errors.New("Odd number of arguments to NewHashMap") - } - m := map[string]MalType{} - for i := 0; i < len(lst); i+=2 { - str, ok := lst[i].(string) - if !ok { - return nil, errors.New("expected hash-map key string") - } - m[str] = lst[i+1] - } - return HashMap{m,nil}, nil + lst, e := GetSlice(seq) + if e != nil { + return nil, e + } + if len(lst)%2 == 1 { + return nil, errors.New("Odd number of arguments to NewHashMap") + } + m := map[string]MalType{} + for i := 0; i < len(lst); i += 2 { + str, ok := lst[i].(string) + if !ok { + return nil, errors.New("expected hash-map key string") + } + m[str] = lst[i+1] + } + return HashMap{m, nil}, nil } func HashMap_Q(obj MalType) bool { - if obj == nil { return false } - return reflect.TypeOf(obj).Name() == "HashMap" + if obj == nil { + return false + } + return reflect.TypeOf(obj).Name() == "HashMap" } // Atoms type Atom struct { - Val MalType - Meta MalType + Val MalType + Meta MalType } + func (a *Atom) Set(val MalType) MalType { - a.Val= val - return a + a.Val = val + return a } func Atom_Q(obj MalType) bool { - switch obj.(type) { - case *Atom: return true - default: return false - } + switch obj.(type) { + case *Atom: + return true + default: + return false + } } - - // General functions func _obj_type(obj MalType) string { - if obj == nil { return "nil" } - return reflect.TypeOf(obj).Name() + if obj == nil { + return "nil" + } + return reflect.TypeOf(obj).Name() } func Sequential_Q(seq MalType) bool { - if seq == nil { return false } - return (reflect.TypeOf(seq).Name() == "List") || - (reflect.TypeOf(seq).Name() == "Vector") + if seq == nil { + return false + } + return (reflect.TypeOf(seq).Name() == "List") || + (reflect.TypeOf(seq).Name() == "Vector") } func Equal_Q(a MalType, b MalType) bool { - ota := reflect.TypeOf(a); otb := reflect.TypeOf(b) - if !((ota == otb) || (Sequential_Q(a) && Sequential_Q(b))) { - return false - } - //av := reflect.ValueOf(a); bv := reflect.ValueOf(b) - //fmt.Printf("here2: %#v\n", reflect.TypeOf(a).Name()) - //switch reflect.TypeOf(a).Name() { - switch a.(type) { - case Symbol: - return a.(Symbol).Val == b.(Symbol).Val - case List: - as,_ := GetSlice(a); bs,_ := GetSlice(b) - if len(as) != len(bs) { return false } - for i := 0; i < len(as); i+=1 { - if !Equal_Q(as[i], bs[i]) { return false } - } - return true - case Vector: - as,_ := GetSlice(a); bs,_ := GetSlice(b) - if len(as) != len(bs) { return false } - for i := 0; i < len(as); i+=1 { - if !Equal_Q(as[i], bs[i]) { return false } - } - return true - case HashMap: - return false - default: - return a == b - } + ota := reflect.TypeOf(a) + otb := reflect.TypeOf(b) + if !((ota == otb) || (Sequential_Q(a) && Sequential_Q(b))) { + return false + } + //av := reflect.ValueOf(a); bv := reflect.ValueOf(b) + //fmt.Printf("here2: %#v\n", reflect.TypeOf(a).Name()) + //switch reflect.TypeOf(a).Name() { + switch a.(type) { + case Symbol: + return a.(Symbol).Val == b.(Symbol).Val + case List: + as, _ := GetSlice(a) + bs, _ := GetSlice(b) + if len(as) != len(bs) { + return false + } + for i := 0; i < len(as); i += 1 { + if !Equal_Q(as[i], bs[i]) { + return false + } + } + return true + case Vector: + as, _ := GetSlice(a) + bs, _ := GetSlice(b) + if len(as) != len(bs) { + return false + } + for i := 0; i < len(as); i += 1 { + if !Equal_Q(as[i], bs[i]) { + return false + } + } + return true + case HashMap: + return false + default: + return a == b + } } |
