- ABORT
- ABORT"
- ABS
- ACCEPT
- ACTION-OF
- AGAIN
- ALIGN
- ALIGNED
- ALLOT
- AND
- BASE
- BEGIN
- BL
- BUFFER:
- [
- [CHAR]
- [COMPILE]
- [']
- CASE
- C,
- CELL+
- CELLS
- C@
- CHAR
- CHAR+
- CHARS
- COMPILE,
- CONSTANT
- COUNT
- CR
- CREATE
- C!
- :
- :NONAME
- ,
- C"
- DECIMAL
- DEFER
- DEFER@
- DEFER!
- DEPTH
- DO
- DOES>
- DROP
- DUP
- /
- /MOD
- .R
- .(
- ."
- ELSE
- EMIT
- ENDCASE
- ENDOF
- ENVIRONMENT?
- ERASE
- EVALUATE
- EXECUTE
- EXIT
- =
- FALSE
- FILL
- FIND
- FM/MOD
- @
- HERE
- HEX
- HOLD
- HOLDS
- I
- IF
- IMMEDIATE
- INVERT
- IS
- J
- KEY
- LEAVE
- LITERAL
- LOOP
- LSHIFT
- MARKER
- MAX
- MIN
- MOD
- MOVE
- M*
- -
- NEGATE
- NIP
- OF
- OR
- OVER
- 1-
- 1+
- PAD
- PARSE-NAME
- PARSE
- PICK
- POSTPONE
- +
- +LOOP
- +!
- QUIT
- RECURSE
- REFILL
- REPEAT
- RESTORE-INPUT
- R@
- ROLL
- ROT
- RSHIFT
- R>
- SAVE-INPUT
- SIGN
- SM/REM
- SOURCE-ID
- SOURCE
- SPACE
- SPACES
- STATE
- SWAP
- ;
- S\"
- S"
- S>D
- !
- THEN
- TO
- TRUE
- TUCK
- TYPE
- '
- *
- */
- */MOD
- 2DROP
- 2DUP
- 2/
- 2@
- 2OVER
- 2R@
- 2R>
- 2SWAP
- 2!
- 2*
- 2>R
- U.R
- UM/MOD
- UM*
- UNLOOP
- UNTIL
- UNUSED
- U.
- U<
- U>
- VALUE
- VARIABLE
- WHILE
- WITHIN
- WORD
- XOR
- 0=
- 0<
- 0>
- 0<>
- \
- .
- <
- >
- <>
- #>
- <#
- #
- #S
- (
- ?DO
- ?DUP
- >BODY
- >IN
- >NUMBER
- >R
6.2.2182 SAVE-INPUT CORE EXT
x1 through xn describe the current state of the input source specification for later use by RESTORE-INPUT.
See:
Rationale:
SAVE-INPUT and RESTORE-INPUT are intended for repositioning within a single input source; for example, the following scenario is NOT allowed for a Standard Program:
This is incorrect because, at the time RESTORE-INPUT is executed, the input source is the string via EVALUATE, which is not the same input source that was in effect when SAVE-INPUT was executed.
The following code is allowed:
After EVALUATE returns, the input source specification
is restored to its previous state, thus
SAVE-
INPUT
and RESTORE-INPUT are called with the same input source
in effect.
In the above examples, the EVALUATE phrase could have been replaced by a phrase involving INCLUDE-FILE and the same rules would apply.
The standard does not specify what happens if a program violates the above rules. A Standard System might check for the violation and return an exception indication from RESTORE-INPUT, or it might fail in an unpredictable way.
The return value from RESTORE-INPUT is primarily intended to report the case where the program attempts to restore the position of an input source whose position cannot be restored. The keyboard might be such an input source.
Nesting of SAVE-INPUT and RESTORE-INPUT is allowed. For example, the following situation works as expected:
In principle, RESTORE-INPUT could be implemented to "always fail", e.g.:
Such an implementation would not be useful in most cases. It would be preferable for a system to leave SAVE-INPUT and RESTORE-INPUT undefined, rather than to create a useless implementation. In the absence of the words, the application programmer could choose whether or not to create "dummy" implementations or to work-around the problem in some other way.
Examples of how an implementation might use the return values from SAVE-INPUT to accomplish the save/restore function:
| Input Source | possible stack values | |||
| block | >IN @ | BLK @ | 2 | |
| EVALUATE | >IN @ | 1 | ||
| keyboard | >IN @ | 1 | ||
| text file | >IN @ | lo-pos | hi-pos | 3 |
These are examples only; a Standard Program may not assume any particular meaning for the individual stack items returned by SAVE-INPUT.
Testing:
VARIABLE siv -1 siv !
: NeverExecuted
." This should never be executed" ABORT
;
11111 SAVE-INPUT
siv @
[IF]
0 siv !
RESTORE-INPUT
NeverExecuted
[ELSE]
\ Testing the ELSE part is executed
22222
[THEN]
T{ -> 11111 0 22222 }T \ 0 comes from RESTORE-INPUT
Testing with a string source
VARIABLE si_inc 0 si_inc !
: si1
si_inc @ >IN +!
15 si_inc !
;
: s$ S" SAVE-INPUT si1 RESTORE-INPUT 12345" ;
T{ s$ EVALUATE si_inc @ -> 0 2345 15 }T
Testing nesting
: read_a_line
REFILL 0=
ABORT" REFILL failed"
;
0 si_inc !
2VARIABLE 2res -1. 2res 2!
: si2
read_a_line
read_a_line
SAVE-INPUT
read_a_line
read_a_line
s$ EVALUATE 2res 2!
RESTORE-INPUT
;
WARNING: do not delete or insert lines of text after si2 is called otherwise the next test will fail
si2
33333 \ This line should be ignored
2res 2@ 44444 \ RESTORE-INPUT should return to this line
55555
T{ -> 0 0 2345 44444 55555 }T
ContributeContributions
FrancoisLaagel
[265] Bogus Test Case for SAVE-INPUTSuggested Testcase2022-09-06 14:36:57
In the "Testing" NeverExecuted obviously is executed and that's the end of it!
JohanKotlinski
[282] Is data stack required?Request for clarification2023-02-14 20:17:30
Is it a requirement that SAVE-INPUT and RESTORE-INPUT saves the state on the data stack?
I would prefer if it was allowed to keep the state on some other stack. (my Forth has a very limited data stack space)
AbstractionFirst
[437] A language standard should specify abstractions rather than mechanismsComment2026-07-18 19:38:23
I would like to raise a more general design question rather than the specific semantics of SAVE-INPUT itself.
One of the primary goals of a language standard is to specify observable semantics while leaving implementation details to implementors whenever possible.
This raises the following question:
Can a portable application express a requirement that naturally maps to SAVE-INPUT?
In practice, application programs manipulate data, define new words, parse text, compile code, evaluate strings, and process files. They naturally use words such as PARSE, EVALUATE, REFILL, and POSTPONE.
SAVE-INPUT and RESTORE-INPUTappear to belong to a different category. They expose and preserve the internal state of the input-processing mechanism rather than providing an application-level abstraction.
If these words are intended primarily for implementors of Forth systems rather than for portable application programs, should they really be part of the standard application interface?
More generally, should a language standard expose implementation mechanisms, or should it specify only the observable behavior required of a conforming system?
I believe this distinction deserves discussion because it directly affects implementation freedom without changing observable language semantics.