github.com/masahide/goansible@v0.0.0-20160116054156-01eac649e9f2/lisp/builtin.go (about) 1 package lisp 2 3 import "fmt" 4 5 type Builtin struct{} 6 7 var builtin = Builtin{} 8 9 var builtin_commands = map[string]string{ 10 "+": "Add", 11 "-": "Sub", 12 "*": "Mul", 13 "==": "Eq", 14 ">": "Gt", 15 "<": "Lt", 16 ">=": "Gte", 17 "<=": "Lte", 18 "display": "Display", 19 "cons": "Cons", 20 "car": "Car", 21 "cdr": "Cdr", 22 } 23 24 func (Builtin) Display(vars ...Value) (Value, error) { 25 if len(vars) == 1 { 26 fmt.Println(vars[0]) 27 } else { 28 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 29 } 30 return vars[0], nil 31 } 32 33 func (Builtin) Cons(vars ...Value) (Value, error) { 34 if len(vars) == 2 { 35 cons := Cons{&vars[0], &vars[1]} 36 return Value{consValue, &cons}, nil 37 } else { 38 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 39 } 40 } 41 42 func (Builtin) Car(vars ...Value) (Value, error) { 43 if len(vars) == 1 && vars[0].typ == consValue { 44 cons := vars[0].Cons() 45 return *cons.car, nil 46 } else { 47 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 48 } 49 } 50 51 func (Builtin) Cdr(vars ...Value) (Value, error) { 52 if len(vars) == 1 && vars[0].typ == consValue { 53 cons := vars[0].Cons() 54 return *cons.cdr, nil 55 } else { 56 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 57 } 58 } 59 60 func (Builtin) Add(vars ...Value) (Value, error) { 61 var sum int64 62 for _, v := range vars { 63 if v.typ == numberValue { 64 sum += v.Number() 65 } else { 66 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 67 } 68 } 69 return Value{numberValue, sum}, nil 70 } 71 72 func (Builtin) Sub(vars ...Value) (Value, error) { 73 if vars[0].typ != numberValue { 74 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 75 } 76 sum := vars[0].Number() 77 for _, v := range vars[1:] { 78 if v.typ == numberValue { 79 sum -= v.Number() 80 } else { 81 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 82 } 83 } 84 return Value{numberValue, sum}, nil 85 } 86 87 func (Builtin) Mul(vars ...Value) (Value, error) { 88 if vars[0].typ != numberValue { 89 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 90 } 91 sum := vars[0].Number() 92 for _, v := range vars[1:] { 93 if v.typ == numberValue { 94 sum *= v.Number() 95 } else { 96 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 97 } 98 } 99 return Value{numberValue, sum}, nil 100 } 101 102 func (Builtin) Eq(vars ...Value) (Value, error) { 103 for i := 1; i < len(vars); i++ { 104 v1 := vars[i-1] 105 v2 := vars[i] 106 107 if v1.typ != v2.typ { 108 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 109 } else if v1.typ == numberValue { 110 if v1.Number() != v2.Number() { 111 return False, nil 112 } 113 } else if v1.typ == stringValue { 114 if v1.String() != v2.String() { 115 return False, nil 116 } 117 } else { 118 return Nil, fmt.Errorf("Unsupported argument type: %v", vars) 119 } 120 } 121 return True, nil 122 } 123 124 func (Builtin) Gt(vars ...Value) (Value, error) { 125 for i := 1; i < len(vars); i++ { 126 v1 := vars[i-1] 127 v2 := vars[i] 128 if v1.typ != numberValue || v2.typ != numberValue { 129 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 130 } else if !(v1.Number() > v2.Number()) { 131 return False, nil 132 } 133 } 134 return True, nil 135 } 136 137 func (Builtin) Lt(vars ...Value) (Value, error) { 138 for i := 1; i < len(vars); i++ { 139 v1 := vars[i-1] 140 v2 := vars[i] 141 if v1.typ != numberValue || v2.typ != numberValue { 142 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 143 } else if !(v1.Number() < v2.Number()) { 144 return False, nil 145 } 146 } 147 return True, nil 148 } 149 150 func (Builtin) Gte(vars ...Value) (Value, error) { 151 for i := 1; i < len(vars); i++ { 152 v1 := vars[i-1] 153 v2 := vars[i] 154 if v1.typ != numberValue || v2.typ != numberValue { 155 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 156 } else if !(v1.Number() >= v2.Number()) { 157 return False, nil 158 } 159 } 160 return True, nil 161 } 162 163 func (Builtin) Lte(vars ...Value) (Value, error) { 164 for i := 1; i < len(vars); i++ { 165 v1 := vars[i-1] 166 v2 := vars[i] 167 if v1.typ != numberValue || v2.typ != numberValue { 168 return Nil, fmt.Errorf("Badly formatted arguments: %v", vars) 169 } else if !(v1.Number() <= v2.Number()) { 170 return False, nil 171 } 172 } 173 return True, nil 174 }