Commits

Anonymous committed 3f4a171

Add command to support adding new commands from basic words.
Mainly, this is testing my ability to use closures.
We really could add the ':' command but ...
I'm not really trying for the full enchilada here. Just a simple
parser for computation on command line parameters.

Comments (0)

Files changed (2)

 	{"4095 4096 roundup", "4096", ""},
 	{"4097 8192 roundup", "8192", ""},
 	{"2 x +", "", "parsing \"x\": invalid syntax"},
+	{"1 dd +", "2", ""},
+	{"1 d3d", "3", ""},
 }
 
 func TestForth(t *testing.T) {
 	if f.Empty() != true {
 		t.Errorf("Test: After Reset(): stack is %v and should be true", f.Empty())
 	}
+	NewWord(f, "dd", "dup")
+	NewWord(f, "d3d", "dup dup + +")
 	for _, tt := range forthTests {
 		var err error
 		res, err := Eval(f, tt.val)
 			fmt.Printf("Test: '%v' '%v' '%v': Pass\n", tt.val, res, err)
 		} else {
 			t.Errorf("Test: '%v' '%v' '%v': Fail\n", tt.val, res, err)
+			fmt.Printf("ops %v\n", Ops())
 		}
 		if f.Length() != 0 {
 			t.Errorf("Test: %v: stack is %d and should be empty", tt, f.Length())
 	Empty() bool
 	Newop(string, forthop)
 	Reset()
+	Stack()[]string
 }
 
 // New creates a new stack
 	opmap[n] = op
 }
 
+func  Ops() (map[string] forthop){
+	return opmap
+}
 // Reset resets the stack to empty
 func (f *forthstack) Reset() {
 	f.stack = f.stack[0:0]
 }
+// Return the stack as a []string
+func (f *forthstack) Stack() []string{
+	return f.stack
+}
 
 // Push pushes the string on the stack. 
 func (f *forthstack) Push(s string) {
 	}
 }
 
-/* Eval takes a Forth and strings and splits the string on space
+/* iEval takes a Forth and strings and splits the string on space
  * characters, pushing each element on the stack or invoking the 
- * operator if it is found in the opmap. It returns TOS when it is done. 
- * it is an error to leave the stack non-Empty. 
+ * operator if it is found in the opmap. 
  */
-func Eval(f Forth, s string) (ret string, err error) {
-	defer errRecover(&err)
+func iEval(f Forth, s string) {
 	for _, val := range strings.Split(s, " ") {
 		/* two or more spaces can have odd results */
 		if len(val) == 0 || val == " " {
 			f.Push(val)
 		}
 	}
+	return
+}
+/* Eval takes a Forth and strings and splits the string on space
+ * characters, pushing each element on the stack or invoking the 
+ * operator if it is found in the opmap. It returns TOS when it is done. 
+ * it is an error to leave the stack non-Empty. 
+ */
+func Eval(f Forth, s string) (ret string, err error) {
+	defer errRecover(&err)
+	iEval(f, s)
 	ret = f.Pop()
 	return
 
 	host := f.Pop()
 	f.Push(strings.TrimLeft(host, "abcdefghijklmnopqrstuvwxyz -"))
 }
+
+func NewWord(f Forth, name, command string) {
+	newword := func(f Forth) {
+		iEval(f, command)
+		return
+	}
+	opmap[name] = newword
+	return
+}
+