Menu

[r376]: / mpl.pas  Maximize  Restore  History

Download this file

219 lines (191 with data), 11.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
(* MPL - MICRO PROGRAMMING LANGUAGE / COPYRIGHT (C) 2017-2019 DEREK JOHN EVANS *)
(* NOTE: CP/M END ADDRESS = E000 *)
{$D-}{$I-}{$R-}{$V-}
{$IFDEF TPC}{$A-}{$ENDIF}
{$IFDEF FPC}{$MODE TP}{$S-}{$ENDIF}
{$IFDEF HPC}{$M 8,4,4,4}{$F-}{$S-}{$ENDIF}
PROGRAM MPL;
{$IFDEF TPC}TYPE TADR=INTEGER;{$ELSE}USES DOS; TYPE TADR=LONGINT;
FUNCTION ADDR(VAR V):TADR; BEGIN ADDR:=TADR(@V) END;{$ENDIF}
CONST H80=128; TOM=12287; (* 12287=24K 16382=~32K *)
TYPE
TCHR=PACKED RECORD VAL:CHAR END;
TFLG=BOOLEAN; TINT=INTEGER; TSTR=STRING[80];
PINT=RECORD CASE TINT OF 0:(ADR:TADR);1:(PTR:^TINT) END;
PSTR=RECORD CASE TINT OF 0:(ADR:TADR);1:(PTR:^TSTR) END;
PEXT=RECORD CASE TINT OF 0:(ADR:TADR);1:(PTR:^TEXT) END;
TERR=(ESYN,EDUP,EMIS); TLEV=(L0,L1,L2,L3,L4,L5,L6,L7,L8);
TOPR=(
OABRT,OCASE,OENTR,OEXIT,OIDX1,OIDX2,OJPEQ,OJPNE,OJSUB,OJUMP,OLEAD,OLOAD,
OAD1A,OAD2A,OADA1,OADA2,OADD1,OADD2,OADD3,OADD4,OBAN1,OBAN2,OBAN3,OBAN4,
OBOR1,OBOR2,OBOR3,OBOR4,OBOX1,OBOX2,OBOX3,OBOX4,ODIV1,ODIV2,ODIV3,ODIV4,
OEQV1,OEQV2,OEQV3,OEQV4,OLD11,OLD12,OLD21,OLD22,OLIT1,OLIT2,OLIT3,OLIT4,
OMOD1,OMOD2,OMOD3,OMOD4,OMUL1,OMUL2,OMUL3,OMUL4,OSET1,OSET2,OSET3,OSET4,
OSHL1,OSHL2,OSHL3,OSHL4,OSHR1,OSHR2,OSHR3,OSHR4,OSU1A,OSU2A,OSUA1,OSUA2,
OSUB1,OSUB2,OSUB3,OSUB4,OTAN1,OTAN2,OTEQ1,OTEQ2,OTGE1,OTGE2,OTGT1,OTGT2,
OTLE1,OTLE2,OTLT1,OTLT2,OTNE1,OTNE2,OTOR1,OTOR2,OTOX1,OTOX2,OFRE1,OFRE2,
OOO96);
VAR
GM:PACKED RECORD CASE TINT OF
0:(V:PACKED ARRAY[(VNIL,VTOM,VAUX,VTMP,VPRG)] OF TINT);
1:(I:PACKED ARRAY[0..TOM] OF TINT);
2:(C:PACKED ARRAY[0..0] OF TCHR) END;
GI,GE,GMZ,GSZ:TINT; GC:CHAR; GS:TSTR; GL:TLEV; GO:TOPR;
GPF:PEXT; GPS:PSTR; GPI: PINT; GV:PACKED ARRAY[0..511] OF TINT;
PROCEDURE WC(C:CHAR); BEGIN GM.C[GMZ].VAL:=C; GMZ:=SUCC(GMZ) END;
PROCEDURE WI(I:TINT); BEGIN MOVE(I,GM.C[GMZ],2); GMZ:=GMZ+2 END;
PROCEDURE WS; VAR PS:PSTR; BEGIN
PS.ADR:=ADDR(GM.C[GMZ]); PS.PTR^:=GS; GMZ:=SUCC(GMZ+LENGTH(GS)) END;
PROCEDURE WO(O:TOPR); BEGIN GM.C[GMZ].VAL:=CHR(ORD(O)); GMZ:=SUCC(GMZ) END;
PROCEDURE OB(O:TOPR;B:TFLG); BEGIN IF B THEN WO(PRED(O)) ELSE WO(O) END;
PROCEDURE OC(O:TOPR;C:CHAR); BEGIN WO(O); WC(C) END;
PROCEDURE OI(O:TOPR;I:TINT); BEGIN WO(O); WI(I) END;
PROCEDURE OCI(O:TOPR;CI:TINT); BEGIN
IF(CI>=-H80)AND(CI<H80)THEN OC(PRED(O),CHR(CI)) ELSE OI(O,CI) END;
PROCEDURE OJP(O:TOPR;I:TINT); VAR MZ:TINT; BEGIN
MZ:=GMZ; GMZ:=I; OI(O,MZ); GMZ:=MZ END;
PROCEDURE OLI(I:TINT); BEGIN
IF(I<(ORD(OOO96)-H80))OR(I>=H80)THEN OCI(OLIT2,I) ELSE WC(CHR(I+H80)) END;
PROCEDURE FAIL(E:TERR); BEGIN GE:=SUCC(GE); WRITELN; WRITE(' --> '); CASE E OF
ESYN:WRITE('SYNTAX'); EDUP:WRITE('DUPLICATE'); EMIS:WRITE('MISSING') END;
WRITE('? @ "',GS,'"') END;
FUNCTION OPEN:TFLG; BEGIN OPEN:=TRUE; ASSIGN(GPF.PTR^,{$IFDEF HPC}'M:\MPL\'+{$ENDIF}GS);
RESET(GPF.PTR^); IF IORESULT<>0 THEN BEGIN ASSIGN(GPF.PTR^,GS); RESET(GPF.PTR^);
OPEN:=IORESULT=0 END END;
PROCEDURE SHUT; BEGIN CLOSE(GPF.PTR^); IF GO<>OABRT THEN FAIL(ESYN) END;
PROCEDURE RDCH; BEGIN GC:=CHR(0); IF NOT EOF(GPF.PTR^) THEN READ(GPF.PTR^,GC) END;
PROCEDURE ARGV(VAR S:TSTR; I:TINT); BEGIN S:=PARAMSTR(I);
FOR I:=1 TO LENGTH(S) DO S[I]:=UPCASE(S[I]) END;
FUNCTION META:CHAR; BEGIN IF GC='*' THEN BEGIN RDCH; CASE UPCASE(GC) OF
'0':GC:=CHR(00);'A':GC:=CHR(07);'B':GC:=CHR(08);'T':GC:=CHR(09);'N':GC:=CHR(10);
'V':GC:=CHR(11);'P':GC:=CHR(12);'F':GC:=CHR(12);'R':GC:=CHR(13);'C':GC:=CHR(13);
'E':GC:=CHR(27);'S':GC:=CHR(32) END END; META:=GC END;
PROCEDURE LO1(L:TLEV;O:TOPR); BEGIN GL:=L; GO:=O END;
PROCEDURE LO2(L:TLEV;O:TOPR); BEGIN GL:=L; GO:=O; RDCH END;
PROCEDURE NEXT; LABEL 0; BEGIN 0:LO1(L1,OABRT);
WHILE GC IN [CHR(1)..CHR(32)] DO RDCH; GC:=UPCASE(GC); GS:=GC;
IF GC IN ['.','A'..'Z'] THEN BEGIN
RDCH; GC:=UPCASE(GC); WHILE GC IN ['.','A'..'Z','0'..'9'] DO
BEGIN GS:=GS+GC; RDCH; GC:=UPCASE(GC) END; GO:=OLIT1 END
ELSE IF GC IN ['0'..'9'] THEN BEGIN GI:=ORD(GC)-ORD('0'); RDCH;
WHILE GC IN ['0'..'9'] DO BEGIN GI:=GI*10+ORD(GC)-ORD('0');
GS:=GS+GC; RDCH END; GO:=OLIT2 END ELSE BEGIN RDCH; CASE GS[1] OF
'''':BEGIN GI:=ORD(META); RDCH; IF GC='''' THEN LO2(L1,OLIT2) END;
'"':BEGIN GS:=''; WHILE NOT(GC IN [CHR(0),'"']) DO BEGIN
GS:=GS+META; RDCH END; IF GC='"' THEN LO2(L1,OLIT3) END;
'/':CASE GC OF'=':LO2(L2,ODIV4);
'*':BEGIN RDCH; REPEAT WHILE NOT(GC IN [CHR(0),'*'])DO RDCH;
RDCH UNTIL GC IN [CHR(0),'/']; RDCH; GOTO 0 END;
'/':BEGIN READLN(GPF.PTR^,GS); RDCH; GOTO 0 END ELSE LO1(L3,ODIV2)END;
'(':GO:=OSET1;')':GO:=OSET2;'[':GO:=OENTR;']':GO:=OEXIT;',':GO:=OIDX1;
'%':GO:=OLD11;'!':GO:=OLD12;'@':GO:=OJUMP;'?':GO:=OCASE;';':GO:=OIDX2;
':':IF GC=':'THEN LO2(L1,OJSUB)ELSE GO:=OJPNE;'$':LO1(L2,OLEAD);
'*':IF GC='='THEN LO2(L2,OMUL4)ELSE LO1(L3,OMUL2);
'=':IF GC='='THEN LO2(L6,OTEQ2)ELSE LO1(L2,OSET4);
'\':IF GC='='THEN LO2(L2,OMOD4)ELSE LO1(L3,OMOD2);
'#':CASE GC OF'#':LO2(L1,OLOAD);'=':LO2(L2,OEQV4)ELSE LO1(L7,OEQV2)END;
'&':CASE GC OF'&':LO2(L8,OTAN2);'=':LO2(L2,OBAN4)ELSE LO1(L7,OBAN2)END;
'+':CASE GC OF'+':LO2(L1,OAD2A);'=':LO2(L2,OADD4)ELSE LO1(L4,OADD2)END;
'-':CASE GC OF'-':LO2(L1,OSU2A);'=':LO2(L2,OSUB4)ELSE LO1(L4,OSUB2)END;
'^':CASE GC OF'^':LO2(L8,OTOX2);'=':LO2(L2,OBOX4)ELSE LO1(L7,OBOX2)END;
'|':CASE GC OF'|':LO2(L8,OTOR2);'=':LO2(L2,OBOR4)ELSE LO1(L7,OBOR2)END;
'>':CASE GC OF'>':BEGIN RDCH; IF GC='='THEN LO2(L2,OSHR4)ELSE LO1(L5,OSHR2)END;
'=':LO2(L6,OTGE2)ELSE LO1(L6,OTGT2)END;
'<':CASE GC OF'<':BEGIN RDCH; IF GC='='THEN LO2(L2,OSHL4)ELSE LO1(L5,OSHL2)END;
'=':LO2(L6,OTLE2);'>':LO2(L6,OTNE2)ELSE LO1(L6,OTLT2)END END END END;
FUNCTION FIND:TFLG; VAR SZ:TINT; PS:PSTR; BEGIN FIND:=FALSE;
IF GO=OLIT1 THEN BEGIN SZ:=GSZ; PS:=GPS; WHILE SZ>0 DO BEGIN SZ:=PRED(SZ);
IF PS.PTR^=GS THEN BEGIN GPI.ADR:=ADDR(GV[SZ]); FIND:=TRUE; EXIT END;
PS.ADR:=SUCC(PS.ADR+LENGTH(PS.PTR^)) END END ELSE FAIL(ESYN) END;
PROCEDURE ADDS(I:TINT); BEGIN GPS.ADR:=PRED(GPS.ADR-LENGTH(GS)); GPS.PTR^:=GS;
GPI.ADR:=ADDR(GV[GSZ]); GPI.PTR^:=I; GSZ:=SUCC(GSZ) END;
FUNCTION NUMB:TINT; VAR I:TINT; PI:PINT; NEG:TFLG; BEGIN PI:=GPI; I:=0;
NEG:=GO=OSUB2; IF GL=L4 THEN NEXT; IF GO=OLIT2 THEN BEGIN I:=GI; NEXT END
ELSE IF FIND THEN BEGIN IF GS[1]='.' THEN BEGIN I:=GPI.PTR^; NEXT END
ELSE BEGIN NEXT; IF GO=OLEAD THEN BEGIN I:=GPI.PTR^; NEXT END
ELSE I:=GM.I[GPI.PTR^SHR 1] END END ELSE FAIL(EMIS);
IF NEG THEN NUMB:=-I ELSE NUMB:=I; GPI:=PI END;
FUNCTION ONOT(O:TOPR):TFLG; BEGIN IF GO=O THEN BEGIN ONOT:=FALSE; NEXT END
ELSE ONOT:=TRUE END;
PROCEDURE EXPR; FORWARD; PROCEDURE LOAD; FORWARD;
PROCEDURE ELEM(L:TLEV;IS1:TFLG); LABEL 0; VAR I:TINT; O:TOPR; ID:TFLG;
BEGIN IF L>L2 THEN BEGIN ELEM(PRED(L),TRUE); WHILE L=GL DO BEGIN
O:=GO; NEXT; WO(OSET1); ELEM(PRED(L),TRUE); WO(O) END END
ELSE BEGIN CASE GO OF OCASE:BEGIN NEXT; ELEM(L0,IS1); WO(OCASE) END;
OSET1:BEGIN NEXT; EXPR; IF GO=OSET2 THEN NEXT ELSE FAIL(EMIS) END;
OSET4:BEGIN NEXT; EXPR; WO(OEXIT) END;
OJUMP:BEGIN I:=GMZ; NEXT; EXPR; OI(OJPNE,I) END;
OLIT2:BEGIN OLI(GI); NEXT END; OLIT3:BEGIN WO(OLIT3); WS; NEXT END;
OLD11,OLD12:BEGIN IS1:=GO=OLD11; NEXT; ELEM(L0,IS1); IF(L=GL)AND(L=L2)THEN
BEGIN IF GO=OLEAD THEN FAIL(ESYN); WO(OSET1); O:=GO; NEXT; EXPR;
IF IS1 THEN WO(PRED(O)) ELSE WO(O) END ELSE OB(OLD12,IS1) END
ELSE BEGIN O:=GO; IF GL IN [L3,L4,L5,L6] THEN BEGIN
NEXT; ELEM(L1,TRUE); WO(PRED(O)) END
ELSE BEGIN ID:=O IN [OAD2A,OSU2A]; IF ID THEN NEXT; IF FIND THEN
IF GS[1]='.' THEN BEGIN IF ID THEN FAIL(ESYN); OLI(GPI.PTR^); NEXT END
ELSE BEGIN IF GPI.PTR^<0 THEN BEGIN OLI(-GPI.PTR^); WO(OLEAD) END ELSE OLI(GPI.PTR^);
NEXT; IF ID THEN OB(O,IS1) ELSE IF(L=GL)AND(L=L2)THEN BEGIN
IF GO=OLEAD THEN NEXT ELSE BEGIN WO(OSET1); O:=GO; NEXT; EXPR; WO(O)
END END ELSE IF GO IN [OAD2A,OSU2A] THEN BEGIN OB(SUCC(SUCC(GO)),IS1);
NEXT END ELSE WO(OLOAD) END ELSE FAIL(EMIS) END END END;
IF L>L0 THEN BEGIN 0:CASE GO OF
OLD11,OLD12:BEGIN WO(OSET1); IS1:=GO=OLD11; NEXT; ELEM(L0,TRUE);
IF(L=GL)AND(L=L2)THEN BEGIN OB(OIDX2,IS1); O:=GO; NEXT; IF O=OLEAD THEN
WO(OSET2) ELSE BEGIN EXPR; IF IS1 THEN WO(PRED(O)) ELSE WO(O) END END
ELSE OB(OLD22,IS1); GOTO 0 END;
OSET1:BEGIN WO(OSET1); I:=1; NEXT; IF GO<>OSET2 THEN
REPEAT EXPR; WO(OSET1); I:=SUCC(I) UNTIL ONOT(OIDX1);
OLI(I); WO(OJSUB); IF GO=OSET2 THEN NEXT ELSE FAIL(EMIS); GOTO 0
END END END END END;
PROCEDURE EXPR; VAR JPEX,JPEQ,JPNE:TINT; BEGIN JPEX:=GMZ;
IF GO=OENTR THEN BEGIN REPEAT NEXT; EXPR UNTIL GO<>OIDX2;
IF GO=OEXIT THEN NEXT ELSE FAIL(EMIS) END ELSE ELEM(L8,TRUE);
CASE GO OF
OJUMP:BEGIN NEXT; JPEQ:=GMZ; OI(OJPEQ,0); EXPR; OI(OJUMP,JPEX); OJP(OJPEQ,JPEQ) END;
OCASE:BEGIN NEXT; IF GO=OJPNE THEN BEGIN NEXT; JPNE:=GMZ; OI(OJPNE,0); EXPR;
OJP(OJPNE,JPNE) END ELSE BEGIN JPEQ:=GMZ; OI(OJPEQ,0); EXPR;
IF GO<>OJPNE THEN OJP(OJPEQ,JPEQ) ELSE BEGIN JPNE:=GMZ; OI(OJUMP,0);
OJP(OJPEQ,JPEQ); NEXT; EXPR; OJP(OJUMP,JPNE) END END END END END;
PROCEDURE ENTR; VAR AIMP,AVAR:TFLG; I,SZ:TINT; PS:PSTR; BEGIN
WHILE GE=0 DO CASE GO OF OLOAD:REPEAT NEXT; LOAD; NEXT UNTIL GO<>OIDX1;
OABRT,OEXIT:EXIT; OENTR:BEGIN SZ:=GSZ; PS:=GPS; NEXT; ENTR; GSZ:=SZ; GPS:=PS;
IF GO=OEXIT THEN NEXT ELSE FAIL(EMIS) END
ELSE BEGIN GMZ:=SUCC(GMZ)AND-2; AIMP:=GO=OJSUB; IF AIMP THEN NEXT;
WRITELN(GMZ:5,': ',GS);
IF GO<>OLIT1 THEN FAIL(ESYN) ELSE BEGIN AVAR:=GS[1]<>'.';
IF AIMP THEN IF FIND THEN IF AVAR THEN GM.I[GPI.PTR^SHR 1]:=GMZ
ELSE FAIL(ESYN) ELSE FAIL(EMIS) ELSE ADDS(GMZ);
IF GE=0 THEN BEGIN NEXT; CASE GO OF OJPNE:BEGIN NEXT; GPI.PTR^:=NUMB END;
OSET4:REPEAT NEXT; CASE GO OF OLD11:BEGIN NEXT; GMZ:=GMZ+NUMB END;
OLD12:BEGIN NEXT; GMZ:=GMZ+NUMB SHL 1 END;
OLIT3:BEGIN WS; NEXT END ELSE WI(NUMB) END UNTIL GO<>OIDX1;
OSET1:BEGIN IF AVAR THEN IF NOT AIMP THEN WI(GMZ+2); NEXT;
PS:=GPS; SZ:=GSZ; I:=1; IF GO<>OSET2 THEN
REPEAT REPEAT IF GO<>OIDX2 THEN IF(GO<>OLIT1)OR(GS[1]='.')THEN FAIL(ESYN)
ELSE BEGIN ADDS(-I); NEXT; CASE GO OF
OLD11:BEGIN NEXT; I:=I+SUCC(NUMB)SHR 1 END;
OLD12:BEGIN NEXT; I:=I+NUMB END ELSE I:=SUCC(I) END;
END UNTIL ONOT(OIDX1) UNTIL ONOT(OIDX2);
IF GO=OSET2 THEN NEXT ELSE FAIL(EMIS); OLI(I); WO(OENTR); EXPR;
WO(OEXIT); GPS:=PS; GSZ:=SZ END ELSE IF AVAR THEN FAIL(ESYN)
END END END END END END;
PROCEDURE LOAD; VAR F:TEXT; PF:PEXT; C:CHAR; BEGIN GO:=OLIT1;
IF NOT FIND THEN BEGIN ADDS(0); PF:=GPF; C:=GC; GPF.ADR:=ADDR(F); GC:=CHR(32);
IF OPEN THEN BEGIN NEXT; ENTR; SHUT END ELSE FAIL(EMIS); GPF:=PF; GC:=C END END;
PROCEDURE SAVE; VAR F:FILE OF TCHR; BEGIN
{$IFDEF HPC}ERASE('@');{$ENDIF} ASSIGN(F,'@'); REWRITE(F);
IF IORESULT=0 THEN BEGIN BLOCKWRITE(F,GM.C,GM.V[VTOM]); CLOSE(F) END END;
BEGIN WRITELN; WRITELN('MPL COMPILER / COPYRIGHT (C) 2017-2019 DEREK JOHN EVANS');
IF PARAMCOUNT<1 THEN WRITELN('USAGE: MPL <FILE>')
ELSE BEGIN ARGV(GS,1); GPS.ADR:=ADDR(GM.I[TOM]);
FOR GI:=0 TO TOM DO GM.I[GI]:=0; GE:=0; GSZ:=0; GMZ:=ORD(VPRG)SHL 1;
WRITELN; WRITELN('COMPILING'); WRITELN; LOAD;
IF GE=0 THEN BEGIN GS:='.'; GO:=OLIT1; IF FIND THEN BEGIN
GM.V[VAUX]:=GMZ; OLI(GPI.PTR^); WO(OSET1); OLI(1); WO(OJSUB); WO(OABRT);
GM.V[VNIL]:=1234; GM.V[VTOM]:=GMZ END
ELSE FAIL(EMIS) END; WRITELN; IF GE<>0 THEN BEGIN WRITELN;
WRITELN('FAILED'); WRITELN; WRITELN(GE:5,' ERRORS') END
ELSE BEGIN WRITELN(GSZ:5,' SYMBOLS'); WRITELN(GMZ:5,' BYTES');
SAVE; WRITELN; WRITELN('COMPLETED') END END;
WRITELN; {$IFDEF FPC}READLN{$ENDIF}
END.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.