home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
languags
/
prolog
/
epro23.ark
/
EPRO.MAC
< prev
next >
Wrap
Text File
|
1986-11-02
|
7KB
|
404 lines
; EPRO.Z80
; ******** E-Prolog ******
; G. A. Edgar
; 107 W. Dodridge St., Columbus, OH 43202
; CompuServe 70715,1324
; Not copyrighted, but if you improve it, how about
; at least letting me know?
.Z80
SIGNON:: DB 'E-Prolog ver. 2.3'
DB ' (August 1, 1985)',13,10,0
SYMBSZ EQU 3000 ; symbol table size
STACKSZ EQU 1500 ; stack size
.COMMENT %
versions
1.0 April 2, 1985
For Macro-80, Z-80, CP/M 2.2
Based on PIL : Prolog in Lisp,
by Ken Kahn, Par Emanuelson, Martin Nilsson.
1.1 April 10, 1985
Packing of node space
Rewrite VALUE
1.2 April 19, 1985
Rearrange database
(version 1.2 released)
1.3 May 3, 1985
bug fixes
2.0 May 19, 1985
Rewritten, mostly in C
2.1 June 1, 1985
Back into M80, Z-80, CP/M
2.2 July 5, 1985
line-feed following BDOS 10 call
fixes for UNIFY, PROVE
2.3 August 1, 1985
version for SIG/M
Most of the C language source has been left in the code as
comments. The source files are: EPRO.Z80, CLASS.Z80,
SYMB.Z80, HEAP.Z80, DATBADD.Z80, UNIFY.Z80, CMD.Z80,
PROVE.Z80, INPUT.Z80, OUTPUT.Z80, ERROR.Z80, ASSEM.Z80,
INIT.Z80 . The documentation file is EPRO.DOC .
/* types */
typedef unsigned NUMBER;
typedef int BOOLEAN;
typedef struct XSYMBOL {
char * addr;
struct XSYMBOL * lptr;
struct XSYMBOL * rptr;
char string[1];
} SYMBOL;
typedef SYMBOL * VARIABLE;
typedef struct XNODE * PAIR;
typedef union {
PAIR list;
SYMBOL * symbol;
NUMBER number;
} EXPR;
typedef struct XNODE {
EXPR left;
EXPR right;
} NODE;
typedef union XSUBVAL {
struct XSUBST * val;
struct XSEXPR * assgn;
} SUBVAL;
typedef struct XSUBST {
VARIABLE vname;
SUBVAL back;
SUBVAL forw;
} SUBST;
typedef SUBST * LSUBST;
typedef struct XSEXPR {
EXPR sexp;
SUBVAL back;
LSUBST slist;
} SEXPR;
typedef struct {
struct XALPHASTATE * pred;
EXPR assertion;
SUBST subst[1];
} BETASTATE;
typedef struct XALPHASTATE {
BETASTATE * pred; /* tree pred */
PAIR goal;
PAIR datb;
BETASTATE * back; /* linear pred */
} ALPHASTATE;
END OF COMMENT %
FALSE EQU 0
TRUE EQU 1
EMPTY EQU -1 ; empty list
UNDEF EQU -2 ; undefined pointer
FROZEN EQU -3 ; frozen variable
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
; -------------- global variables --------------------
DSEG
;unsigned symbs = SYMBSZ;
SYMBS:: DW SYMBSZ
;unsigned stacks = STACKSZ;
STACKS:: DW STACKSZ
;int opar; /* no. of open parentheses */
OPAR:: DS 1
;char * stop; /* top of symbol table */
;#define hbot stop /* bottom of heap */
HBOT::
STOP:: DS 2
;char * hfree; /* free space in heap */
HFREE:: DS 2
;char * htop; /* top of heap */
HTOP:: DS 2
;char * datbtop; /* top of database */
DBTOP:: DS 2
CSEG
;main()
MAIN::
LD SP,(6)
; {
; static EXPR e;
;
; init();
CALL INIT##
; datbtop = hbot;
LD HL,(HBOT)
LD (DBTOP),HL
; while (1)
EP1:
; {
; hfree = datbtop;
LD HL,(DBTOP)
LD (HFREE),HL
; opar = 0;
XOR A
LD (OPAR),A
; e.list = rdg1();
CALL RDG1
; if (atomp(e.list) || varp(e.list))
CALL ATOMP##
JR NZ,EP3
CALL VARP##
JR Z,EP2
; {
EP3:
; /* prove */
; prove(e.list);
CALL PROVE##
; continue;
JR EP1
; }
EP2:
; if (!(nelistp(e.list)))
CALL NELP##
JR NZ,EP4
; {
; eprint(e.list,empty);
EP5:
LD DE,EMPTY
CALL EPRINT##
; error(" illegal.\r\n");
LD HL,EP3MSG
CALL ERROR##
DSEG
EP3MSG: DB ' illegal.',CR,LF,0
CSEG
; continue;
JR EP1
; }
EP4:
; if (clausep(e.list))
CALL CLP##
JR Z,EP5
; {
; /* add to database */
; datbadd(e.list->left.list->left.symbol,e.list);
PUSH HL
CALL @LEFT##
CALL @LEFT##
POP DE
CALL DBADD##
; continue;
JR EP1
; }
;EP5: above
; /* otherwise */
; eprint(e.list,empty);
; error(" illegal!\r\n");
; }
; exit(0);
; }
; READ A GOAL
;
; input:
; none
; output:
; HL -> goal [EXPR]
;EXPR
;rdg1() /* recursive */
; {
RDG1::
; while (separp(rdchar()))
; ;
RD1:
CALL RDCHAR##
CALL SEPARP
JR NZ,RD1
; if (character == '(')
LD A,(CHR##)
CP '('
JR NZ,RD2
; {
; opar++;
LD A,(OPAR)
INC A
LD (OPAR),A
; return rdg2();
JP RDG2
; }
RD2:
; else
; {
; unrdchar();
CALL UNRDCH##
; return gtoken();
JP GTOKEN##
; }
; }
;
;EXPR
;rdg2()
RDG2:
; {
; unsigned temp;
DSEG
TEMP: DW 0
CSEG
;
; while (separp(rdchar()))
; ;
RD3:
CALL RDCHAR##
CALL SEPARP
JR NZ,RD3
; if (character == ')')
LD A,(CHR##)
CP ')'
JR NZ,RD4
; {
; opar--;
LD A,(OPAR)
DEC A
LD (OPAR),A
; return empty;
LD HL,EMPTY
RET
; }
RD4:
; else if (character == '|')
CP '|'
JR NZ,RD5
; {
; temp = rdg1();
CALL RDG1 ; recursion
LD (TEMP),HL
; while (separp(rdchar()))
; ;
RD6:
CALL RDCHAR##
CALL SEPARP
JR NZ,RD6
; if (!(character == ')'))
LD A,(CHR##)
CP ')'
JR Z,RD7
; fatal("\r\nSyntax error.\r\n");
LD HL,RD6MSG
JP FATAL##
DSEG
RD6MSG: DB CR,LF,'Syntax error.',CR,LF,0
CSEG
RD7:
; opar--;
LD A,(OPAR)
DEC A
LD (OPAR),A
; return temp;
LD HL,(TEMP)
RET
; }
RD5:
; else
; {
; unrdchar();
CALL UNRDCH##
; temp = rdg1();
CALL RDG1 ; recursion
; return makepair(temp,rdg2());
PUSH HL
CALL RDG2 ; recursion
EX DE,HL
POP HL
JP MKPAIR##
; }
; }
; SEPARATOR?
;
; is it a separator? also, skip comment in [...]
; input:
; none
; output:
; Z flag set = no
;BOOLEAN
;separp()
SEPARP::
; {
; switch (character)
LD A,(CHR##)
; {
; case '[':
CP '['
JR NZ,SE1
; do
; rdchar();
SE2:
CALL RDCHAR##
LD A,(CHR##)
; while (character != ']') ;
CP ']'
JR NZ,SE2
JR RETT
SE1:
; case ' ':
CP ' '
JR Z,RETT
; case '\r':
CP CR
JR Z,RETT
; case '\n':
CP LF
JR Z,RETT
; case '\t':
CP HT
JR NZ,RETF
; return TRUE;
RETT:
OR A
RET
; default:
; return FALSE;
RETF:
XOR A
RET
; }
; }
; 16 bit compare
;
; input:
; HL , DE
; output:
; C, Z flags
; AF destroyed, others saved
CPHL:: XOR A ; NC
PUSH HL
SBC HL,DE
POP HL
RET
END MAIN