home *** CD-ROM | disk | FTP | other *** search
-
- ; ===========================================================
- ; CMD.Z80
- ; built-in commands for E-Prolog
- ; June 1, 1985
-
- .Z80
-
- FALSE EQU 0
- TRUE EQU 1
- EMPTY EQU -1
- UNDEF EQU -2
-
- HT EQU 9
- LF EQU 10
- CR EQU 13
- CTLZ EQU 26
-
- CPM EQU 0000H
- BDOS EQU CPM+0005H
- CDMA EQU CPM+0080H
- TPA EQU CPM+0100H
-
- ; compare with given value
- ;
- ?CPHL MACRO ?VALUE
- PUSH DE
- LD DE,?VALUE
- CALL CPHL##
- POP DE
- ENDM
-
- ; copy string
- ;
- ; input:
- ; HL -> source
- ; all registers destroyed
- ?COPY MACRO ?ADDR
- LD DE,?ADDR
- CALL COPY##
- ENDM
-
- ; local storage
- DSEG
- LOCST: DS 8
- REST EQU LOCST
- LS EQU LOCST+2
- X EQU LOCST+4
- Y EQU LOCST+6
- SV EQU LOCST+4
- PTR EQU LOCST
- LSS EQU LS
- X1 EQU LOCST+4
- X2 EQU LOCST+6
- CSEG
-
- ;noretry(ast)
- ; ALPHASTATE * ast;
- ; {
- ; ast->datb = (PAIR)empty;
- ; }
- NORE::
- LD HL,EMPTY
-
- ;setretry(ast,addr)
- ; ALPHASTATE * ast;
- ; char * addr;
- ; {
- ; ast->datb = (PAIR *)addr;
- ; }
- SETRE::
- JP XLDATB##
-
- ;SYMBOL *
- ;vnext(pexp,plsub)
- ; EXPR * pexp;
- ; LSUBST * plsub;
- ; {
- ; SYMBOL * x;
- ; SEXPR * y;
- DSEG
- PEXP: DW 0
- PLSUB: DW 0
- VX: DW 0
- VY: DW 0
- CSEG
- VNEXT::
- LD (PEXP),HL
- LD (PLSUB),DE
- ;
- ; if (varp(pexp->list))
- CALL INDIR##
- CALL VARP##
- JR Z,VN1
- ; {
- ; y = value(vf(pexp->list,*plsub));
- PUSH HL
- LD HL,(PLSUB)
- CALL INDIR##
- EX DE,HL
- POP HL
- CALL VF##
- CALL VALUE##
- LD (VY),HL
- ; if (substp(y))
- CALL SUBSTP##
- JR Z,VN2
- ; return UNDEF;
- LD HL,UNDEF
- RET
- VN2:
- ; pexp->list = y->sexp.list;
- CALL @EXPR##
- EX DE,HL
- LD HL,(PEXP)
- LD (HL),E
- INC HL
- LD (HL),D
- ; *plsub = y->slist;
- LD HL,(VY)
- CALL @SLIST##
- EX DE,HL
- LD HL,(PLSUB)
- LD (HL),E
- INC HL
- LD (HL),D
- ; }
- VN1:
- ; if (nelistp(pexp->list))
- LD HL,(PEXP)
- CALL INDIR##
- CALL NELP##
- JR Z,VN3
- ; {
- ; x = pexp->list->left.symbol;
- CALL @LEFT##
- LD (VX),HL
- ; if (varp(x))
- CALL VARP##
- JR Z,VN4
- ; {
- ; y = value(vf(x,*plsub));
- PUSH HL
- LD HL,(PLSUB)
- CALL INDIR##
- EX DE,HL
- POP HL
- CALL VF##
- CALL VALUE##
- LD (VY),HL
- ; x = y->sexp.symbol;
- CALL @EXPR##
- LD (VX),HL
- ; if (varp(x))
- CALL VARP##
- JR Z,VN4
- ; x = y;
- LD HL,(VY)
- LD (VX),HL
- ; }
- VN4:
- ; pexp->list = pexp->list->right.list;
- LD HL,(PEXP)
- PUSH HL
- CALL INDIR##
- CALL @RIGHT##
- EX DE,HL
- POP HL
- LD (HL),E
- INC HL
- LD (HL),D
- ; return x;
- LD HL,(VX)
- RET
- ; }
- VN3:
- ; return UNDEF;
- LD HL,UNDEF
- RET
- ; }
-
- RETT:: LD HL,TRUE
- RETX: LD A,H
- OR L
- RET
- RETF:: LD HL,FALSE
- JR RETX
-
- ;built-in commands called in this form:
- ; f(rest,ast,ls,pbst)
- ; PAIR rest; (in HL) rest of atom
- ; ALPHASTATE * ast; (in IX) this state
- ; LSUBST ls; (in DE ) substs for rest
- ; BETASTATE * bst; (in IY) empty, at first
- ;
- ;return TRUE to succeed, return FALSE to fail
- ;call noretry() to prohibit further retries
- ;call setretry() to set entry point for next retry
-
- ; ==================== / ====================
- ;_cut(rest,ast,ls,pbst)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; LSUBST ls;
- ; BETASTATE ** pbst;
- ; {
- ; setretry(ast,&rcut);
- ; return TRUE;
- ; }
- _CUT::
- LD HL,RCUT
- CALL SETRE
- JP RETT
-
- ;rcut() /* retry of cut */
- ; {
- ; return EMPTY;
- ; }
- RCUT::
- LD HL,EMPTY
- LD A,H
- OR L
- RET
-
- ; ==================== APPEND ====================
- ; APPEND command
- ;
- ; open file for output, position to the end of the file
- _APPEN::
- PUSH HL
- PUSH DE
- CALL NORE
- CALL CLOSE## ; close existing output file
- POP DE
- POP HL
- CALL DOOUT##
- LD A,(OUTF##)
- DEC A
- JP NZ,RETT ; not disk file
- LD DE,OUTFCB##
- LD C,15 ; open file
- CALL BDOS
- INC A
- JR NZ,APPEN1
- LD (OUTF),A ; not found, revert to console
- JP RETF
- APPEN1: LD DE,OUTFCB##
- LD C,35 ; compute file size
- CALL BDOS
- LD HL,(OUTFCB##+33) ; random record number
- DEC HL
- LD (OUTFCB##+33),HL ; last existing record
- LD DE,OUTDMA##
- LD C,26 ; set DMA
- CALL BDOS
- LD DE,OUTFCB##
- LD C,33 ; read random
- CALL BDOS
- LD HL,OUTDMA##
- APPEN2: LD A,(HL)
- CP CTLZ
- JR Z,APPEN3
- INC HL
- ?CPHL OUTE##
- JR NZ,APPEN2
- LD DE,OUTFCB## ; read sequential to prepare
- LD C,20 ; next record field
- CALL BDOS
- LD HL,OUTE##
- APPEN3: LD (OUTP),HL
- JP RETT
-
- ; ==================== CLOSE ====================
- ;_close(rest,ast)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; {
- ; noretry(ast);
- ; close();
- ; }
-
- _CLOSE::
- CALL NORE
- CLOSEX: CALL CLOSE##
- JP RETT
-
- ; ==================== CREATE ====================
- ; CREATE command
- ;
- ; opens a new file as output
- ; deletes any existing file with the same name
- ; (cf. APPEND command)
- _CREA::
- PUSH HL
- PUSH DE
- CALL NORE
- CALL CLOSE## ; close existing output file
- POP DE
- POP HL
- CALL DOOUT##
- CALL SAVEX
- JP RETT
-
- ; ==================== FAIL ====================
- ;_fail()
- ; {
- ; return FALSE;
- ; }
- _FAIL::
- JP RETF
-
- ; ==================== LESS ====================
- ;_less(rest,ast,ls,pbst)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; LSUBST ls;
- ; BETASTATE ** pbst;
- ; {
- ; static EXPR x1;
- ; static EXPR x2;
- ; static LSUBST lss;
- _LESS::
- ;
- ; lss = ls;
- LD (REST),HL
- LD (LSS),DE
- ; noretry(ast);
- CALL NORE
- ; x1.list = vnext(&rest,&lss);
- LD HL,REST
- LD DE,LSS
- CALL VNEXT
- LD (X1),HL
- ; if (x1.list == UNDEF)
- ; return FALSE;
- ?CPHL UNDEF
- JP Z,RETF
- ; x2.list = vnext(&rest,&lss);
- LD HL,REST
- LD DE,LSS
- CALL VNEXT
- LD (X2),HL
- ; if (x2.list == UNDEF)
- ; return FALSE;
- ?CPHL UNDEF
- JP Z,RETF
- ; if (numbp(x1.number) && numbp(x2.number))
- ; return (x1.number < x2.number);
- LD HL,(X1)
- CALL NUMBP##
- JR Z,LE1
- LD HL,(X2)
- CALL NUMBP##
- JR Z,LE1
- LD HL,(X1)
- LD DE,(X2)
- CALL CPHL##
- JP C,RETT
- JP RETF
- LE1:
- ; if (symbp(x1.symbol) && symbp(x2.symbol))
- ; return (strcmp(x1.symbol->string,x2.symbol->string) < 0);
- LD HL,(X1)
- CALL SYMBP##
- JR Z,LE2
- LD HL,(X2)
- CALL SYMBP##
- JR Z,LE2
- LD HL,(X2)
- CALL @STR##
- PUSH HL
- LD HL,(X1)
- CALL @STR##
- POP DE
- CALL STRCMP##
- JP C,RETT
- JP RETF
- LE2:
- ; *pbst = makebeta(ast,empty);
- LD HL,EMPTY
- CALL MKBETA##
- ; if (substp(x1.symbol))
- LD HL,(X1)
- CALL SUBSTP##
- JR Z,LE3
- ; {
- ; setretry(ast,&rless);
- LD HL,RLESS
- CALL SETRE
- ; if (numbp(x2.number))
- LD HL,(X2)
- CALL NUMBP##
- JR Z,LE5
- ; {
- ; lessv(x2.number-1,x1.symbol);
- LD HL,(X2)
- DEC HL
- LD DE,(X1)
- CALL LESSV
- ; return TRUE;
- JP RETT
- ; }
- LE5:
- ; if (substp(x2.symbol))
- LD HL,(X2)
- CALL SUBSTP##
- JP Z,LE6
- ; {
- ; lessv(0,x1.symbol);
- LD HL,0
- LD DE,(X1)
- CALL LESSV
- ; lessv(1,x2.symbol);
- LD HL,1
- LD DE,(X2)
- CALL LESSV
- ; return TRUE;
- JP RETT
- ; }
- LE6 EQU RETF
- ; }
- LE3:
- ; else if (substp(x2.symbol))
- LD HL,(X2)
- CALL SUBSTP##
- JP Z,LE4
- ; {
- ; setretry(ast,&rless);
- LD HL,RLESS
- CALL SETRE
- ; if (numbp(x1.number))
- LD HL,(X1)
- CALL NUMBP##
- JP Z,LE4
- ; {
- ; lessv(x1.number+1,x2.symbol);
- LD HL,(X1)
- INC HL
- LD DE,(X2)
- CALL LESSV
- ; return TRUE;
- JP RETT
- ; }
- ; }
- LE4 EQU RETF
- ; return FALSE;
- ; }
- ;
- ;rless()
- RLESS: ; needs more work to do retries
- ; {
- ; fatal("\r\nRetry on LESS.");
- LD HL,RLMSG
- JP FATAL##
- DSEG
- RLMSG: DB CR,LF,'Retry on LESS.',0
- CSEG
- ; }
- ;
- ;lessv(val,sub)
- ; NUMBER val;
- ; SUBST * sub;
- ; {
- ; unify(val,empty,sub->vname,sub);
- LESSV:
- PUSH DE
- LD DE,EMPTY
- EXX
- POP HL
- PUSH HL
- CALL @VNAME##
- POP DE
- EXX
- JP UNIFY##
- ; }
-
- ; ==================== LIST ====================
- ;_list(rest,ast)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; {
- _LIST::
- ; noretry(ast);
- CALL NORE
- ; listt((SYMBOL *)sbot);
- LISTX: LD HL,(SBOT##)
- CALL LISTT
- ; return TRUE;
- JP RETT
- ; }
- ;
- ;listt(ptr) /* recursive */
- ; SYMBOL * ptr;
- ; {
- ; PAIR x;
- LISTT:
- LD (PTR),HL
- ;
- ; if (ptr != (SYMBOL *)empty)
- ?CPHL EMPTY
- RET Z
- ; {
- ; listt(ptr->lptr);
- LD HL,(PTR)
- PUSH HL
- CALL @LPTR##
- CALL LISTT ; recursive
- POP HL
- LD (PTR),HL
- ; if (nelistp(x = (PAIR)(ptr->addr)))
- CALL @ADDR##
- LD (X),HL
- CALL NELP##
- JR Z,LI1
- ; {
- ; do
- LI2:
- ; {
- ; listpr(x->left.list);
- LD HL,(X)
- CALL @LEFT##
- CALL LISTPR
- ; }
- ; while (nelistp(x = x->right.list)) ;
- LD HL,(X)
- CALL @RIGHT##
- LD (X),HL
- CALL NELP##
- JR NZ,LI2
- ; chrout('\r');
- ; chrout('\n');
- CALL CRLF##
- ; }
- LI1:
- ; listt(ptr->rptr);
- LD HL,(PTR)
- CALL @RPTR##
- JR LISTT ; tail recursion
- ; }
- ; }
- ;
- ;listpr(y)
- ; PAIR y;
- ; {
- LISTPR:
- LD (Y),HL
- ; chrout('(');
- LD A,'('
- CALL CHROUT##
- ; eprint(y->left.list,empty);
- LD HL,(Y)
- CALL @LEFT##
- LD DE,EMPTY
- CALL EPRINT##
- ; for (y = y->right.list ; nelistp(y) ; y = y->right.list)
- ; {
- LI4:
- LD HL,(Y)
- CALL @RIGHT##
- LD (Y),HL
- CALL NELP##
- JR Z,LI3
- ; msg("\r\n\t");
- LD HL,LI4MSG
- DSEG
- LI4MSG: DB CR,LF,HT,0
- CSEG
- CALL MSG##
- ; eprint(y->left.list,empty);
- LD HL,(Y)
- CALL @LEFT
- LD DE,EMPTY
- CALL EPRINT##
- ; }
- JR LI4
- LI3:
- ; msg(")\r\n");
- LD HL,LI3MSG
- DSEG
- LI3MSG: DB ')',CR,LF,0
- CSEG
- JP MSG##
- ; }
-
- ; ==================== LOAD ====================
- ; LOAD command
- ;
- ; load from given disk file
- ; default filetype 'PRO'
- _LOAD::
- CALL DOIN##
- CALL NORE
- LD A,(INF##)
- DEC A
- JP NZ,RETT ; not a disk file
- LD A,(INFCB##+9)
- CP ' ' ; no filetype?
- JR NZ,LOAD1
- LD HL,APRO## ; use default 'PRO'
- ?COPY INFCB##+9
- LOAD1: JP LOADX
-
- ; ==================== OPEN ====================
- ; OPEN command
- ;
- ; opens an existing file as input
- _OPEN::
- CALL DOIN##
- CALL NORE
- LD A,(INF##)
- DEC A
- JP NZ,RETT ; not a disk file
- LOADX: LD DE,INFCB##
- LD C,15 ; open file
- CALL BDOS
- INC A ; file found?
- JR NZ,OPEN1 ; yes
- XOR A
- LD (INF##),A
- JP RETF
- OPEN1: XOR A
- LD (INFCB##+32),A ; zero current record
- LD HL,INE## ; pointer beyond end
- LD (INP##),HL
- JP RETT
-
- ; ==================== READ ====================
- ;_read(rest,ast,ls,pbst)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; LSUBST ls;
- ; BETASTATE ** pbst;
- ; {
- ; PAIR x;
- _READ::
- LD (REST),HL
- LD (LS),DE
- ; noretry(ast);
- CALL NORE
- ; x = makepair(gtoken(),empty);
- CALL GTOKEN##
- JR READX
-
- ; ==================== READCHAR ====================
- ;_readc(rest,ast,ls,pbst)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; LSUBST ls;
- ; BETASTATE ** pbst;
- ; {
- ; PAIR x;
- ;
- _READC::
- LD (REST),HL
- LD (LS),DE
- ; noretry(ast);
- CALL NORE
- ; rdchar();
- CALL RDCHAR##
- ; x = makepair(character,empty);
- LD A,(CHR##)
- LD L,A
- LD H,0
- READX: LD DE,EMPTY
- CALL MKPAIR##
- LD (X),HL
- ; *pbst = makebeta(ast,empty);
- LD HL,EMPTY
- CALL MKBETA##
- ; if (unify(rest,ls,x,empty))
- ; return TRUE;
- LD HL,(X)
- LD DE,EMPTY
- EXX
- LD HL,(REST)
- LD DE,(LS)
- CALL UNIFY##
- JP NZ,RETT
- ; release(x);
- LD HL,(X)
- CALL RLS##
- ; return FALSE;
- JP RETF
- ; }
-
- ; ==================== READLIST ====================
- ;_readl(rest,ast,ls,pbst)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; LSUBST ls;
- ; BETASTATE ** pbst;
- ; {
- ; PAIR x;
- ;
- _READL::
- LD (REST),HL
- LD (LS),DE
- ; noretry(ast);
- CALL NORE
- ; opar = 0;
- XOR A
- LD (OPAR##),A
- ; x = makepair(rdg1(),empty);
- CALL RDG1##
- JR READX
-
- ; ==================== SAVE ====================
- ; SAVE command
- ;
- ; saves database to named file
- ; default filetype 'PRO'
- _SAVE::
- PUSH HL
- PUSH DE
- CALL NORE
- CALL CLOSE## ; close existing output file
- POP DE
- POP HL
- CALL DOOUT##
- LD A,(OUTFCB##+9)
- CP ' ' ; no filetype?
- JR NZ,SAVE1
- LD HL,APRO## ; use default 'PRO'
- ?COPY OUTFCB##+9
- SAVE1: CALL SAVEX ; create the file for output
- CALL LISTX ; send listing to file
- JP CLOSEX ; close file
- SAVEX:
- LD A,(OUTF##)
- DEC A
- RET NZ ; not disk file
- LD DE,OUTFCB##
- LD C,19 ; delete file
- CALL BDOS
- LD DE,OUTFCB##
- LD C,22 ; make file
- CALL BDOS
- INC A
- JP Z,RETF ; unsuccessful
- LD HL,OUTDMA##
- LD (OUTP##),HL
- RET
-
- ; ==================== WRITE ====================
- ;_write(rest,ast,ls,pbst)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; LSUBST ls;
- ; BETASTATE ** pbst;
- ; {
- ; static SUBVAL sv;
- _WRITE::
- LD (REST),HL
- LD (LS),DE
- ; noretry(ast);
- CALL NORE
- ; if (varp(rest))
- LD HL,(REST)
- CALL VARP##
- JR Z,WR1
- ; {
- ; if (substp(sv.val = value(vf(rest,ls))))
- ; ;
- LD DE,(LS)
- CALL VF##
- CALL VALUE##
- LD (SV),HL
- CALL SUBSTP##
- JR NZ,WR1
- ; else
- ; {
- ; rest = sv.assgn->sexp.list;
- CALL @EXPR##
- LD (REST),HL
- ; ls = sv.assgn->slist;
- LD HL,(SV)
- CALL @SLIST##
- LD (LS),HL
- ; }
- ; }
- WR1:
- ; while (nelistp(rest))
- LD HL,(REST)
- CALL NELP##
- JR Z,WR2
- ; {
- ; eprint(rest->left.list,ls);
- CALL @LEFT
- LD DE,(LS)
- CALL EPRINT##
- ; rest = rest->right.list;
- LD HL,(REST)
- CALL @RIGHT##
- LD (REST),HL
- ; if (varp(rest))
- CALL VARP##
- JR Z,WR3
- ; {
- ; if (substp(sv.val = value(vf(rest,ls))))
- ; ;
- LD DE,(LS)
- CALL VF##
- CALL VALUE##
- LD (SV),HL
- CALL SUBSTP##
- JR NZ,WR3
- ; else
- ; {
- ; rest = sv.assgn->sexp.list;
- CALL @EXPR##
- LD (REST),HL
- ; ls = sv.assgn->slist;
- LD HL,(SV)
- CALL @SLIST##
- LD (LS),HL
- ; }
- ; }
- WR3 EQU WR1
- JR WR1
- ; }
- WR2:
- ; return TRUE;
- JP RETT
- ; }
-
- ; ==================== WRITECHAR ====================
- ;_wrch(rest,ast,ls,pbst)
- ; PAIR rest;
- ; ALPHASTATE * ast;
- ; LSUBST ls;
- ; BETASTATE ** pbst;
- ; {
- ; NUMBER x;
- _WRCH::
- LD (REST),HL
- LD (LS),DE
- ; noretry(ast);
- CALL NORE
- ; x = vnext(&rest,&ls);
- LD HL,REST
- LD DE,LS
- CALL VNEXT
- ; if (! numbp(x))
- ; return FALSE;
- CALL NUMBP##
- JP Z,RETF
- ; if (x > 255)
- ; return FALSE;
- LD DE,256
- CALL CPHL##
- JP NC,RETF
- ; putc(x,outfile);
- LD A,L
- CALL CHROUT##
- ; return TRUE;
- JP RETT
- ; }
-
- END