@@ -93,7 +93,7 @@ func PrimitiveSetup(vm *VirtualMachine) error {
9393 if err != nil {
9494 return JoinEntryError (err , entry , "could not pop delimiter" )
9595 }
96- str , err := vm .ParseArea .Word (byte (n ))
96+ str , err := vm .ParseArea .Word (byte (n ), false )
9797 if err != nil {
9898 return JoinEntryError (err , entry , "could not parse string" )
9999 }
@@ -127,7 +127,7 @@ func PrimitiveSetup(vm *VirtualMachine) error {
127127 if err != nil {
128128 return JoinEntryError (err , entry , "could not pop delimiter" )
129129 }
130- str , err := vm .ParseArea .Word (byte (n ))
130+ str , err := vm .ParseArea .Word (byte (n ), false )
131131 if err != nil {
132132 return JoinEntryError (err , entry , "could not parse string" )
133133 }
@@ -158,6 +158,83 @@ func PrimitiveSetup(vm *VirtualMachine) error {
158158 return nil
159159 },
160160 },
161+ {
162+ name : "LWORDESCAPED" , // returns a string and length
163+ goFunc : func (vm * VirtualMachine , entry * DictionaryEntry ) error {
164+ delim16 , err := vm .Stack .PopNumber ()
165+ if err != nil {
166+ return JoinEntryError (err , entry , "could not pop delimiter" )
167+ }
168+ delim := byte (delim16 )
169+ bytes , err := vm .ParseArea .Word (delim , true )
170+ if err != nil {
171+ return JoinEntryError (err , entry , "could not parse string" )
172+ }
173+ str := make ([]byte , 0 )
174+ translation := map [byte ][]byte {
175+ 'a' : {7 },
176+ 'b' : {8 },
177+ 'e' : {27 },
178+ 'f' : {12 },
179+ 'l' : {10 },
180+ 'm' : {13 , 10 },
181+ 'n' : {10 }, // just LF
182+ 'q' : {34 },
183+ 'r' : {13 },
184+ 't' : {9 },
185+ 'v' : {11 },
186+ 'z' : {0 },
187+ '"' : {34 },
188+ '\\' : {92 },
189+ // nonstandard: allow parsing a different delimiter
190+ delim : {delim },
191+ }
192+ var i int
193+ for i = 0 ; i < len (bytes )- 1 ; i ++ {
194+ b := bytes [i ]
195+ if b == '\\' {
196+ i += 1
197+ next := bytes [i ]
198+ replace , ok := translation [next ]
199+ if ok {
200+ str = append (str , replace ... )
201+ } else {
202+ return EntryError (entry , "unknown escape character %c %d" , next , next )
203+ }
204+ } else {
205+ str = append (str , b )
206+ }
207+ }
208+ if i == len (bytes )- 1 {
209+ str = append (str , bytes [i ]) // append whatever the final byte is
210+ }
211+ var de DictionaryEntry
212+ counted := false
213+ cells , err := bytesToCells (str , counted )
214+ if err != nil {
215+ return JoinEntryError (err , entry , "could not convert bytes to cells" )
216+ }
217+ w := WordForth {cells , & de }
218+ de = DictionaryEntry {
219+ Word : & w ,
220+ Flag : Flag {Data : true },
221+ }
222+ c := CellAddress {
223+ Entry : & de ,
224+ Offset : 0 ,
225+ UpperByte : false ,
226+ }
227+ err = vm .Stack .Push (c )
228+ if err != nil {
229+ return JoinEntryError (err , entry , "could not push address" )
230+ }
231+ err = vm .Stack .Push (CellNumber {uint16 (len (str ))})
232+ if err != nil {
233+ return JoinEntryError (err , entry , "could not push length" )
234+ }
235+ return nil
236+ },
237+ },
161238 {
162239 name : "--CREATE-FORTH" ,
163240 goFunc : func (vm * VirtualMachine , entry * DictionaryEntry ) error {
0 commit comments