Unified · Split
| @@ -35,6 +35,7 @@ var forthTests = []forthTest{ · 34 unmodified lines | |||
| 35 | {"1 dup +", "2", ""}, | 35 | {"1 dup +", "2", ""}, |
| 36 | {"4095 4096 roundup", "4096", ""}, | 36 | {"4095 4096 roundup", "4096", ""}, |
| 37 | {"4097 8192 roundup", "8192", ""}, | 37 | {"4097 8192 roundup", "8192", ""}, |
| 38 | {"2 x +", "", "parsing \"x\": invalid syntax"}, | ||
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | func TestForth(t *testing.T) { | 41 | func TestForth(t *testing.T) { |
| @@ -65,6 +66,10 @@ func TestForth(t *testing.T) { · 24 unmodified lines | |||
| 65 | var err error | 66 | var err error |
| 66 | res, err := Eval(f, tt.val) | 67 | res, err := Eval(f, tt.val) |
| 67 | if res == tt.res || (err != nil && err.Error() == tt.err) { | 68 | if res == tt.res || (err != nil && err.Error() == tt.err) { |
| 69 | if err != nil { | ||
| 70 | /* stack is not going to be right; reset it. */ | ||
| 71 | f.Reset() | ||
| 72 | } | ||
| 68 | fmt.Printf("Test: '%v' '%v' '%v': Pass\n", tt.val, res, err) | 73 | fmt.Printf("Test: '%v' '%v' '%v': Pass\n", tt.val, res, err) |
| 69 | } else { | 74 | } else { |
| 70 | t.Errorf("Test: '%v' '%v' '%v': Fail\n", tt.val, res, err) | 75 | t.Errorf("Test: '%v' '%v' '%v': Fail\n", tt.val, res, err) |
| @@ -145,44 +145,52 @@ func Eval(f Forth, s string) (ret string, err error) { · 144 unmodified lines | |||
| 145 | 145 | ||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | func toInt(f Forth) int { | ||
| 149 | i, err := strconv.Atoi(f.Pop()) | ||
| 150 | if err != nil { | ||
| 151 | panic(err) | ||
| 152 | } | ||
| 153 | return i | ||
| 154 | } | ||
| 155 | |||
| 148 | func plus(f Forth) { | 156 | func plus(f Forth) { |
| 149 | x, _ := strconv.Atoi(f.Pop()) | 157 | x := toInt(f) |
| 150 | y, _ := strconv.Atoi(f.Pop()) | 158 | y := toInt(f) |
| 151 | z := x + y | 159 | z := x + y |
| 152 | f.Push(strconv.Itoa(z)) | 160 | f.Push(strconv.Itoa(z)) |
| 153 | } | 161 | } |
| 154 | 162 | ||
| 155 | func times(f Forth) { | 163 | func times(f Forth) { |
| 156 | x, _ := strconv.Atoi(f.Pop()) | 164 | x := toInt(f) |
| 157 | y, _ := strconv.Atoi(f.Pop()) | 165 | y := toInt(f) |
| 158 | z := x * y | 166 | z := x * y |
| 159 | f.Push(strconv.Itoa(z)) | 167 | f.Push(strconv.Itoa(z)) |
| 160 | } | 168 | } |
| 161 | 169 | ||
| 162 | func sub(f Forth) { | 170 | func sub(f Forth) { |
| 163 | x, _ := strconv.Atoi(f.Pop()) | 171 | x := toInt(f) |
| 164 | y, _ := strconv.Atoi(f.Pop()) | 172 | y := toInt(f) |
| 165 | z := y - x | 173 | z := y - x |
| 166 | f.Push(strconv.Itoa(z)) | 174 | f.Push(strconv.Itoa(z)) |
| 167 | } | 175 | } |
| 168 | 176 | ||
| 169 | func div(f Forth) { | 177 | func div(f Forth) { |
| 170 | x, _ := strconv.Atoi(f.Pop()) | 178 | x := toInt(f) |
| 171 | y, _ := strconv.Atoi(f.Pop()) | 179 | y := toInt(f) |
| 172 | z := y / x | 180 | z := y / x |
| 173 | f.Push(strconv.Itoa(z)) | 181 | f.Push(strconv.Itoa(z)) |
| 174 | } | 182 | } |
| 175 | 183 | ||
| 176 | func mod(f Forth) { | 184 | func mod(f Forth) { |
| 177 | x, _ := strconv.Atoi(f.Pop()) | 185 | x := toInt(f) |
| 178 | y, _ := strconv.Atoi(f.Pop()) | 186 | y := toInt(f) |
| 179 | z := y % x | 187 | z := y % x |
| 180 | f.Push(strconv.Itoa(z)) | 188 | f.Push(strconv.Itoa(z)) |
| 181 | } | 189 | } |
| 182 | 190 | ||
| 183 | func roundup(f Forth) { | 191 | func roundup(f Forth) { |
| 184 | rnd, _ := strconv.Atoi(f.Pop()) | 192 | rnd := toInt(f) |
| 185 | v, _ := strconv.Atoi(f.Pop()) | 193 | v := toInt(f) |
| 186 | v = ((v + rnd - 1) / rnd) * rnd | 194 | v = ((v + rnd - 1) / rnd) * rnd |
| 187 | f.Push(strconv.Itoa(v)) | 195 | f.Push(strconv.Itoa(v)) |
| 188 | } | 196 | } |
| @@ -207,7 +215,7 @@ func dup(f Forth) { · 18 unmodified lines | |||
| 207 | } | 215 | } |
| 208 | 216 | ||
| 209 | func ifelse(f Forth) { | 217 | func ifelse(f Forth) { |
| 210 | x, _ := strconv.Atoi(f.Pop()) | 218 | x := toInt(f) |
| 211 | y := f.Pop() | 219 | y := f.Pop() |
| 212 | z := f.Pop() | 220 | z := f.Pop() |
| 213 | if x != 0 { | 221 | if x != 0 { |