[an error occurred while processing this directive]

  

; Библиотека для работы с текстовыми строками
; поддерживаются только счетные строки

; Дата написания: 30.08.94

; BorSoft
; Copyright 1994
; All rights reserved

; If You have some changes in this file
; PLEASE Call (095) 188-31-34 ( in Moscow )

; Содержание библиотеки:
;  ¤Constant - Объявить текстовую константу
;              Пример: ¤Constant MyGreating "Hello!!"
;               (

;  ¤Variable - Объявить текстовую переменную
;              Пример: 25 ¤Variable ForMyWork
;               (

;  ¤!        - Перености строку( как ! )
;              Пример: MyGreating MyWork ¤!

;  ¤"        - Принять из потока строку( на вых. адрес )
;              Пример: ¤" This is mine" outs>This is mine

;  ¤In       - Ввести строку 
;              Пример: ¤In>?MyString+<ENTER> outs>MyString

;  ¤Left     - Выделить левую часть строки
;              Пример: MyGreating 2 ¤Left outs>My

;  ¤Right    - Выделить правую часть строки 
;              Пример: MyGreating 8 ¤Right outs>Greating

;  ¤Mid      - Выделить середину строки
;              Пример: MyGreating 1 3 ¤Mid outs>yGr

;  ¤+        - Соединить строки в памяти
;              Пример: ForMyWork MyGreating ¤+ outs>
;                      MyGreatingMyGreating

;  ¤Compare  - Сравненить строк
;              Пример: ¤" FuckIt" MyGreating ¤Compare .>
;                      1

;- ¤Str      - Перевести одинарное число на стеке в строку
;              Пример: 23 ¤Str outs>23

;  
; Дополнительные возможности для работы с памятью:
;  InsString - Вставить строку в память 
;              Пример: 

;  Search    - Искать вхождение строки по памяти
;              Пример: 1000 MyGreating Search

;
; Дополнительные возможности со строками в памяти
;  SkipStr   - Пропустить строки в памяти
;              Пример: 5 SkipStr( -5 SkipStr )

;- Val       - Перевести строку в число на стеке
;              Формат: StrAdr 
;              Выход:  NumberL NumberH True/False

; Ncase      - Создать "аппаратный" переключатель для
;              кодов в стеке.
;              Пример: 1 2 2 ncase my two one default
;                      ^ ^ ^       ^  ^   ^   ^
;      первый код------+ ! !       !  !   !   + по-умолч.
;      второй код--------+ !       !  !   +-для кода 1
;     число кодов----------+       !  +-для кода 2
;                                  +-имя переключателя
; 
;                                   
; Начальная инициализация библиотеки
Strlib
 dfb ¤86
 asc "strliB"
 dw  Setmem
strlib  
 rts
 
; Уменьшим на 1 содержимое VREM
DecVrem
 lda Vrem
 bne justdvr
 dec Vrem+1
justdvr
 dec Vrem
 rts

; Двигаем строку( по ее адресу и длине по адресу )
movestr
 jsr StackVrem     Куда
 jsr Pop
 sta Vrem+4        Сколько
 jsr StackVrem2    Откуда
 ldy #¤0
 lda Vrem+4
 sta (Vrem),y      Запишем длину

b303
 lda Vrem+4
 beq allisdone
 lda (Vrem+2),y
 iny
 sta (Vrem),y
 dec Vrem+4
l300
 jmp b303

allisdone
 rts
 
; Oбъявим текстовую константу
Dconstant
 dfb ¤89,¤24
 asc "constanT"
 dw  Freeblock

dconstant
 jsr create
 jsr smug
 jsr lit
  dw KAVICHKI
 jsr word
 jsr here
 jsr cat
 jsr onep
 jsr allot     Запомним строку после слова
 jsr pscode                               

DCons
 pla
 tay
 pla
 iny
 bne b300
 clc
 adc #¤1
b300
 sty Vrem
 tay
 lda Vrem
     
 jmp PushNext        Выдаем адрес константы в стек

; Объявим место для текстовой переменной
Dvariable
 dfb ¤89,¤24
 asc "variablE"
 dw  Dconstant

dvariable
 jsr create
 jsr smug
 jsr allot
 jsr pscode
 
DVar
 pla
 tay
 pla
 iny
 bne b301
 clc
 adc #¤1
b301
 sty Vrem
 tay
 lda Vrem
     
 jmp PushNext        Выдаем адрес переменной в стек
 
; Перенесем строку( на верху стека КУДА ниже ОТКУДА )
Dstore
 dfb ¤82,¤24
 asc "!"
 dw  0

dstore
 jsr StackVrem     Куда
 jsr StackVrem2    Откуда
 ldy #¤0
 lda (Vrem+2),y    Число символов для переноса
 sta Vrem+4
 inc Vrem+4
    
movestr1
 lda Vrem+4
 beq allstrmove
 dec Vrem+4
 lda (Vrem+2),y
 sta (Vrem),y
 iny
 bne movestr1

allstrmove
 rts
 
; Принять строку из потока в PAD( ограничитель " )
Dquote
 dfb ¤c2,¤24
 asc ¤"¤
 dw  Dstore

dquote
 jsr lit
  dw KAVICHKI
 jsr state
 jsr at
 jsr zbran
  dw notcompmode-*-2
 
 jsr comp
l3001
  dw quote
 jsr word
 jsr here
 jsr cat
 jsr onep

 jmp allot

notcompmode
 jsr word
 jsr here
 jsr pad
l301
 jsr dstore

 jmp pad

quote
 jsr fromr
 jsr onep
 jsr dup
 jsr count
 jsr onem
 jsr plus
 jsr tor 
 
 rts


; Ввести строку из ввода в PAD( ограничитель <ENTER> )
Din
 dfb ¤83,¤24
 asc "iN"   
 dw  Con

din
 jsr pad
 jsr onep
 jsr t32
 jsr gets
 jsr span
 jsr at
 jsr pad
 jsr cstor

 jmp pad

; Выделить левую часть строки в PAD
Dleft
 dfb ¤85,¤24
 asc "lefT"
 dw  Getid

dleft
 jsr tor
 jsr count
 jsr fromr
 jsr min 
 jsr pad    
l302
 jsr movestr

 jmp pad

; Выделить правую часть строки в PAD
Dright
 dfb ¤86,¤24
 asc "righT"
 dw  Strlib

dright
 jsr tor
 jsr count
 jsr dup
 jsr fromr
 jsr min
 jsr tor     Реальное число символов справа на возвратах

 jsr i
 jsr sub
 jsr plus    Получим реальный адрес строки на стеке
 
 jsr fromr
 jsr pad
l303
 jsr movestr

 jmp pad
 
; Выделить середину строки в PAD( StrAdr From StrLen- )
Dmid
 dfb ¤84,¤24
 asc "miD"
 dw  Free

dmid
l304
 jsr makestr
 jsr pad
l305
 jsr movestr

 jmp pad
         
makestr
 jsr Pop
 sta Vrem+2
 jsr Pop
 sta Vrem+3
 jsr StackVrem
 ldy #¤0
 lda (Vrem),y
 sta Vrem+4
 cmp Vrem+3
 bcs noswap
 sta Vrem+3
noswap
 sec 
 sbc Vrem+3
 sta Vrem+5     Оставшаяся длина строки
 cmp Vrem+2
 bcs noclip     Если осталось>=чем нужно, то не обрезаем
 sta Vrem+2
noclip
 lda Vrem+3
 sec
 adc Vrem
 sta Vrem
 bcc noincvrem
 inc Vrem+1
noincvrem
 jsr VremStack
 lda Vrem+2
 ldy #¤0

 jmp PushNext

; Присоединить строку 1 к строке 2 и поместить в PAD
Dplus
 dfb ¤82,¤24
 asc "+"
 dw  Dquote

dplusa
 jsr tor
 jsr pad
l306
 jsr dstore
 jsr pad
 jsr count
 jsr plus        Получили адрес конца строки в PAD

 jsr fromr                                        
 jsr count
 jsr tor
 jsr i
 jsr rot         На стеке: Str2+1 Str2Len Pad+Str1Len-
 jsr swap
 jsr cmove

 jsr pad         Изменим длину строки
 jsr cat
 jsr fromr
 jsr plus 
 jsr pad
 jsr cstor

 jmp pad

; Сравнить посимвольно две строки на стек результат:
; 0 :строки равны
; 1 :1 строка >
; -1:2 строка >
Dcompare
 dfb ¤88,¤24
 asc "comparE"
 dw  Getmembl
dcompare
 
 jsr StackVrem     Восстановим адреса строк в VREM, VREM+2
 jsr StackVrem2                                      
 
 ldy #¤0
 lda (Vrem),y
 cmp (Vrem+2),y
 bcc firstless
 lda (Vrem+2),y
firstless
 sta Vrem+4        Длина строк выровнена
  
nextsymb
 iny
 lda Vrem+4
 beq equals
 dec Vrem+4
 lda (Vrem),y
 cmp (Vrem+2),y
 beq nextsymb
 bcs greata
     
lessa
 lda #¤ff
b310
 tay
b398
 jmp PushNext

greata
 lda #¤1
 ldy #¤0
 beq b398
 
equals
 lda #¤0
 beq b310

; Скопируем как CMOVE только от старших к младшим адресов
Lscmove
 dfb ¤86,¤3c
 asc "cmovE"
 dw  Dright
lscmove
 
 jsr Pop
 sta Vrem+4
 sty Vrem+5      Восстановим длину копируемого блока
 
 jsr StackVrem   Куда
 jsr StackVrem2  Откуда
   
 ldy #¤0

 lda Vrem+4      Установимся на конец КУДА
 clc
 adc Vrem
 sta Vrem
 lda Vrem+5
 adc Vrem+1
 sta Vrem+1                               
 
 lda Vrem+4      Установимся на конец ОТКУДА
 clc
 adc Vrem+2
 sta Vrem+2
 lda Vrem+5
 adc Vrem+3
 sta Vrem+3                                 
           
copyit
 lda (Vrem+2),y
 sta (Vrem),y

 lda Vrem
 bne b311
 dec Vrem+1
b311
 dec Vrem
 lda Vrem+2
 bne b312
 dec Vrem+3
b312
 dec Vrem+2

 lda Vrem+4
 bne b313
 lda Vrem+5
 beq alldone
 dec Vrem+5
b313
 dec Vrem+4
    
l308
 jmp copyit

alldone
 rts

; Перевести число на стеке в строку на PAD


; Вставить строку в память( для текстового редактора )
; на стеке: MemAdr MemBlockLen DeltaMem-
; если DELTAMEM<0, то нужно смыкать, иначе размыкать
Insstring
 dfb ¤89
 asc "insstrinG"
 dw  Dvariable
insstring
 
 jsr Pop
 sta Vrem+8
 sty Vrem+9
 ora #¤0
 beq notneedmove
 
 jsr StackVrem2
 jsr StackVrem
 
 lda Vrem+9
 bmi justcmove

; Здесь готовим переход на <CMOVE( раздвинем )
 inx
 inx
 clc       
 lda Vrem+8
 adc Vrem
 sta Vrem
 bcc b314
 inc Vrem+1    Увеличим адрес КУДА
b314
 jsr VremStack
 jsr Vrem2Stack
    
l309
 jmp lscmove
 
; Здесь готовим переход на CMOVE( сдвинем )
justcmove
 sec
 lda Vrem
 sbc Vrem+8
 pha
 lda Vrem+1
 sbc Vrem+9
 tay
 pla
 jsr Push
 jsr VremStack       
 jsr Vrem2Stack
    
 jmp cmove
 
; Здесь не нужно ничего
notneedmove
 jmp ddrop

; Искать строку в интервале памяти( LimAdr BegAdr StrAdr )
Search
 dfb ¤86
 asc "searcH"
 dw  Lscmove

search     
 jsr StackVrem
 ldy #¤0
 lda (Vrem),y
 sta Vrem+4
 jsr IncVrem
 jsr StackVrem2
 jsr Pop
 sta Vrem+6         Предел для поиска
 sty Vrem+7                          
 
searchit
 lda Vrem+3
 cmp Vrem+7
 bne contsearch
 lda Vrem+2
 cmp Vrem+6
 beq endreach
      
contsearch
 ldy #¤0    
contony
 lda (Vrem),y
 cmp (Vrem+2),y
 bne nextx
 iny
 cpy Vrem+4
 bne contony

; Здесь мы нашли нашу строку и выдадим в стек ее адрес
; ( строка понятно несчетная )
 jsr Vrem2Stack

 jmp TrueFlag
 
nextx
 inc Vrem+2
 bne searchit
 inc Vrem+3  
 bne searchit
 
endreach
 jmp FalseFlag

; Пропустить строку( и ) в памяти( ограничитель <ВВОД> )
Skipstr
 dfb ¤87
 asc "skipstR"
 dw  Setvmem

skipstr
 jsr StackVrem2
 jsr StackVrem 
 ldy #¤0
 lda Vrem+3
 bmi backward1

; Здесь прямой пропуск строк в памяти
forward
 lda Vrem+2
 bne ntstvr3
 lda Vrem+3
 beq allskipf
 dec Vrem+3
ntstvr3  
 dec Vrem+2
           
nextss
 lda (Vrem),y
 beq allskipf        Нулевая строка
 cmp #ENTERKEY
 beq nextss1
 jsr IncVrem
l311
 jmp nextss
nextss1
 jsr IncVrem

l312
 jmp forward

; Здесь обратный пропуск строк в памяти
backward1
 lda (Vrem),y
 beq allskipbz

backward
 lda Vrem+2
 bne rrr
 lda Vrem+3
 beq allskipf
rrr
 inc Vrem+2
 bne rrrrr
 inc Vrem+3
rrrrr  

; Ищем конец предыдущей строки
prevss       
l313
 jsr DecVrem
 lda (Vrem),y
 beq allskipf
 cmp #ENTERKEY
 bne prevss
 
; Нашли конец- ищем начало
searchbstr  
l319
 jsr DecVrem
 lda (Vrem),y
 beq titix
 cmp #ENTERKEY
 bne searchbstr
titix
 jsr IncVrem
 bne backward
 
allskipf
 jmp VremStack   В стек адрес начала строки после пропуска
         
allskipbz
l315
 jsr DecVrem

 jmp VremStack
 
; Измерим длину строки, ограниченной <ENTER>
Strln
 dfb ¤85
 asc "strlN"
 dw  Dleft
strln

 jsr StackVrem
 ldy #¤1
 sty Vrem+2   
 dey
lookenter
 lda (Vrem),y
 beq nlstr
 cmp #ENTERKEY
 beq allstr
 inc Vrem+2
 iny 
 bne lookenter
 inc Vrem+1
 bne lookenter
    
nlstr
 lda #¤0
 sta Vrem+2

allstr
 lda Vrem+2
 ldy #¤0     

 jmp PushNext

; Процедура стуктуризации программы 
; формат обращения: KeyCode1 . . . . KeyCodeN N
;                   NCase <NAMECASE> 
;                  KeyProcN . . . . KeyProc1 ProcOtherWise
Ncase
 dfb ¤c5
 asc "ncasE"
 dw  Strln

ncase
 jsr create
 jsr rbrac
 jsr dup
 jsr ccom
 jsr zero
 jsr xdo
       
caseloop
 jsr dfind
 jsr zequ
 jsr lit
  dw NOTFOUND
 jsr qerr

 jsr drop
 jsr cfa
 
 jsr i
 jsr srp
 jsr equal
 jsr nzbran
  dw notcomkey-*-2
 jsr swap
 jsr ccom  Скомпилируем ее ключ

notcomkey
 jsr comma Скомпилируем адрес процедуры
 
 jsr xloo
  dw caseloop-*-2
 jsr lbrac
 jsr pscode

; Реальный ПЕРЕКЛЮЧАТЕЛЬ
 pla
 sta Vrem
 pla 
 sta Vrem+1
 ldy #¤1
 lda (Vrem),y
 sta Vrem+2
 jsr Pop
 ldy #¤2
nextkey
 cmp (Vrem),y
 beq findkey
 iny
 iny
 iny
 dec Vrem+2
 bne nextkey
 dey

findkey
 iny
 lda (Vrem),y
 sta Vrem+2
 iny
 lda (Vrem),y
 tay
 lda Vrem+2
 jsr Push
 
 jmp exec
 
; Подсчет строк текста по начальному и конечному адресу
Countstr
 dfb ¤88
 asc "countstR"
 dw  Dcompare

countstr
 jsr StackVrem
 jsr StackVrem2
 ldy Vrem+2
 lda #¤0
 sta Vrem+2  
 sta Vrem+4       Число строк уже пройденных
     
check4lim
 cpy Vrem
 bne contcount
 lda Vrem+1
 cmp Vrem+3
 bne contcount
 
 lda Vrem+4
 ldy #¤0

 jmp PushNext

contcount
 lda (Vrem+2),y
 cmp #ENTERKEY
 bne incworkadr
 inc Vrem+4
incworkadr
 iny
 bne check4lim
 inc Vrem+3
 bne check4lim
     
; Переведем счетную строку в число на стеке и флаг
Dval
 dfb ¤84,¤24
 asc "vaL"
 dw  Dmid

dval
 jsr dup
 jsr tor
 jsr ifnotdig
 jsr tor
 jsr rot
 jsr drop
 jsr fromr
 jsr fromr
 jsr count
 jsr plus

 jmp equal
 
; Переведем счетнуя строку в число на стеке
Val
 dfb ¤83
 asc "vaL"
 dw  Din

val
l320
 jsr dval

 jmp drop

EndLib
[an error occurred while processing this directive]