@@ -74,7 +74,7 @@ func PrimitiveSetup(vm *VirtualMachine) error {
7474 if ! ok {
7575 return EntryError (entry , "requires an address cell" )
7676 }
77- name , err := cellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
77+ name , err := countedCellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
7878 if err != nil {
7979 return JoinEntryError (err , entry , "could not parse name" )
8080 }
@@ -130,7 +130,7 @@ func PrimitiveSetup(vm *VirtualMachine) error {
130130 if ! ok {
131131 return EntryError (entry , "requires an address cell" )
132132 }
133- name , err := cellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
133+ name , err := countedCellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
134134 if err != nil {
135135 return JoinEntryError (err , entry , "could not parse name" )
136136 }
@@ -510,7 +510,7 @@ func PrimitiveSetup(vm *VirtualMachine) error {
510510 if ! ok {
511511 return EntryError (entry , "requires an address cell" )
512512 }
513- name , err := cellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
513+ name , err := countedCellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
514514 if err != nil {
515515 return JoinEntryError (err , entry , "could not convert input to string" )
516516 }
@@ -548,6 +548,45 @@ func PrimitiveSetup(vm *VirtualMachine) error {
548548 return nil
549549 },
550550 },
551+ {
552+ name : "EVALUATE" ,
553+ goFunc : func (vm * VirtualMachine , entry * DictionaryEntry ) error {
554+ // get the size
555+ size , err := vm .Stack .PopNumber ()
556+ if err != nil {
557+ return PopError (err , entry )
558+ }
559+ // get the code
560+ cell , err := vm .Stack .Pop ()
561+ if err != nil {
562+ return JoinEntryError (err , entry , "could not pop code" )
563+ }
564+ cellAddr , ok := cell .(CellAddress )
565+ if ! ok {
566+ return EntryError (entry , "requires code" )
567+ }
568+ code , err := cellsToString (cellAddr .Entry .Word .(* WordForth ).Cells , int (size ), cellAddr .UpperByte )
569+ if err != nil {
570+ return JoinEntryError (err , entry , "could not parse code" )
571+ }
572+ // save the parse area
573+ err = vm .ParseArea .Save ()
574+ if err != nil {
575+ return JoinEntryError (err , entry , "could not save parse area" )
576+ }
577+ // execute
578+ err = vm .Execute ([]byte (code ))
579+ if err != nil {
580+ return JoinEntryError (err , entry , "error while executing: %s" , code )
581+ }
582+ // restore parse area
583+ err = vm .ParseArea .Restore ()
584+ if err != nil {
585+ return JoinEntryError (err , entry , "could not restore parse area" )
586+ }
587+ return nil
588+ },
589+ },
551590 {
552591 name : "EXECUTE" ,
553592 goFunc : func (vm * VirtualMachine , entry * DictionaryEntry ) error {
@@ -610,7 +649,7 @@ func PrimitiveSetup(vm *VirtualMachine) error {
610649 if ! ok {
611650 return EntryError (entry , "requires a name" )
612651 }
613- name , err := cellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
652+ name , err := countedCellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
614653 if err != nil {
615654 return JoinEntryError (err , entry , "could not parse name" )
616655 }
@@ -1365,6 +1404,12 @@ func PrimitiveSetup(vm *VirtualMachine) error {
13651404 return nil
13661405 }
13671406 return EntryError (entry , "could not subtract %s type %T from %s type %T due to types" , right , right , left , left )
1407+ case CellNumber :
1408+ err = vm .Stack .Push (CellAddress {r .Entry , r .Offset - int (l .Number ), false })
1409+ if err != nil {
1410+ return PushError (err , entry )
1411+ }
1412+ return nil
13681413 default :
13691414 return EntryError (entry , "could not subtract %s type %T from %s type %T due to types" , right , right , left , left )
13701415 }
@@ -2491,7 +2536,7 @@ func parseWord(vm *VirtualMachine, entry *DictionaryEntry) (string, error) {
24912536 if ! ok {
24922537 return "" , EntryError (entry , "name argument needs to be an address to a string" )
24932538 }
2494- name , err := cellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
2539+ name , err := countedCellsToString (cellAddr .Entry .Word .(* WordForth ).Cells )
24952540 if err != nil {
24962541 return "" , JoinEntryError (err , entry , "could not parse name" )
24972542 }
@@ -2511,7 +2556,7 @@ func parseAssembly(vm *VirtualMachine, entry *DictionaryEntry) ([]string, error)
25112556 }
25122557 switch c := cell .(type ) {
25132558 case CellAddress :
2514- substr , err := cellsToString (c .Entry .Word .(* WordForth ).Cells )
2559+ substr , err := countedCellsToString (c .Entry .Word .(* WordForth ).Cells )
25152560 if err != nil {
25162561 return nil , JoinEntryError (err , entry , "could not convert input to string" )
25172562 }
0 commit comments