func shuffle(v vector.Vector) { for i := len(v) - 1; i >= 1; i-- { j := rand.Intn(i) v.Swap(i, j) } }
func parse_forth(dat string, DataStack *vector.Vector) { L := DataStack.Len() switch strings.TrimSpace(string(dat)) { case "": case "<cr>": return case "t": //check the DataStack size using the popped value // if it passes, then the program continues minimum := int(DataStack.Pop().(float32)) if DataStack.Len() < minimum { log.Println("DataStack has not enough minerals (values)") } case ".": log.Println(DataStack.Pop()) case "0SP": DataStack.Cut(0, L) case ".S": log.Println(DataStack) case "2/": DataStack.Push(DataStack.Pop().(float32) / 2) case "2*": DataStack.Push(DataStack.Pop().(float32) * 2) case "2-": DataStack.Push(DataStack.Pop().(float32) - 2) case "2+": DataStack.Push(DataStack.Pop().(float32) + 2) case "1-": DataStack.Push(DataStack.Pop().(float32) - 1) case "1+": DataStack.Push(DataStack.Pop().(float32) + 1) case "DUP": DataStack.Push(DataStack.Last()) case "?DUP": if DataStack.Last().(float32) != 0 { DataStack.Push(DataStack.Last().(float32)) } case "PICK": number := int(DataStack.Pop().(float32)) if number < L { DataStack.Push(DataStack.At(L - 1 - number).(float32)) } else { log.Fatal("picking out of stack not allowed. Stack Length: " + string(L) + ". Selecting: " + string(number) + ".") return } case "TUCK": DataStack.Insert(L-2, int(DataStack.Last().(float32))) case "NIP": DataStack.Delete(L - 2) case "2DROP": DataStack.Pop() DataStack.Pop() case "2DUP": DataStack.Push(DataStack.At(L - 2)) DataStack.Push(DataStack.At(DataStack.Len() - 2)) case "DROP": DataStack.Pop() case "OVER": DataStack.Push(DataStack.At(L - 2)) case "SWAP": l := DataStack.Len() DataStack.Swap(l-2, l-1) case "*": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num1 * num2) case "+": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num1 + num2) case "-": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num2 - num1) case "/": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num2 / num1) case "-ROT": DataStack.Swap(L-1, L-2) DataStack.Swap(L-2, L-3) case "ROT": DataStack.Swap(L-3, L-2) DataStack.Swap(L-2, L-1) case "2OVER": DataStack.Push(DataStack.At(L - 4)) DataStack.Push(DataStack.At(DataStack.Len() - 4)) case "2SWAP": DataStack.Swap(L-4, L-2) DataStack.Swap(L-3, L-1) case "EMIT": log.Println(string([]byte{uint8(DataStack.Last().(float32))})) default: val, ok := strconv.Atof32(dat) if ok == nil { DataStack.Push(val) } else { log.Println(ok) log.Fatalln("error, unknown token \"" + dat + "\"") } } }