Skip to content

Commit f8d2c2d

Browse files
committed
Extend S" C" and ." so they can be interpreted.
Max length of strings made with S" and ." increased from 255 to 65535 characters. Saves 1 byte per usage when cross compiling.
1 parent c2e6e9a commit f8d2c2d

File tree

4 files changed

+79
-8
lines changed

4 files changed

+79
-8
lines changed

pkg/forth/builtin/02_core.f

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,22 @@
227227
COMPILE, \ and compile it!
228228
; IMMEDIATE
229229
: COUNT ( c-addr -- c-addr+1 n ) DUP CHAR+ SWAP C@ ;
230-
: STRING" '"' WORD ; \ read a string and put it on the stack
231-
: C" STRING" POSTPONE LITERAL ; IMMEDIATE
232-
: S" STRING" COUNT SWAP POSTPONE LITERAL POSTPONE LITERAL ; IMMEDIATE
230+
: STRING" '"' WORD ; ( -- c-addr ) \ read a string and put it on the stack as a counted string
231+
: LSTRING" '"' LWORD ; ( -- addr u ) \ read a string and put it on the stack as a string and length
232+
: C" \ this is an extended C" to allow it to run while interpreting
233+
STRING" \ always parse the counted string
234+
STATE @ IF \ but if we're compiling,
235+
POSTPONE LITERAL \ compile the output
236+
THEN
237+
; IMMEDIATE
238+
239+
: S" \ this is the extended mechanics of S" to allow it to run while interpreting
240+
LSTRING" \ always parse the string
241+
STATE @ IF \ but if we're compiling,
242+
SWAP POSTPONE LITERAL POSTPONE LITERAL \ compile the output
243+
THEN
244+
; IMMEDIATE
245+
233246
: [CHAR]
234247
BL WORD \ get the next word
235248
COUNT DROP \ get the address of the first letter

pkg/forth/builtin/10_print.f

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,15 @@
5656
DROP \ remove c-addr
5757
;
5858

59-
: ." POSTPONE S" POSTPONE TYPE ; IMMEDIATE
59+
\ Can be used to print a string while interpreting or compiling.
60+
: ."
61+
POSTPONE S"
62+
STATE @ IF
63+
POSTPONE TYPE
64+
ELSE
65+
TYPE
66+
THEN
67+
; IMMEDIATE
6068

6169
\ set EMIT to the system printchar by default
6270
' ESP.PRINTCHAR IS EMIT

pkg/forth/primitive.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func PrimitiveSetup(vm *VirtualMachine) error {
8787
},
8888
},
8989
{
90-
name: "WORD",
90+
name: "WORD", // returns a counted string
9191
goFunc: func(vm *VirtualMachine, entry *DictionaryEntry) error {
9292
n, err := vm.Stack.PopNumber()
9393
if err != nil {
@@ -98,7 +98,8 @@ func PrimitiveSetup(vm *VirtualMachine) error {
9898
return JoinEntryError(err, entry, "could not parse string")
9999
}
100100
var de DictionaryEntry
101-
cells, err := bytesToCells(str, true)
101+
counted := true
102+
cells, err := bytesToCells(str, counted)
102103
if err != nil {
103104
return JoinEntryError(err, entry, "could not convert bytes to cells")
104105
}
@@ -119,6 +120,44 @@ func PrimitiveSetup(vm *VirtualMachine) error {
119120
return nil
120121
},
121122
},
123+
{
124+
name: "LWORD", // returns a string and length
125+
goFunc: func(vm *VirtualMachine, entry *DictionaryEntry) error {
126+
n, err := vm.Stack.PopNumber()
127+
if err != nil {
128+
return JoinEntryError(err, entry, "could not pop delimiter")
129+
}
130+
str, err := vm.ParseArea.Word(byte(n))
131+
if err != nil {
132+
return JoinEntryError(err, entry, "could not parse string")
133+
}
134+
var de DictionaryEntry
135+
counted := false
136+
cells, err := bytesToCells(str, counted)
137+
if err != nil {
138+
return JoinEntryError(err, entry, "could not convert bytes to cells")
139+
}
140+
w := WordForth{cells, &de}
141+
de = DictionaryEntry{
142+
Word: &w,
143+
Flag: Flag{Data: true},
144+
}
145+
c := CellAddress{
146+
Entry: &de,
147+
Offset: 0,
148+
UpperByte: false,
149+
}
150+
err = vm.Stack.Push(c)
151+
if err != nil {
152+
return JoinEntryError(err, entry, "could not push address")
153+
}
154+
err = vm.Stack.Push(CellNumber{uint16(len(str))})
155+
if err != nil {
156+
return JoinEntryError(err, entry, "could not push length")
157+
}
158+
return nil
159+
},
160+
},
122161
{
123162
name: "--CREATE-FORTH",
124163
goFunc: func(vm *VirtualMachine, entry *DictionaryEntry) error {

pkg/forth/suite_test.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,17 @@ func TestSuite(t *testing.T) {
366366
T{ 1S 1ST ! 1ST @ -> 1S }T \ CAN STORE CELL-WIDE VALUE
367367
`,
368368
},
369-
// C"
369+
{
370+
name: "C\"",
371+
setup: `
372+
T{ : cq1 C" 123" ; -> }T
373+
T{ : cq2 C" " ; -> }T
374+
T{ cq1 COUNT EVALUATE -> 123 }T
375+
T{ cq2 COUNT EVALUATE -> }T
376+
\ This test is nonstandard, C" can be interpreted
377+
T{ C" A String"DROP -> }T \ There is no space between the " and 2DROP
378+
`,
379+
},
370380
// DECIMAL does not have any tests
371381
{
372382
name: "DEFER",
@@ -1000,14 +1010,15 @@ func TestSuite(t *testing.T) {
10001010
setup: `
10011011
T{ : GC4 S" XY" ; -> }T
10021012
T{ : GC5 S" A String"2DROP ; -> }T \ There is no space between the " and 2DROP
1013+
\ This test is from an extended mechanic, S" can be interpreted
1014+
T{ S" A String"2DROP -> }T \ There is no space between the " and 2DROP
10031015
`,
10041016
code: `
10051017
T{ GC4 SWAP DROP -> 2 }T
10061018
T{ GC4 DROP DUP C@ SWAP CHAR+ C@ -> 58 59 }T
10071019
T{ GC5 -> }T
10081020
`,
10091021
},
1010-
// S"
10111022
{
10121023
name: "S>D",
10131024
code: `

0 commit comments

Comments
 (0)