Я пытаюсь написать текстовый редактор, имитирующий формат ввода ed
. В ed
вы пишете ввод по одной строке за раз и заканчиваете, когда вводите один .
в строке. Вот что я придумал:
0 [
[ readln [ "." = not ] keep swap ] dip 1 + swap
] loop
nip 1 - narray
Этот фрагмент получает ввод от пользователя по одной строке за раз, останавливается, когда достигает одной точки, и возвращает массив строк.
Я не получаю никаких ошибок, когда это само по себе, но как только я пытаюсь выразить это словами:
: getinput ( -- input )
0 [
[ readln [ "." = not ] keep swap ] dip 1 + swap
] loop
nip 1 -
narray
;
Я получаю следующую ошибку:
The input quotation to “loop” doesn't match its expected effect
Input Expected Got
[ ~quotation~ dip 1 + swap ] ( ... -- ... ? ) ( x -- x x x )
(U) Quotation: [ c-to-factor -> ]
...
Я думаю, что это может быть связано с тем, что компилятор не заботится об объявлении стека, когда оно не в слове, а когда оно есть. Он недоволен изменением стека под циклом? Я знаю о call( )
, но если мне нужно использовать его здесь, то как?
Изменить: я также только что попробовал следующее:
:: getinput ( -- input )
0 :> count!
[ [ "." = not ] keep swap ]
[ readln count 1 + count! ] do while
drop count 1 - narray
;
Я получаю аналогичную ошибку, однако эффекты стека немного отличаются:
The input quotations to “while” don't match their expected effects
Input Expected Got
[ ~quotation~ keep swap ] ( ..a -- ..b ? ) ( x -- x x )
[ _ 1 load-locals readln 0 get-local local-value 1 + 0 get-local... ( ..b -- ..a ) ( -- x )
(U) Quotation: [ c-to-factor -> ]
...
Опять же, хорошо сам по себе, но, одним словом, он не компилируется.