Last active
August 29, 2015 14:22
-
-
Save MisterTimur/9657201c447f736cd375 to your computer and use it in GitHub Desktop.
programming language ATR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;{ AbdUlov Timur Rifovich 2015 programming language ATR ------------------------ | |
; https://sites.google.com/site/timpascallib/atr | |
; Еще не доделан чуток осталося дописать | |
; in the development not completed | |
;} | |
org 100h ;{ Стартовый адрес програмы ------------------------------------------- | |
;call InitMem; | |
;--------------------------------------------- | |
call ReadPro ; Разбиваем программу на слова | |
;--------------------------------------------- | |
mov ah,'(' ; Вкладываем скобки | |
mov al,')' ; | |
call COM_SCO ; | |
;--------------------------------------------- | |
mov ah,'{' ; Вкладываем фигурные скобки | |
mov al,'}' ; | |
call COM_SCO ; | |
;--------------------------------------------- | |
call COM_BLO ; | |
;--------------------------------------------- | |
call COM_MA1 ; Вкладываем мат операции 1 | |
call COM_MA3 ; Вкладываем мат операции 2 | |
;--------------------------------------------- | |
;call ELS_VIE ;// ПРосмотр структуры | |
Call FUN_RUS ; Выполнение программы | |
;--------------------------------------------- | |
;call ELE_COP ; | |
;call ELS_VIE ;// ПРосмотр структуры | |
call Exitf ; | |
;} | |
;{ Для работы с элементами ----------------------------------------------------- | |
ELE_CRE: ;{ Возвращает в регистре DI адрес созданого Элемента | |
pushad ; сохраняем регистры | |
Mov di,TrMe ; Читаем адрес начала кучи | |
.Cik: mov al,[di]; ; Ищим свободное место для елемента | |
test al,al ; ПРоверяем свободно ли это место | |
jz .ECik; ; Если найдео свободное место | |
add di,Zerno ; Если не свободно переходим к следеющему | |
JMP .Cik ; | |
.ECik: | |
mov byte [di],2 ; записываем что этот участок памяти вделен под Элемент | |
inc di; ; | |
;----------------------------------------------------------------------------------- | |
mov byte [di],0; ; RES обнуляем Резервный элемент на всякий случай | |
mov cx,di; ; Запоминаем Адрес новго элемента ========== CX CX CX CX CX ==== | |
;------------------ | |
inc di; ; TIP Тип элемента | |
mov byte [di],0; ; Тип обнуляем | |
;------------------ | |
inc di; ; FUN Если это функция содержит 0 | |
mov byte [di],0; ; Обнуляем | |
;------------------ | |
inc di; ; ERR Код ошибки будет содеражть | |
mov byte [di],0; ; Обнуляем код ошибки | |
;============================================================= | |
inc di ; | |
mov SI,DI ; Сохраняем DI для записи в него адреса новой созданой строки | |
Call STR_CRE ; Запрашиваем строку перекрывание не возникает так как | |
mov dx,di; ; участок уже зарезервирован запоминаем адрес строки | |
MOV DI,SI ; Востанавливаем DI | |
mov word [di],dx ; Записываем адрес созданой строки там будет храниться NAM | |
;================== | |
inc di ; | |
inc di ; Увеличиваем на 2 так как 16 битный режим | |
MOV SI,DI ; ZNA Значение элемента в этой строке | |
Call STR_CRE ; Запрашиваем строку | |
mov dx,di ; DX используеться для получения адреса нвоой строкуи | |
MOV DI,SI ; | |
mov word [di],dx ; | |
;============================================================== | |
inc di ; SAM | |
inc di; ; Увеличиваем на 2 так как 16 битный режим | |
mov word [di],cx ; Указатель на самого себя свой адрес | |
;//=================== | |
inc di ; ROD | |
inc di ; Увеличиваем на 2 так как 16 битный режим | |
mov word [di],0 ; Указатель на Родителя себя свой адрес | |
;//=================== | |
inc di ; PRE | |
inc di ; Увеличиваем на 2 так как 16 битный режим | |
mov word [di],0 ; Указатель на Предка NIL | |
;//=================== | |
inc di ; NEX | |
inc di; ; Увеличиваем на 2 так как 16 битный режим | |
mov word [di],0 ; Указатель на Следующий элемент NIL | |
;//=================== | |
inc di ; BLO | |
inc di; ; Увеличиваем на 2 так как 16 битный режим | |
mov word [di],0; ; Указатель на Вложеный элемент NIL | |
;//=================== | |
; Станадартная концовка для возвращения значения подпрограммы с 1 Возвращаемым параметром DI | |
POP DI; | |
mov DI,CX; | |
PUSH DI | |
popad; | |
Ret | |
;==============================================================================} | |
ELE_FRE: ;{ Удаление элемента DI со всеми вложеными элементами | |
pushad | |
dec DI; | |
mov byte [di],0; | |
popad | |
ret; | |
;} | |
ELE_DEL: ;{ Удаляет элемент DI из своего списка | |
pushad | |
; Запоминаем некотрые знаяения элемента | |
Mov si,di ; Запоминаем предыдущий элемент у текущего элемента | |
Add si,El_Pre ; в регистр CX | |
Mov cx,[si] ; Читаем значение поле предыдущий элемент | |
Mov si,di ; Запоминаем Следующий элемент у текущего элемента | |
Add si,El_Nex ; В Регистр DX | |
Mov dx,[si] ; Читаем значение поле Следующицй элемент | |
;================================================================= | |
; обрабатываем предыдущий элемент | |
test cx,cx ; Запоминаем есть ли вообще предыдущий элемент CX<>0 | |
Jz .Nex1 ; Если предыдыщий элемнта нету идем дальше | |
mov si,cx ; | |
add si,El_Nex ; елементе вместо себя следующий элемент | |
mov [si],dx ; это значит что следующего элемента нету | |
.Nex1: ;================================================================= | |
;обрабаотываем следующий элемент ; | |
test dx,dx ; Запоминаем есть ли вообще предыдущий элемент DX<>0 | |
Jz .Nex2 ; | |
mov si,dx ; | |
add si,El_Pre ; ТОже самое что и для предыдущего тока для следующего | |
mov [si],cx ; | |
.Nex2: ;================================================================= | |
; Настройка родителя | |
Mov si,di ; | |
add si,El_Rod ; Читаем родительский элемент | |
mov ax,[si] ; | |
test ax,ax ; | |
jz .Nex3 ; Если родитедля нету то идем дальше | |
add ax,El_Blo ; в противном случае читаем его блок | |
mov si,ax ; | |
mov ax,[si] ; | |
cmp ax,di ; Если мы есть первый элемент то первым делаем следующий элемент | |
jnz .Nex3 ; Если мы не первый елемент то идем дальше ; | |
mov [si],dx ; В противном случае назначем след элемент первым в родительском элементе | |
.Nex3: ; ОТстыковка от всех елементов | |
mov si,di ; | |
add si,El_Rod ; | |
mov word [si],0;Обнуляем указатель на родителя | |
inc si ; | |
inc si ; | |
mov word [si],0;обнуляем указатель на предыддущий элемент | |
inc si ; | |
inc si ; | |
mov word [si],0;обнуляем указатель на следующий | |
popad | |
ret | |
;==============================================================================} | |
ELE_ADD: ;{ Добавлеи Элмемент DX в элемент DI | |
pushad; | |
mov cx,di ; CX Родительский элемент | |
; DX добавляемый элемент | |
;---------------------------------------------------------- | |
mov di,dx ; Удаляем элемент из предудущего списка | |
call ELE_DEL ; | |
mov di,cx ; Ищим в родительском элементе последний элемент | |
call ELE_LST ; Находм последний элемент в элементе DI | |
test di,di ; | |
JNZ .ADD_NEX ; если есть хоть один вложеный элемент то переходим к ADD_NEX то присоеденяем | |
; соотвественно если нету последнего элемента добавляемся как первый элемент | |
mov SI,CX ; | |
add SI,El_Blo ; Указываем в блоке родительского элемента что это первый вложеный элемент | |
Mov [si],dx ; | |
Jmp .Nex1 ; | |
;---------------------------------------------------------- | |
.ADD_NEX: ; Если есть последний элемент | |
mov si,di ; | |
add si,El_Nex ; | |
mov [si],dx ; Указываем в последнем элементе что это добавляемый элемент DX следующий | |
; Указываем предыдущий элмемент в себе последний в родительском | |
mov si,dx; | |
add si,El_Pre ; | |
mov [si],di ;Указываем в нашем елементе предыдущий элемент который наден процедрой поиска последнего элемента | |
.Nex1: | |
mov si,dx ; | |
add si,El_Rod ; Указываем родителя в получившемся элементе | |
mov [si],cx ; | |
popad ; | |
ret | |
;==============================================================================} | |
ELE_LST: ;{ Ищит последний элеммент у элемента DI | |
pushad ; | |
mov si,0 ; | |
Add di,El_Blo ; Читаем Блок | |
mov ax,[di] ; | |
.Cik: | |
test ax,ax ; | |
JZ .ECik ; пока AX <> 0 | |
mov si,ax ; Запоминаем последний не нулевой элемент | |
mov di,ax ; Пытаемся передсти к следуюющему | |
Add di,El_Nex ; Читаем Следующий элемент | |
mov ax,[di] ; | |
jmp .Cik ; | |
.ECik: ; Станадартная концовка для возвращения значения подпрограммы с 1 Возвращаемым параметром DI | |
pop di ; | |
mov DI,Si ; | |
push di ; | |
popad ; | |
ret | |
;==============================================================================} | |
ELE_COP: ;{ Создает копию элемента DI со всеми вложеными элементами | |
pushad | |
mov CX,DI ; CX Запоминаем адрес копируемого элемента | |
Call ELE_CRE ; DI Новый елемент | |
mov bx,di ; BX запоминаем адрес созданого элемента | |
mov di,cx ; DI откуда копируем SI < DI | |
mov si,bx ; SI Куда копируем | |
;---------------------------------------------------------- | |
mov al,[di] ; Читаем RES | |
mov [si],al ; Записываем RES | |
inc si ; Увеличиваем указатель Источника | |
inc di ; Увеличиваем указатель Получателя | |
;---------------------------------------------------------- | |
mov al,[di] ; Читаем Tip | |
mov [si],al ; Записываем Tip | |
inc si ; Увеличиваем указатель Источника | |
inc di ; Увеличиваем указатель Получателя | |
;---------------------------------------------------------- | |
mov al,[di] ; Читаем Fun | |
mov [si],al ; Записываем Fun | |
inc si ; Увеличиваем указатель Источника | |
inc di ; Увеличиваем указатель Получателя | |
;---------------------------------------------------------- | |
mov al,[di] ; Читаем Err | |
mov [si],al ; Записываем Err | |
inc si ; Увеличиваем указатель Источника | |
inc di ; Увеличиваем указатель Получателя | |
;---------------------------------------------------------- | |
; Копируем Имя | |
mov ax,[si] ; | |
mov dx,[di] ; | |
call STR_COP ; | |
add si,2 ; Увеличиваем указатель Источника | |
add di,2 ; Увеличиваем указатель Получателя | |
;---------------------------------------------------------- | |
; Копируем Значение | |
mov ax,[si] ; | |
mov dx,[di] ; | |
call STR_COP ; | |
;---------------------------------------------------------- | |
;------------------------------------------------------------- | |
; Копируем дочернии элементы | |
mov si,cx ; | |
add si,El_Blo; | |
mov dx,[si] ; | |
.Cik: | |
test dx,dx ; | |
jz .ECik ; | |
mov si,dx ; | |
;--------------- | |
mov di,dx ; | |
call ELE_COP ; Создаем копию Элемента | |
mov dx,di ; | |
mov di,bx ; | |
call ELE_ADD ; | |
;--------------- | |
add si,El_Nex; | |
mov dx,[si] ; | |
jmp .Cik ; | |
.ECik: | |
pop di ; | |
mov di,bx ; | |
push di ; | |
popad ; | |
ret | |
;==============================================================================} | |
ELE_PAR: ;{ Копирует параметры из элемента DX в элемент AX AX<DX | |
pushad | |
;------------------------------------------------------------- | |
; открываем скобку в принимающих значениях функции AX | |
mov si,Ax ; | |
add si,El_Blo ; | |
mov Ax,[si] ; | |
test ax,ax ; | |
jz .Vihod ; Если скобки нету выход | |
;--------------- | |
mov si,ax ;ОТкрываем первый элемент внутри скобки | |
add si,El_Blo ; | |
mov ax,[si] ; | |
jz .Vihod ; Если параметров нету выход | |
;--------------- | |
; открываем скобку в входящих значениях функции DX | |
mov si,dx ; | |
add si,El_Blo ; | |
mov dx,[si] ; | |
test dx,dx ; | |
jz .Vihod ; Если скобки нету выход | |
;--------------- | |
mov si,dx ;ОТкрываем первый элемент внутри скобки | |
add si,El_Blo; | |
mov dx,[si] ; | |
jz .Vihod ; Если параметров нету выход | |
.Cik: | |
test ax,ax ; | |
jz .Vihod ; | |
test dx,dx ; | |
jz .Vihod ; | |
mov si,ax ; | |
mov di,dx ; | |
push si; | |
push di; | |
;--------------- | |
add si,El_Zna; | |
add di,El_Zna; | |
mov ax,[si] ; | |
mov dx,[di] ; | |
Call STR_COP ; Копируем значение | |
;--------------- | |
pop di ; | |
pop si ; | |
add si,El_Nex; | |
add di,El_Nex; | |
mov ax,[si] ; | |
mov dx,[di] ; | |
jmp .Cik ; | |
.Vihod: | |
popad ; | |
ret | |
;==============================================================================} | |
ELE_ADS: ;{ Создает и добавляет элемент в списко елемента DI Добавляемое слово Slo | |
; AL тип одбавляемомго элемента ПАРАМЕТР DI то куда добавляем | |
pushad; | |
mov cx,di ; запоминаем елемент в котрый добавляем | |
call ELE_CRE ; Создаем новый элемент | |
mov si,di ; Записываем тип элемента | |
add si,El_Tip; | |
mov [si],Al ; Записываем тип элемента | |
mov si,di; | |
add si,El_Nam; Имя элемента | |
mov ax,[si] ; Адрес строки куда копируем | |
mov dx,Slo ; Копируемое слово | |
Call STR_COP ; Копируем Имя элемента NAM с строки SLO | |
inc si ; Переходим к значению | |
inc si ; | |
mov ax,[si] ; Адрес строки куда копируем | |
Call STR_COP ; Копируем Значение ZNA С строки SLO | |
mov dx,Di ; Указываем новенький созданый элемент | |
Mov Di,Cx ; Указываем куда добавить | |
Call ELE_ADD ; Добавляем элемент | |
popad; | |
ret | |
;==============================================================================} | |
ELE_1VI: ;{ ПРосмотрл элемента DI | |
pushad ; | |
mov cx,di ; Запоминаем адрес элемента для печати | |
;------------------------------------------------ | |
; Печать отступа Читает сколько родительских элементов | |
mov si,di ; | |
add si,El_Rod ; | |
mov ax,[si] ; | |
.Cik: | |
test ax,ax ; | |
jz .ECik ; | |
mov DI,TE_PRO ; Печатает пробелы | |
call Print ; | |
mov si,ax ; | |
add si,El_Rod ; | |
mov ax,[si] ; | |
jmp .Cik ; | |
;------------------------------------------------ | |
.ECik: | |
;------------------------------------------------ | |
;Печать вдрес элемента | |
mov di,TE_ADR; | |
call Print; | |
mov di,cx; | |
call PrintInt; | |
;------------------------------------------------ | |
; Печать адреса родительского элемента | |
mov DI,TE_ROD; | |
call Print; | |
mov si,cx; | |
add si,El_Rod; | |
mov di,[si]; | |
call PrintInt; | |
;------------------------------------------------ | |
;Печать адреса предыдущего элемента | |
mov DI,TE_PRE; | |
call Print; | |
mov si,cx; | |
add si,El_Pre; | |
mov di,[si]; | |
call PrintInt; | |
;------------------------------------------------ | |
; Печать адреса следующего элемента | |
mov DI,TE_NEX; | |
call Print; | |
mov si,cx; | |
add si,El_Nex; | |
mov di,[si]; | |
call PrintInt; | |
;------------------------------------------------ | |
; Печать адреса первого вложеного элемента | |
mov DI,TE_BLO; | |
call Print; | |
mov si,cx; | |
add si,El_Blo; | |
mov di,[si] | |
call PrintInt; | |
;------------------------------------------------ | |
; Печать Наименования элемента | |
mov DI,TE_NAM; | |
call Print; | |
mov si,cx; | |
add sI,El_Nam; | |
mov di,[sI]; | |
Call Print; | |
;------------------------------------------------ | |
; Печать Значения элемента | |
mov DI,TE_ZNA; | |
call Print; | |
mov si,cx; | |
add sI,El_Zna; | |
mov di,[sI]; | |
Call Print; | |
.Nex: | |
mov di,TE_LNN; Перевод строки | |
call Print; | |
.Vihod: popad; | |
ret | |
;==============================================================================} | |
ELE_VIE: ;{ ПРосмотрл элемента DI | |
pushad ; | |
mov cx,di ; Запоминаем адрес элемента для печати | |
;------------------------------------------------ | |
; Печать отступа Читает сколько родительских элементов | |
mov si,di ; | |
add si,El_Rod ; | |
mov ax,[si] ; | |
.Cik: | |
test ax,ax ; | |
jz .ECik ; | |
mov DI,TE_PRO ; Печатает пробелы | |
call Print ; | |
mov si,ax ; | |
add si,El_Rod ; | |
mov ax,[si] ; | |
jmp .Cik ; | |
;------------------------------------------------ | |
.ECik: | |
;------------------------------------------------ | |
;Печать вдрес элемента | |
mov di,TE_ADR; | |
call Print; | |
mov di,cx; | |
call PrintInt; | |
;------------------------------------------------ | |
; Печать ТИпа элемента | |
mov DI,TE_TIP; | |
call Print; | |
mov si,cx; | |
add si,El_Tip; | |
xor ax,ax; | |
mov al,[si]; | |
mov di,ax; | |
call PrintInt; | |
;------------------------------------------------ | |
; Печать Функия элемента | |
mov DI,TE_FUN; | |
call Print; | |
mov si,cx; | |
add si,El_Fun; | |
xor ax,ax; | |
mov al,[si]; | |
mov di,ax; | |
call PrintInt; | |
;------------------------------------------------ | |
; Печать адреса родительского элемента | |
; mov DI,TE_ROD; | |
; call Print; | |
; mov si,cx; | |
; add si,El_Rod; | |
; mov di,[si]; | |
; call PrintInt; | |
;------------------------------------------------ | |
;Печать адреса предыдущего элемента | |
;mov DI,TE_PRE; | |
; call Print; | |
; mov si,cx; | |
; add si,El_Pre; | |
; mov di,[si]; | |
; call PrintInt; | |
;------------------------------------------------ | |
; Печать адреса следующего элемента | |
; mov DI,TE_NEX; | |
; call Print; | |
; mov si,cx; | |
; add si,El_Nex; | |
; mov di,[si]; | |
; call PrintInt; | |
;------------------------------------------------ | |
; Печать адреса первого вложеного элемента | |
; mov DI,TE_BLO; | |
; call Print; | |
; mov si,cx; | |
; add si,El_Blo; | |
; mov di,[si] | |
; call PrintInt; | |
;------------------------------------------------ | |
; Печать Наименования элемента | |
mov DI,TE_NAM; | |
call Print; | |
mov si,cx; | |
add sI,El_Nam; | |
mov di,[sI]; | |
Call Print; | |
;------------------------------------------------ | |
; Печать Значения элемента | |
mov DI,TE_ZNA; | |
call Print; | |
mov si,cx; | |
add sI,El_Zna; | |
mov di,[sI]; | |
Call Print; | |
;------------------------------------------------ | |
; Печать Вложеных элементов если они есть | |
mov di,cx; | |
add Di,El_Blo; | |
mov ax,[di]; | |
test ax,ax; | |
jz .Nex; | |
mov di,cx; | |
call ELS_VIE; | |
.Nex: | |
mov di,TE_LNN; Перевод строки | |
call Print; | |
.Vihod: popad; | |
ret | |
;==============================================================================} | |
ELS_VIE: ;{ ПРосмотрл элементов DI | |
pushad ; | |
mov si,di ; | |
mov di,TE_LNN ; Перевод строки | |
call Print ; | |
mov di,si ; | |
test di,di ; ПРоверяем на 0 | |
jz .THE_ERR ; Если адрес элемента 0 печатаем ошибку | |
add di,El_Blo ; открываем первый вложеный элемент | |
mov ax,[di] ; Читаем первый вложеный элемент в элементе | |
.Cik: | |
test ax,ax ; Если он не нуль | |
jz .Vihod ; | |
mov di,ax ; | |
call ELE_VIE ; | |
;call Pausef ; | |
add di,El_Nex ; | |
mov ax,[di] ; | |
jmp .Cik ; | |
.THE_ERR: | |
mov di,TE_ERR ; | |
call Print ; Печатаем сообщение об ошибки | |
mov di,0 ; | |
.Vihod: | |
popad ; | |
ret ; | |
;==============================================================================} | |
ReadSim: ;{ Читем первую букву элемента DX возвращает в AL; | |
push si | |
mov si,dx; | |
add si,El_Nam; | |
mov ax,[si]; | |
mov si,ax; | |
inc si; | |
mov al,[si]; | |
pop si | |
ret; | |
;==============================================================================} | |
ReadTip: ;{ Читем первую букву элемента DX возвращает в AL; | |
; Читаем символ текущего элемента | |
push si | |
mov si,dx; | |
add si,El_Tip; | |
mov al,[si]; | |
pop si | |
ret; | |
;==============================================================================} | |
;-------------------------------------------------------------------------------} | |
;{ Формирование структуры кода ------------------------------------------------- | |
COM_SCO:;{ Вкладывает скоби елемент DI в списке AH=( Al=) | |
pushad; | |
push ax; | |
;------------------------------------------ | |
; Читаем первый елемент | |
MOV CX,DI ; CX Елемент в который осуществляеться добавление | |
MOV si,DI ; DX Текущий элемент | |
ADD si,El_Blo ; BX Следующий элемент | |
MOV DX,[SI] ; DI Елемент с котрого начали обработку | |
.Cik: TEST DX,DX ; | |
Jz .Vihod ; ПРоверяем текущий элемент если ноль обработка закончена | |
;---------------------------------------------------- | |
; Читаем следующий элемент записываем в BX | |
mov si,dx ; | |
ADD si,El_Nex ; | |
MOV bx,[si] ; | |
;---------------------------------------------------- | |
;-------------------------------------------------- | |
; Если текущий элемент закрывающаяся скобка поднимаемся на уровень наверх | |
call ReadSim ; переходим к обработке следующего элемента | |
; тут слегка замудренно ну блин регистров не хватаеть ))) | |
mov si,cx; | |
pop cx; | |
cmp al,cl ; | |
push cx; | |
mov cx,si; | |
jnz .Nex1 ; | |
mov si,cx ; Перемещаемся на уровень вверх | |
add si,El_Rod ; | |
mov cx,[si] ; | |
mov si,di ; Удаляем закрывающиюся скобку | |
mov di,dx ; | |
call ELE_DEL ; | |
mov di,si ; | |
jmp .Nex ; переходим к обработке следующего элемента | |
;---------------------------------------------------- | |
.Nex1: | |
;------------------------------------------------------- | |
; Вкладываем текущий элемент в контенер если CX<>DI | |
cmp di,cx ; | |
jz .Nex2 ; | |
mov si,di ; Сохраняем DI | |
mov di,cx ; CX контенер куда нужно вкладывать элементы | |
call ELE_ADD ; | |
mov di,si ; Востанавлвиаем DI | |
;---------------------------------------------------------- | |
.Nex2: | |
;---------------------------------------------------- | |
; Если текущий элемент Открывающаяся скобка назначаем новый контенер | |
call ReadSim ; | |
; тут слегка замудренно ну блин регистров не хватаеть ))) | |
mov si,cx; | |
pop cx; | |
cmp al,ch ; | |
push cx; | |
mov cx,si; | |
jnz .Nex ; | |
mov cx,dx ; назначаем новый элмент для складывания елементов | |
;--------------------------------------------------- | |
.Nex: | |
mov dx,bx; | |
jmp .Cik ; | |
.Vihod: | |
pop ax; | |
popad; | |
ret | |
;==============================================================================} | |
COM_BLO:;{ Вкладывает блоки елемент DI | |
pushad ; Читаем первый элемент в списке | |
mov si,di ; | |
add Si,El_Blo ; | |
mov bx,[si] ; BX Предыдущий элемент | |
test bx,bx ; CX Следующий элемент | |
jz .Vihod ; | |
mov si,bx ; | |
add si,El_Nex ; DX Текущий элемент | |
mov dx,[si] ; | |
.Cik: ;--------------------------------------------------- | |
test dx,dx ; | |
JZ .Vihod ; | |
;--------------------------------------------------- | |
; Обработка внутрених елементов | |
mov si,dx ; | |
add si,El_Blo ; | |
mov ax,[si] ; | |
test ax,ax ; | |
jz .NNN ; | |
mov si,di ; | |
mov DI,DX ; | |
call COM_BLO ; | |
mov di,si ; | |
;--------------------------------------------------- | |
.NNN: | |
;--------------------------------------------------- | |
; Чтение следующего элемента | |
Mov si,dx ; | |
add si,El_Nex ; | |
mov cx,[si] ; | |
;--------------------------------------------------- | |
;--------------------------------------------------- | |
; Чтение Предыдущего элемента | |
Mov si,dx ; | |
add si,El_Pre ; | |
mov bx,[si] ; | |
;--------------------------------------------------- | |
;---------------------------------------------------- | |
;Читаем тип предыдущего элемента | |
mov si,dx ; | |
mov dx,bx ; | |
call ReadTip ; | |
cmp al,10 ; | |
mov dx,si ; | |
jnz .Nex ; Если предыдущий тип элемента не оператор переходим к следующему элементу | |
;--------------- | |
call ReadSim ; | |
cmp al,'(' ; | |
jz .AddEl1 ; Если текущий тип элемента добавить | |
cmp al,'{' ;} | |
jz .AddEl2 ; Если текущий тип элемента добавить | |
jmp .Nex ; передти к следующему элменту | |
;---------------------------------------------------- | |
.AddEl1: | |
;---------------------------------------------------- | |
mov si,di ; | |
mov di,bx ; | |
call ELE_ADD ; | |
mov di,si ; | |
jmp .Nex ; | |
;---------------------------------------------------- | |
.AddEl2: | |
;---------------------------------------------------- | |
mov si,di ; Если вкладываем блок значит это описание функции; | |
mov di,bx ; | |
call ELE_ADD ; | |
add di,El_Fun ; | |
mov byte [di],1 ; | |
mov di,si ; | |
jmp .Nex ; | |
;---------------------------------------------------- | |
.Nex: | |
mov dx,cx ; | |
jmp .Cik ; | |
.Vihod: | |
popad ; | |
ret | |
;=============================================================================} | |
COM_MA3:;{ Вкладывает математически операции | |
pushad ; Читаем первый элемент в списке | |
mov si,di ; | |
add Si,El_Blo ; | |
mov bx,[si] ; BX Предыдущий элемент | |
test bx,bx ; CX Следующий элемент | |
jz .Vihod ; | |
mov dx,bx; | |
call .ObrVr ; Обработка внутрених елементов | |
mov si,bx ; | |
add si,El_Nex ; DX Текущий элемент | |
mov dx,[si] ; | |
.Cik: ;--------------------------------------------------- | |
test dx,dx ; | |
JZ .Vihod ; | |
call .ObrVr ; Обработка внутрених елементов | |
;--------------------------------------------------- | |
; Чтение следующего элемента | |
Mov si,dx ; | |
add si,El_Nex ; | |
mov cx,[si] ; | |
;--------------------------------------------------- | |
;--------------------------------------------------- | |
; Чтение Предыдущего элемента | |
Mov si,dx ; | |
add si,El_Pre ; | |
mov bx,[si] ; | |
;--------------------------------------------------- | |
;---------------------------------------------------- | |
;--------------- | |
call ReadSim ; | |
cmp al,'=' ; | |
jz .AddEl ; Если текущий тип элемента + добавить | |
jmp .Nex ; передти к следующему элменту | |
;---------------------------------------------------- | |
.AddEl: | |
;---------------------------------------------------- | |
mov si,dx ; Добавление предыдущего элемента | |
mov di,dx ; | |
mov dx,bx ; | |
call ELE_ADD ; | |
mov dx,si ; | |
;---------------------------------------------------- | |
;---------------------------------------------------- | |
mov si,dx ; Добавление Следующего элемента | |
mov di,dx ; | |
mov dx,cx ; | |
call ELE_ADD ; | |
mov dx,si ; | |
;---------------------------------------------------- | |
;--------------------------------------------------- | |
; Чтение следующего элемента | |
Mov si,dx ; | |
add si,El_Nex ; | |
mov cx,[si] ; | |
;--------------------------------------------------- | |
.Nex: | |
mov dx,cx ; | |
jmp .Cik ; | |
.Vihod: | |
popad ; | |
ret | |
;--------------------------------------------------- | |
; Обработка внутрених елементов | |
.ObrVr: pushad | |
mov si,dx ; | |
add si,El_Blo ; | |
mov ax,[si] ; | |
test ax,ax ; | |
jz .NNN ; | |
mov si,di ; | |
mov DI,DX ; | |
call COM_MA3 ; | |
mov di,si ; | |
.NNN: ;--------------------------------------------------- | |
popad | |
ret | |
;==============================================================================} | |
COM_MA1:;{ Вкладывает математически операции | |
pushad ; Читаем первый элемент в списке | |
mov si,di ; | |
add Si,El_Blo ; | |
mov bx,[si] ; BX Предыдущий элемент | |
test bx,bx ; CX Следующий элемент | |
jz .Vihod ; | |
mov dx,bx ; | |
call .ObrVr ; Обработка внутрених елементов | |
mov si,bx ; | |
add si,El_Nex ; DX Текущий элемент | |
mov dx,[si] ; | |
.Cik: ;--------------------------------------------------- | |
test dx,dx ; | |
JZ .Vihod ; | |
call .ObrVr ; Обработка внутрених елементов | |
;--------------------------------------------------- | |
; Чтение следующего элемента | |
Mov si,dx ; | |
add si,El_Nex ; | |
mov cx,[si] ; | |
;--------------------------------------------------- | |
;--------------------------------------------------- | |
; Чтение Предыдущего элемента | |
Mov si,dx ; | |
add si,El_Pre ; | |
mov bx,[si] ; | |
;--------------------------------------------------- | |
;---------------------------------------------------- | |
;--------------- | |
call ReadSim ; | |
cmp al,'+' ; | |
jz .AddEl ; Если текущий тип элемента + добавить | |
cmp al,'-' ; | |
jz .AddEl ; Если текущий тип элемента - добавить | |
jmp .Nex ; передти к следующему элменту | |
;---------------------------------------------------- | |
.AddEl: | |
;---------------------------------------------------- | |
mov si,dx ; Добавление предыдущего элемента | |
mov di,dx ; | |
mov dx,bx ; | |
call ELE_ADD ; | |
mov dx,si ; | |
;---------------------------------------------------- | |
;---------------------------------------------------- | |
mov si,dx ; Добавление Следующего элемента | |
mov di,dx ; | |
mov dx,cx ; | |
call ELE_ADD ; | |
mov dx,si ; | |
;---------------------------------------------------- | |
;--------------------------------------------------- | |
; Чтение следующего элемента | |
Mov si,dx ; | |
add si,El_Nex ; | |
mov cx,[si] ; | |
;--------------------------------------------------- | |
.Nex: | |
mov dx,cx ; | |
jmp .Cik ; | |
.Vihod: | |
popad ; | |
ret | |
;--------------------------------------------------- | |
; Обработка внутрених елементов | |
.ObrVr: pushad | |
mov si,dx ; | |
add si,El_Blo ; | |
mov ax,[si] ; | |
test ax,ax ; | |
jz .NNN ; | |
mov si,di ; | |
mov DI,DX ; | |
call COM_MA1 ; | |
mov di,si ; | |
.NNN: ;--------------------------------------------------- | |
popad | |
ret; | |
;==============================================================================} | |
;-------------------------------------------------------------------------------} | |
;{ Выполнение программы -------------------------------------------------------- | |
FUN_RUS: ;{ Запускает группу элементов на выполнение =========================== | |
pushad ; | |
mov si,di ; | |
add si,El_Blo ; | |
mov dx,[SI] ; Читаем первый элемент | |
.Cik: | |
test dx,dx ; | |
Jz .Vihod; | |
;----------------------- | |
mov si,dx ; проверяем если это не описание функции выполняем | |
add si,El_Fun ; | |
mov al,[si] ; | |
cmp al,1 ; | |
jz .Nex ; Если это описание функции то переходим к следующему элементу | |
;---------------------- | |
Mov di,dx ; | |
call FUN_RUN ; выполняем функцию DX | |
.Nex: ;---------------------- | |
mov si,dx ; Переходим к следующему элементу | |
add si,El_Nex ; | |
mov dx,[si] ; | |
jmp .Cik; | |
.Vihod: | |
popad ; | |
ret ; | |
;==============================================================================} | |
FUN_RUN: ;{ выполняет елеемнт DI | |
pushad | |
mov bx,Di ; Запоминаем исполнительный элемент | |
;------------------------------------------------------------ | |
mov si,di ; | |
add si,El_Nam; | |
mov ax,[si] ; | |
mov dx,TE_PRI; | |
call STR_RAV ; | |
jz .Nex10 ; | |
call FUN_CON ;Если команда печати на экран выполняет | |
jmp .Vihod ; | |
;------------------------------------------------------------ | |
.Nex10: | |
mov dx,di ; | |
call ReadSim ;Если команда Скобка выполняем скобку | |
cmp al,'(' ; | |
Jnz .Nex20 ; | |
call FUN_SCO ; | |
jmp .Vihod ; | |
;------------------------------------------------------------ | |
.Nex20: | |
mov dx,di ; | |
call ReadSim ;Если команда Блок выполняем блок | |
cmp al,'{' ;} | |
Jnz .Nex30 ; | |
call FUN_RUS ; | |
jmp .Vihod ; | |
;------------------------------------------------------------ | |
.Nex30: | |
mov dx,di ; | |
call ReadSim ;Если команда ПРисвоения выполняет | |
cmp al,'=' ; | |
Jnz .Nex40 ; | |
call FUN_PRI ; | |
jmp .Vihod ; | |
;------------------------------------------------------------ | |
.Nex40: | |
mov dx,di ; | |
call ReadSim ;Если команда сложения выполняет | |
cmp al,'+' ; | |
Jnz .Nex50 ; | |
call FUN_PLU ; | |
jmp .Vihod ; | |
;------------------------------------------------------------ | |
; Если это не одна из кооманд то выполняем как функцию | |
;------------- Вычисляем параметры | |
.Nex50: | |
mov si,di ;Подготавливаем имя для поиска | |
add si,El_Nam; | |
mov cx,[si] ; | |
mov si,di ; | |
call FUN_FIN ; ищим функцию | |
jz .Vihod ; если такой функции нету то выход | |
;------------ | |
call ELE_COP ; Создаем копию функциии | |
; ----------- ПРисоденеяем | |
mov si,bx; | |
call .Connect; | |
; ----------- | |
mov ax,di ; | |
mov dx,bx ; | |
call ELE_PAR ; Копируем параметры | |
;------------ ; | |
call FUN_RUS ; Выполняем Функцию | |
;------------ | |
mov si,bx ; | |
add si,El_Zna; | |
add di,El_Zna; | |
mov ax,[si] ; | |
mov dx,[di] ; | |
call STR_COP ; | |
.Vihod: | |
popad; | |
ret | |
.Connect:;----------------{ | |
; присоеденение элемента di в цепочку si | |
pushad; | |
; Присоеденяем родительский элемент | |
push si | |
push di | |
add si,El_Rod; | |
add di,El_Rod; | |
mov ax,[si]; | |
mov [di],ax; | |
pop di | |
pop si | |
; Присоеденяем предыдущий элемент | |
push si | |
push di | |
add si,El_Pre; | |
add di,El_Pre; | |
mov ax,[si]; | |
mov [di],ax; | |
pop di | |
pop si | |
; Присоеденяем Следующий элемент | |
push si | |
push di | |
add si,El_Nex; | |
add di,El_Nex; | |
mov ax,[si]; | |
mov [di],ax; | |
pop di | |
pop si | |
popad; | |
ret; | |
;----------------------------} | |
;==============================================================================} | |
FUN_FIN: ;{ Ищит функцию CX с элемента DI | |
pushad | |
mov bx,di; Запоминаем | |
mov dx,di; Запоминаем | |
.Cik1: test dx,dx ; | |
jz .ECik1 ; | |
;--------------------------------------------------------------------------- | |
; Ищим в предыдущих елементах | |
mov di,dx ; | |
call .FNamRa ; | |
jnz .Vihod ; Если равны идем на выход в di содержиться результат поиска | |
;----------------------- | |
;Переходим к предыдущиму элементу | |
mov si,dx ; | |
add si,El_Pre ; | |
mov dx,[si] ; | |
jmp .Cik1 ; | |
;--------------------------------------------------------------------------- | |
.ECik1: | |
;---------------------------------------------------------------------------- | |
; Ищим в параметрах | |
mov si,bx ; если есть родительский элемент | |
add si,El_Fun ; Если я функция | |
mov al,[si] ; | |
test al,al ; | |
jz .ECik2 ; | |
;----------------------- Поиск внутри параметров | |
mov si,bx ; | |
add si,El_Blo ; | |
mov ax,[si] ; | |
test ax,ax ; | |
jz .ECik2; | |
mov si,ax ; | |
add si,El_Blo ; | |
mov ax,[si] ; | |
.Cik2: | |
test ax,ax ; | |
jz .ECik2 ; | |
mov di,ax ; | |
call .NamRA ; | |
jnz .Vihod ; Если равны идем на выход в di содержиться результат поиска | |
;----------------------- | |
mov si,ax ; Переходим к следующему элементу | |
add si,El_Nex ; | |
mov ax,[si] ; | |
Jmp .Cik2 ; | |
;--------------------------------------------------------------------------- | |
.ECik2: | |
;---------------------------------------------------------------------------- | |
; Ищим в родительском элементе | |
mov si,bx ; | |
add si,El_Rod ; | |
mov ax,[si] ; | |
test ax,ax ; | |
jz .Nex ; | |
mov di,ax ; | |
call FUN_FIN ; | |
jmp .Vihod ; | |
.Nex: mov di,0 ; | |
;--------------------------------------------------------------------------- | |
.Vihod: | |
mov dx,di ; | |
pop di ; | |
mov di,dx ; | |
push di ; | |
popad; | |
ret | |
.FNamRa:;{если элемент DI Функия и имя его равно CX возвращает 1 | |
pushad | |
mov si,di; | |
add si,El_Fun ; | |
mov al,[si] ; | |
test al,al ; | |
jz .LVih ;Если это не функция выходим | |
;----------------------- | |
call .NamRA ; срвниваем строки | |
.LVih: popad | |
ret;-------------------} | |
.NamRA: ;{сравнивает строки CX с Именем элемента DI | |
pushad | |
mov si,di | |
add si,El_Nam ; Если это функция читаем название | |
mov ax,[si] ; | |
mov dx,cx ; | |
call STR_RAV ; срвниваем строки -=-=-= | |
popad | |
ret; } | |
;==============================================================================} | |
FUN_CON: ;{ Выводит на печать строку DI | |
pushad | |
call FUN_RUS ; Выполнение вложений | |
; ------------------------------------------- | |
add di,El_Blo ; | |
mov dx,[di] ; | |
test dx,ax ; | |
jz .Vihod ; Выход если нету вложений | |
; -------------------------------------------- | |
mov di,dx; | |
add di,El_Zna ; Вычисляем адрес ZNA вложения | |
mov ax,[di] ; | |
mov di,ax ; | |
call Print ; Печать знаяения вырожения | |
mov di,TE_LNN ; | |
call Print ; Печать перевода строки | |
.Vihod: | |
popad | |
ret | |
;==============================================================================} | |
FUN_SCO: ;{ Выполняет скобку | |
pushad | |
;---------------------------------------------------------------- | |
mov si,di ; | |
add si,El_Zna ; | |
mov ax,[si] ; AX Адрес строки скобки ZNA | |
mov si,ax ; | |
mov Byte [si],0 ; Обнуляем значение скобки | |
;----------------------------------------------------------------- | |
; Выполняем элементы внутри скобки | |
call FUN_RUS ; | |
;----------------------------------------------------------------- | |
; достаем первый элемент из скобки | |
add di,El_Blo ; | |
mov cx,[di] ; | |
.Cik: | |
test cx,cx ; | |
jz .Vihod ; | |
;-------------------- | |
mov si,cx ; Значение вложеного элемента | |
add si,El_Zna ; | |
mov dx,[si] ; | |
call STR_SUM ; | |
;-------------------- | |
mov di,cx ; Переходим к следующему элементу | |
add di,El_Nex ; | |
mov cx,[di] | |
jmp .Cik; | |
.Vihod: | |
popad | |
ret | |
;==============================================================================} | |
FUN_PLU: ;{ Выполняет операцию сложения | |
pushad; | |
mov bx,di; | |
; --------------------------------------- | |
; Вычисляем адрес результирующей строки сложения | |
mov si,di ; | |
add si,El_Zna ; | |
mov cx,[si] ; CX Запоминаем адрес результирующей строки | |
mov si,cx ; | |
mov Byte [si],0 ; Обнуляем длину строки результата | |
; ------------------------------- | |
; Выполняем первый элемент | |
add di,El_Blo ; | |
mov si,[di] ; | |
mov di,si ; Вычисляем первый элемент | |
call FUN_RUN ; | |
;call ELE_VIE ; | |
add si,El_Zna ; | |
mov dx,[si] ; | |
mov ax,cx ; | |
call STR_SUM ; | |
; ------------------------------- | |
; Выполняем Следующий элемент | |
add di,El_Nex ; | |
mov si,[di] ; | |
mov di,si ; | |
call FUN_RUN ; | |
add si,El_Zna ; | |
mov dx,[si] ; | |
mov ax,cx ; | |
call STR_SUM ; | |
mov di,bx | |
popad; | |
ret | |
;==============================================================================} | |
FUN_PRI: ;{ Выполняет операцию присваивания | |
pushad; | |
; Выполняем первый элемент | |
add di,El_Blo ; | |
mov si,[di] ; | |
mov di,si ; Вычисляем первый элемент | |
add di,El_Nam ; | |
mov cx,[di] ; | |
mov di,si ; Вычисляем первый элемент | |
call FUN_FIN; | |
add di,El_Zna ; | |
mov ax,[di] ; | |
; ------------------------------- | |
; Выполняем Следующий элемент | |
add si,El_Nex ; | |
mov di,[si] ; | |
call FUN_RUN; | |
add di,El_Zna ; | |
mov dx,[di] ; | |
call STR_COP ; | |
popad; | |
ret | |
;==============================================================================} | |
;------------------------------------------------------------------------------} | |
;{ Парсер ---------------------------------------------------------------------- | |
ReadPro: ;{ Читает программу | |
Pushad; | |
call ELE_CRE ; создаем элемент | |
Mov [COD],di ; Запоминаем корневой адрес программы | |
mov word [Poi],Pro; Сбрасываем указатель устанавливаем на начало текста программы | |
;---------------------------------------------------------------------- | |
.Cik: | |
Mov si,[Poi] ; | |
mov al,Byte [si] ; Читаем символ из текста программы | |
test al,al ; ПРоверяем не достигнут ли конец программы 0 байт | |
JZ .Vihod ; Если нудевой символ то программа закончилася | |
; Читаем оператор из букв состоящий | |
mov al,'A' ; устанавливаем интервал символы читаемые | |
mov ah,'Z' ; | |
call ReadOpe ; Читаем оператор Использует стандартный указатель POI для чтения | |
mov al,[Slo] ; читаем длину прочитаной строки | |
test al,al ; если строка нуль то значит это не оператор соотвественно | |
jz .R_Cif ; Если прочитать не удалося пытаемся прочитать как цифру | |
mov al,10 ; Если прочитать удалося записывает тип оператор и добавляем элемент | |
mov di,[COD] ; Указываем куда нужно добавить елемент | |
call ELE_ADS ; ELE_ADS Использует стондартное слово SLO для добавления | |
jmp .Cik ; Повторяем цикл | |
.R_Cif: ; Чтение Цифры из теста программы | |
mov al,'0' ; | |
mov ah,'9' ; | |
call ReadOpe ; Читаем Цифру | |
mov al,[Slo] ; читаем длину прочитаной строки | |
test al,al ; если строка нуль длоиной то значит это не цифра | |
jz .R_Zna ; Если прочитать не удалося пытаемся прочитать как Знак | |
mov al,20 ; Если прочитать удалося записывает тип Цифра и добавляем элемент | |
mov di,[COD] ; Указываем куда нужно добавить елемент | |
call ELE_ADS ; | |
jmp .Cik ; | |
.R_Zna: ; Читаем знак из текста программы | |
call ReadZna ; Читаем Знак | |
mov al,[Slo] ; читаем длину прочитаной строки | |
test al,al ; если строка нуль длоиной то значит это не Знак | |
jz .R_Kav ; Если прочитать не удалося пытаемся прочитать как Кавычку | |
mov al,30 ; Если прочитать удалося записывает тип Знак и добавляем элемент | |
mov di,[COD] ; Указываем куда нужно добавить елемент | |
call ELE_ADS ; | |
jmp .Cik ; | |
.R_Kav: | |
call ReadKav ; Читаем Кавычку | |
mov al,[Slo] ; читаем длину прочитаной строки | |
test al,al ; если строка нуль длоиной то значит это не Знак | |
jz .R_Nex ; Если прочитать не удалося пытаемся прочитать как Кавычку | |
mov al,30 ; Если прочитать удалося записывает тип Знак и добавляем элемент | |
mov di,[COD] ; Указываем куда нужно добавить елемент | |
call ELE_ADS ; | |
jmp .Cik; | |
.R_Nex: | |
inc word [Poi] ; Если прочитать не удалося просто пропускаем символ | |
jmp .Cik ; | |
.Vihod: ; чтение програмым закончено Программа разбита на слова | |
; в элементе адрес котрого храниться тут [COD] | |
pop di ; | |
mov di,[COD] ; | |
push di ; | |
popad ; | |
ret ; | |
;==============================================================================} | |
ReadOpe: ;{ ПРоцедура чтения оператора read one word from programm | |
;// AX AH - верхний предел символа AL - нижний предел символа | |
;// читает слово в адрес Slo ПОДПРОГРАММА ПАРАМЕТРОВ НЕ ИМЕЕТ | |
pushad ; | |
mov byte [Slo],0; Обнуляем длину читаемого слова | |
.Cik: mov di,[Poi] ; Читаем указатель на читаемый символ в программе | |
mov dl,[di] ; читаем символ | |
test dl,dl ; Проверяем на нуль 0 это конец текста программы | |
jz .Vihod ; Если нулевой символ; | |
cmp dl,al ; | |
jb .Vihod ; Если ниже выход Нижний предел if pro[poi]<al exit | |
cmp dl,ah ; | |
ja .Vihod ; Если выше выход Верхнимй редел if pro[poi]>ah exit | |
mov di,Slo ; Если предел удовлетварительный то читаем адрес слова | |
call STR_ADC ; Добавляем символ в слово | |
inc Word [Poi] ; Увеличиваем указатель | |
jmp .Cik ; повторяем | |
.Vihod: popad; | |
Ret; | |
;==============================================================================} | |
ReadZna: ;{ ПРоцедура чтения Знака read one word from programm | |
; читает знак в адрес Slo; ПОДПРОГРАМАМ ПАРАМЕТРОВ НЕ ИМЕТ | |
pushad; | |
mov byte [Slo],0; Обнуляем длину читаемого слова | |
mov di,[Poi] ; | |
mov al,[di] ; Читаем символ из программы | |
mov cl,11 ; Устанавливаем количество обрабатываемых сзнаков | |
Mov di,ZNAKS ; Читаем адрес расположения знаков | |
.Cik: Mov dl,[di] ; Читаем знак | |
cmp al,dl ; сравниываем | |
Jnz .Nex ; Если не равно идем дальше | |
mov di,Slo ; | |
call STR_ADC ; Если такой знак есть в списк добавлем в слово и выход | |
inc word [Poi] ; Увеличиваем указатель читаемых символов из программы | |
Jmp .Vihod ; | |
.Nex: | |
inc di ; Переходим к следующему знаку в списке для сравнения | |
dec cl ; считаем скока знаков сравнили | |
test cl,cl ; Смотрим не кончилися ли знаки в списке | |
Jnz .Cik ; Если не кончилися перекходим к следующему знаку | |
.Vihod: | |
popad; | |
Ret; | |
;==============================================================================} | |
ReadKav: ;{ ПРоцедура чтения Кавычки read one word from programm | |
; читает кавычку в адрес Slo; | |
pushad; | |
mov byte [Slo],0; Обнуляем длину читаемого слова | |
mov si,[Poi] ; Читаем Номер символа для прочтения | |
mov dl,[si] ; читаем символ | |
cmp dl,'"' ; Сравниваем с кавычкой | |
jnz .Vihod ; Если не кавычка выход | |
; Если это кавычка то читаем как кавычку | |
.Cik: inc word [Poi] ; Увеличиваем указатель заодно пропускаем первую кавычку | |
mov di,[Poi] ; читаем номер сивола | |
add di,[Pro] ; ПРибавляем адрес программы | |
Mov dl,[di] ; Читаем символ | |
cmp dl,'"' ; Сравниваем с кавычкой | |
jz .ECik ; если опять кавычка заканчиваем чтение | |
mov di,Slo ; записываем адрес SLO в котром копим результиат | |
call STR_ADC ; Добавляем символ в слово | |
jmp .Cik ; | |
.ECik: inc word [Poi] ; Увеличиваем указатель пропускаем последнию кавычку | |
.Vihod: popad; | |
Ret; | |
;==============================================================================} | |
;------------------------------------------------------------------------------} | |
;{ Для работы со строками ------------------------------------------------------ | |
STR_CRE: ;{ Возвращает в регистре DI Адрес созданой строки | |
pushad ; | |
Mov di,TrMe ; Начальный Адрес кучи | |
.Cik: Mov al,[di] ; Ищим свободное зерно в начале каждого зерна байт флаг | |
test al,al ; если 0 значит свободно | |
jz .ECik ; Если зерно свободно используем для создания строки | |
add di,Zerno ; в противном случае берем следующе зерно увеличиваем адрес +Zerno | |
JMP .Cik ; | |
.ECik: | |
mov byte [di],1 ; записываем что этот участок памяти вделен под строку | |
inc di; ; Вдрес всех элементов равен адрес зерна +1 так как 1 байт флаг занятости | |
mov byte [di],0 ; Обнуляем длину строки первый байт в строке её длина | |
MOV SI,DI ; | |
; Станадартная концовка для возвращения значения подпрограммы с 1 Возвращаемым параметром DI | |
POP DI ; pushad всегда на вершине стека DI регистр в него и пишем результат | |
mov DI,SI ; | |
PUSH DI ; | |
popad ; | |
Ret ; | |
;==============================================================================} | |
STR_RAV: ;{ Выполняет операцию Сравнения строк AX<DX | |
pushad; | |
mov si,ax ; | |
mov di,dx ; | |
mov al,[si] ; Читаем длину строки AX | |
mov ah,[di] ; Читаем длину строки DX | |
mov cl,al ; Запоминаем длину строк что бы сравнивать по буквам | |
cmp ah,al ; Сравниваем длины строк | |
Jnz .NeRavno ; | |
inc si ; Если строки одинаковой длины продолжим сравнение | |
inc di ; | |
.Cik: test cl,cl ; | |
Jz .Ravno ; | |
mov ah,[di] ; Читаем символ строки AX | |
mov al,[si] ; Читаем символ строки DX | |
cmp al,ah ; | |
Jnz .NeRavno ; Если символы не совпадают | |
dec cl ; Считаем количество символов сравненых | |
inc di ; | |
inc si ; | |
Jmp .Cik ; | |
.Ravno: | |
mov al,1 ; | |
test al,al ; | |
jmp .Vihod ; | |
.NeRavno: | |
mov al,0 ; | |
test al,al ; | |
.Vihod: | |
popad ; | |
ret ; | |
;==============================================================================} | |
STR_COP: ;{ Выполняет операцию Копирования строки AX<DX | |
pushad ; | |
mov di,dx ; | |
mov si,ax ; | |
mov cl,[di] ; | |
mov [si],cl ; | |
inc di ; | |
inc si ; | |
.Cik: | |
test cl,cl ; | |
JZ .ECik ; | |
mov ch,[di] ; | |
mov [si],ch ; | |
dec cl ; | |
inc di ; | |
inc si ; | |
jmp .Cik ; | |
.ECik: | |
popad ; | |
ret | |
;==============================================================================} | |
STR_SUM: ;{ Выполняет операцию Сложения строки AX:=AX+DX | |
pushad ; | |
mov si,dx ; | |
mov cl,[si] ; Читаем длину слова второго | |
inc si ; | |
.Cik: ;------------------------------------------- | |
test cl,cl ; | |
JZ .ECik ; | |
mov dl,[si] ; | |
mov di,ax ; | |
call STR_ADC ; | |
dec cl; | |
inc si; | |
jmp .Cik; | |
.ECik: | |
popad; | |
ret | |
;==============================================================================} | |
STR_ADC: ;{ ПРибавляет к строке символ=Dl DI=адрес строки куда прибавить | |
pushad ; Сохраняем состояние регистров | |
inc byte [di] ; Увеличиваем длину строки | |
xor ax,ax ; | |
mov al,[di] ; Читаем длину строки | |
add di,ax ; прибавляем длину строки | |
mov [di],dl ; записываем символ в нужное место | |
popad; ; Востанавливаем состояние регистров | |
ret; ; Возврат из подпрограммы добавления символа | |
;==============================================================================} | |
;------------------------------------------------------------------------------} | |
;{ Системные функции ----------------------------------------------------------- | |
Exitf: ;{ Завершение программы параметрова не имеет | |
int 20h; | |
ret; | |
;==============================================================================} | |
Pausef: ;{ Подпрограмма пауза параметров не имеет | |
pushad; | |
mov ah,8h; | |
int 21h | |
popad; | |
ret; | |
;==============================================================================} | |
Print: ;{ Печатает строку в консоль DI Адрес строки котрую нада напечатать | |
;// Печатает строку в консоль print string first byte len word | |
pushad ; Сохраняем состояние регистров | |
test di,di ; ПРоверка на Ноль | |
jz .THE_NIL ; Если указатель на строку равен 0 печатем NIL; | |
xor ax,ax ; ОБнуялем AX | |
Mov al,[di] ; читаем длину устроки | |
test al,al ; | |
jz .THE_PUS ; Если длина строки равна 0 то печатаем PUS | |
inc di ; пропускам длину строки так как первый байт это длина прибавляем 1 | |
mov dx,di ; запоминаем адрес начала строки для печати | |
add di,ax ; прибавляем Длину строки | |
mov byte [di],24h; записываем доллор в конец строки окончание строки в досе $ | |
mov ah,9h ; устанавливаем номер функции прерывания DOS для печати строки в консоль | |
int 21h ; Вызываем прерывание для печати строки в консоль | |
jmp .Vihod ; | |
.THE_NIL: ; | |
MOV DI,TE_NIL ; Печать NIL | |
Call Print ; | |
Jmp .Vihod ; | |
.THE_PUS: | |
MOV DI,TE_PUS ; Печать PUS | |
Call Print ; | |
.Vihod: ; Выход | |
popad ; Востанавливаем состояние регистров | |
ret; | |
;==============================================================================} | |
PrintInt:;{ Печатает цифру из регистра DI | |
pushad; | |
; Обнуляем Строку | |
mov si,Slo; | |
mov byte [si],0; | |
mov cx,di; | |
; Вычисляем первый разряд | |
mov dx,cx; | |
shR dx,12; | |
call .LPRO; | |
; Вычисляем первый разряд | |
mov dx,cx; | |
shL dx,4; | |
shR dx,12; | |
call .LPRO; | |
; Вычисляем первый разряд | |
mov dx,cx; | |
shL dx,8; | |
shR dx,12; | |
call .LPRO; | |
; Вычисляем первый разряд | |
mov dx,cx; | |
shL dx,12; | |
shR dx,12; | |
call .LPRO; | |
; Выводим на печать | |
mov Di,Slo; | |
call Print; | |
popad; | |
ret; | |
.LPRO: | |
cmp dl,9; | |
ja .LNex1; | |
add dx,'0'; | |
jmp .LVihod; | |
.LNex1: sub dx,10; | |
add dx,'A'; | |
.LVihod: | |
mov di,Slo; | |
Call STR_ADC; | |
ret | |
;==============================================================================} | |
InitMem: ;{ Инициализация памяти | |
pushad | |
mov si,TrMe; | |
.Cik: cmp si,50000; | |
jz .Vihod; | |
inc si; | |
jmp .Cik; | |
.Vihod: | |
popad; | |
ret; | |
;} | |
;------------------------------------------------------------------------------} | |
;{ Переменные константы стурктуры ---------------------------------------------- | |
Peremens: ;{ Переменные | |
Poi : dw 0;// Указатель на читаемый символ Pointer to read char | |
COD : dw 0;// Это корневой элемент исполняемой программы | |
Slo : db 64 dup(0) ;// первый байт размер строки | |
ZNAKS : db '+-*/(){}=<>'; списко понимаемых знаков | |
; Тект программы Text Programm | |
Pro : db "SUMMA(A,B){SUMMA=A+B};PRINT(SUMMA(3,5)) ;",0 | |
;Pro : db "X(){};X=12;PRINT(X);",0 | |
;------------------------------------------------------------------------------} | |
ATR: ;{ Для отладки просто пишет OTL | |
pushad | |
mov di,TE_OTL; | |
call Print; | |
call Pausef; | |
popad; | |
ret | |
;==============================================================================} | |
TELE: ;{ Основной элемент структуры программы | |
Zerno=32; | |
El_Res = 0 ; | |
El_Tip = 1 ;// Тип Элемента | |
El_Fun = 2 ;// Если это Функция | |
El_Err = 3 ;// Если это Функция | |
El_Nam = 4 ;// Наименование элемента | |
El_Zna = 6 ;// Значение | |
El_Sam = 8 ;// Свой собственый адрес | |
El_Rod = 10;// Родительский элемент | |
El_Pre = 12;// предыдущий эллемент | |
El_Nex = 14;// Следующий элемент | |
El_Blo = 16;// Вложеный елемент | |
;------------------------------------------------------------------------------} | |
TEXT: ;{ Различные текстовые сообщения в программе | |
TE_FUN : db 6," FUN",0; | |
TE_PRI : db 5,"PRINT",0; | |
TE_SPR : db 6," Sta ",0; | |
TE_EPR : db 6," End ",0; | |
TE_OTL : db 6," Otl ",0; | |
TE_ERR : db 6," ERR ",0; | |
TE_PRO : db 1," ",0; | |
TE_NIL : db 6," Nil ",0; | |
TE_PUS : db 6," Pus ",0; | |
TE_ADR : db 6," ADR ",0; | |
TE_TIP : db 6," TIP ",0; | |
TE_NAM : db 6," NAM ",0; | |
TE_ZNA : db 6," ZNA ",0; | |
TE_NEX : db 6," NEX ",0; | |
TE_PRE : db 6," PRE ",0; | |
TE_ROD : db 6," ROD ",0; | |
TE_SAM : db 6," SAM ",0; | |
TE_BLO : db 6," BLO ",0; | |
TE_RAZ : db 3," - ",0; | |
TE_LNN : db 2,13,10,0; | |
TE_SC1 : db 1,"(",0; | |
TE_SC2 : db 1,")",0; | |
;------------------------------------------------------------------------------} | |
REM: ;{ Различные записи пометки | |
; int Res = 0 | |
; int TIP = 1; // Тип Элемента | |
; int FUN = 2; // Если это Функция | |
; int ERR = 3; // Код ошибки | |
; string NAM =4; // Наименование элемента | |
; string ZNA =6; // Значение | |
; TEl* Rod = 8; // Родительский элемент | |
; TEl* Rod = 10; // Родительский элемент | |
; TEl* Pre = 12; // предыдущий эллемент | |
; TEl* Nex = 14; // Следующий элемент | |
; TEl* blo = 16; // Вложеный елемент | |
; byte Ti_Ope=10; // Оператор | |
; byte Ti_Cif=20; // Цифра | |
; byte Ti_Zna=30; // Знак ОДинарный например = + - / , | |
; byte Ti_Kav=40; // В кавычках "" | |
;(макс раз буфера 1 байт )(сколько байт ввели 1 байт )(введенный текст ) | |
; mov ah,0xA; // Номер функции ввода с консоли | |
; mov dx,S; //Записываем в регистр адрес буфера первое число максимальный размер буфера | |
; int 21h; //ВВод с консоли | |
; mov dx,S; // Записываем в регистр адрес буфера первое число максимальный размер буфера | |
; inc dx; // ПРопускаем максимальный размер буфера | |
; mov si,dx; // Читаем адрес количество введенных символов | |
; xor cx,cx; // очишаем регистр CX | |
; mov cl,[si];// читаем количество введенных символов | |
; add cx,dx; // приьбавляем к адресу буфера | |
; inc cx; // увеличиваем на 1 | |
; mov si,cx; | |
; mov byte [si],24h;// записываем доллор в конец строки | |
; mov ah,9h; // Номер функции вывода на консоль | |
; mov dx,S; // читаем адрес введенных символов | |
; inc dx; // пропускаем максимальное размер буфера | |
; inc dx; // пропускаем количество введенных символов | |
; int 21h; //Вывод на консоль | |
;------------------------------------------------------------------------------} | |
TrMe: db 0;Адрес размещения кучи | |
;==============================================================================} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment