1 eÿTermcap.mod
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\r\b(*
2 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 See the copyright notice in the ACK home directory, in the file "Copyright".
7 Module: Interface to termcap database
8 From: Unix manual chapter 3
9 Version: $Id: Termcap.mod,v 1.5 1994/06/24 12:50:13 ceriel Exp $
13 IMPLEMENTATION MODULE Termcap;
16 FROM SYSTEM IMPORT ADR, ADDRESS;
17 FROM Unix IMPORT gtty;
21 TYPE STR = ARRAY[1..32] OF CHAR;
22 STRCAP = POINTER TO STR;
24 VAR Buf, Buf1 : ARRAY [1..1024] OF CHAR;
27 PROCEDURE Tgetent(name: ARRAY OF CHAR) : INTEGER;
32 i := XXTermcap.tgetent(ADR(Buf), ADR(name));
34 IF gtty(1, ADR(sp)) < 0 THEN
36 XXTermcap.ospeed := ORD(sp[2]);
39 IF Tgetstr("pc", x) THEN
40 XXTermcap.PC := x^[1];
41 ELSE XXTermcap.PC := 0C;
43 IF Tgetstr("up", x) THEN ; END; XXTermcap.UP := x;
44 IF Tgetstr("bc", x) THEN ; END; XXTermcap.BC := x;
49 PROCEDURE Tgetnum(id: ARRAY OF CHAR): INTEGER;
51 RETURN XXTermcap.tgetnum(ADR(id));
54 PROCEDURE Tgetflag(id: ARRAY OF CHAR): BOOLEAN;
56 RETURN XXTermcap.tgetflag(ADR(id)) = 1;
59 PROCEDURE Tgoto(cm: STRCAP; col, line: INTEGER): STRCAP;
61 RETURN XXTermcap.tgoto(cm, col, line);
64 PROCEDURE Tgetstr(id: ARRAY OF CHAR; VAR res: STRCAP) : BOOLEAN;
68 a := ADR(Buf1[BufCnt]);
69 a2 := XXTermcap.tgetstr(ADR(id), ADR(a));
79 PROCEDURE Tputs(cp: STRCAP; affcnt: INTEGER; p: PUTPROC);
81 XXTermcap.tputs(cp, affcnt, XXTermcap.PUTPROC(p));
84 PROCEDURE InitTermcap;
87 IF GetEnv("TERM", Bf) = 0 THEN
90 IF Tgetent(Bf) <= 0 THEN
97 \0CSP.mod
\0mod
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0$
\e(*$R-*)
98 IMPLEMENTATION MODULE CSP;
100 Module: Communicating Sequential Processes
101 From: "A Modula-2 Implementation of CSP",
102 M. Collado, R. Morales, J.J. Moreno,
103 SIGPlan Notices, Volume 22, Number 6, June 1987.
104 Some modifications by Ceriel J.H. Jacobs
105 Version: $Id: CSP.mod,v 1.10 1994/06/24 12:48:25 ceriel Exp $
107 See this article for an explanation of the use of this module.
110 FROM random IMPORT Uniform;
111 FROM SYSTEM IMPORT BYTE, ADDRESS, NEWPROCESS, TRANSFER;
112 FROM Storage IMPORT Allocate, Deallocate;
113 FROM Traps IMPORT Message;
115 CONST WorkSpaceSize = 2000;
117 TYPE ByteAddress = POINTER TO BYTE;
118 Channel = POINTER TO ChannelDescriptor;
119 ProcessType = POINTER TO ProcessDescriptor;
120 ProcessDescriptor = RECORD
127 guardcount: CARDINAL;
135 head, tail: ProcessType;
138 ChannelDescriptor = RECORD
148 (* ------------ Private modules and procedures ------------- *)
152 IMPORT ProcessType, Queue;
153 EXPORT Push, Pop, InitQueue, IsEmpty;
155 PROCEDURE InitQueue(VAR q: Queue);
163 PROCEDURE Push(p: ProcessType; VAR q: Queue);
176 PROCEDURE Pop(VAR q: Queue; VAR p: ProcessType);
189 PROCEDURE IsEmpty(q: Queue): BOOLEAN;
197 PROCEDURE DoTransfer;
198 VAR aux: ProcessType;
205 TRANSFER(aux^.cor, cp^.cor)
209 PROCEDURE OpenChannel(ch: Channel; n: INTEGER);
212 IF guardindex = 0 THEN
220 PROCEDURE CloseChannels(p: ProcessType);
223 WHILE opened # NIL DO
224 opened^.guardindex := 0;
225 opened := opened^.next
230 PROCEDURE ThereAreOpenChannels(): BOOLEAN;
232 RETURN cp^.opened # NIL;
233 END ThereAreOpenChannels;
235 PROCEDURE Sending(ch: Channel): BOOLEAN;
237 RETURN NOT IsEmpty(ch^.senders)
240 (* -------------- Public Procedures ----------------- *)
243 (* Beginning of a COBEGIN .. COEND structure *)
248 (* End of a COBEGIN .. COEND structure *)
249 (* VAR aux: ProcessType; *)
256 PROCEDURE StartProcess(P: PROC);
257 (* Start an anonimous process that executes the procedure P *)
258 VAR newprocess: ProcessType;
260 Pop(free, newprocess);
261 IF newprocess = NIL THEN
262 Allocate(newprocess,SIZE(ProcessDescriptor));
263 Allocate(newprocess^.wsp, WorkSpaceSize)
269 NEWPROCESS(P, wsp, WorkSpaceSize, cor)
271 cp^.sons := cp^.sons + 1;
272 Push(newprocess, ready)
275 PROCEDURE StopProcess;
276 (* Terminate a Process (itself) *)
277 VAR aux: ProcessType;
280 aux^.sons := aux^.sons - 1;
281 IF aux^.sons = 0 THEN
290 TRANSFER(aux^.cor, cp^.cor)
294 PROCEDURE InitChannel(VAR ch: Channel);
295 (* Initialize the channel ch *)
297 Allocate(ch, SIZE(ChannelDescriptor));
306 PROCEDURE GetChannel(ch: Channel);
307 (* Assign the channel ch to the process that gets it *)
311 Message("Channel already has an owner");
318 PROCEDURE Send(data: ARRAY OF BYTE; VAR ch: Channel);
319 (* Send a message with the data to the cvhannel ch *)
321 (* aux: ProcessType; *)
326 Allocate(cp^.msgadr, SIZE(data));
328 cp^.msglen := HIGH(data);
329 FOR i := 0 TO HIGH(data) DO
333 IF guardindex # 0 THEN
334 owner^.guardindex := guardindex;
335 CloseChannels(owner);
342 PROCEDURE Receive(VAR ch: Channel; VAR dest: ARRAY OF BYTE);
343 (* Receive a message from the channel ch into the dest variable *)
344 VAR aux: ProcessType;
350 Message("Only owner of channel can receive from it");
356 FOR i := 0 TO aux^.msglen DO
368 FOR i := 0 TO aux^.msglen DO
375 Deallocate(aux^.msgadr, aux^.msglen+1);
380 PROCEDURE SELECT(n: CARDINAL);
381 (* Beginning of a SELECT structure with n guards *)
383 cp^.guardindex := Uniform(1,n);
388 PROCEDURE NEXTGUARD(): CARDINAL;
389 (* Returns an index to the next guard to be evaluated in a SELECT *)
391 RETURN cp^.guardindex
394 PROCEDURE GUARD(cond: BOOLEAN; ch: Channel;
395 VAR dest: ARRAY OF BYTE): BOOLEAN;
396 (* Evaluates a guard, including reception management *)
397 (* VAR aux: ProcessType; *)
405 ELSIF Sending(ch) THEN
410 OpenChannel(ch, cp^.guardindex);
415 PROCEDURE ENDSELECT(): BOOLEAN;
416 (* End of a SELECT structure *)
419 IF guardindex <= 0 THEN
422 guardcount := guardcount - 1;
423 IF guardcount # 0 THEN
424 guardindex := (guardindex MOD INTEGER(guardno)) + 1
425 ELSIF ThereAreOpenChannels() THEN
437 Allocate(cp,SIZE(ProcessDescriptor));
444 PascalIO.mod
\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\13$(*
445 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
446 See the copyright notice in the ACK home directory, in the file "Copyright".
450 IMPLEMENTATION MODULE PascalIO;
452 Module: Pascal-like Input/Output
453 Author: Ceriel J.H. Jacobs
454 Version: $Id: PascalIO.mod,v 1.18 1994/06/24 12:49:12 ceriel Exp $
457 FROM Conversions IMPORT
458 ConvertInteger, ConvertCardinal;
459 FROM RealConversions IMPORT
460 LongRealToString, StringToLongReal;
461 FROM Traps IMPORT Message;
462 FROM Streams IMPORT Stream, StreamKind, StreamMode, StreamResult,
463 InputStream, OutputStream, OpenStream, CloseStream,
464 EndOfStream, Read, Write, StreamBuffering;
465 FROM Storage IMPORT Allocate;
466 FROM SYSTEM IMPORT ADR;
468 TYPE charset = SET OF CHAR;
469 btype = (Preading, Pwriting, free);
471 CONST spaces = charset{11C, 12C, 13C, 14C, 15C, ' '};
473 TYPE IOstream = RECORD
480 Text = POINTER TO IOstream;
481 numbuf = ARRAY[0..255] OF CHAR;
483 VAR ibuf, obuf: IOstream;
485 result: StreamResult;
487 PROCEDURE Reset(VAR InputText: Text; Filename: ARRAY OF CHAR);
490 getstruct(InputText);
492 OpenStream(stream, Filename, text, reading, result);
493 IF result # succeeded THEN
494 Message("could not open input file");
503 PROCEDURE Rewrite(VAR OutputText: Text; Filename: ARRAY OF CHAR);
506 getstruct(OutputText);
508 OpenStream(stream, Filename, text, writing, result);
509 IF result # succeeded THEN
510 Message("could not open output file");
517 PROCEDURE CloseOutput();
527 PROCEDURE doclose(Xtext: Text);
529 IF Xtext # Notext THEN
532 CloseStream(stream, result);
539 PROCEDURE getstruct(VAR Xtext: Text);
542 WHILE (Xtext # NIL) AND (Xtext^.type # free) DO
543 Xtext := Xtext^.next;
546 Allocate(Xtext,SIZE(IOstream));
552 PROCEDURE Error(tp: btype);
554 IF tp = Preading THEN
555 Message("input text expected");
557 Message("output text expected");
562 PROCEDURE ReadChar(InputText: Text; VAR ch : CHAR);
564 ch := NextChar(InputText);
565 IF InputText^.eof THEN
566 Message("unexpected EOF");
569 InputText^.done := FALSE;
572 PROCEDURE NextChar(InputText: Text): CHAR;
575 IF type # Preading THEN Error(Preading); END;
577 IF EndOfStream(stream, result) THEN
581 Read(stream, ch, result);
589 PROCEDURE Get(InputText: Text);
592 ReadChar(InputText, dummy);
595 PROCEDURE Eoln(InputText: Text): BOOLEAN;
597 RETURN NextChar(InputText) = 12C;
600 PROCEDURE Eof(InputText: Text): BOOLEAN;
602 RETURN (NextChar(InputText) = 0C) AND InputText^.eof;
605 PROCEDURE ReadLn(InputText: Text);
609 ReadChar(InputText, ch)
613 PROCEDURE WriteChar(OutputText: Text; char: CHAR);
616 IF type # Pwriting THEN Error(Pwriting); END;
617 Write(stream, char, result);
621 PROCEDURE WriteLn(OutputText: Text);
623 WriteChar(OutputText, 12C);
626 PROCEDURE Page(OutputText: Text);
628 WriteChar(OutputText, 14C);
631 PROCEDURE ReadInteger(InputText: Text; VAR int : INTEGER);
633 SAFELIMITDIV10 = MAX(INTEGER) DIV 10;
634 SAFELIMITREM10 = MAX(INTEGER) MOD 10;
641 WHILE NextChar(InputText) IN spaces DO
644 ch := NextChar(InputText);
647 ch := NextChar(InputText);
651 ch := NextChar(InputText);
657 safedigit := SAFELIMITREM10;
658 IF neg THEN safedigit := safedigit + 1 END;
660 IF (ch >= '0') AND (ch <= '9') THEN
661 WHILE (ch >= '0') & (ch <= '9') DO
662 chvalue := ORD(ch) - ORD('0');
663 IF (int < -SAFELIMITDIV10) OR
664 ( (int = -SAFELIMITDIV10) AND
665 (chvalue > safedigit)) THEN
666 Message("integer too large");
669 int := 10*int - VAL(INTEGER, chvalue);
671 ch := NextChar(InputText);
678 Message("integer expected");
683 PROCEDURE ReadCardinal(InputText: Text; VAR card : CARDINAL);
685 SAFELIMITDIV10 = MAX(CARDINAL) DIV 10;
686 SAFELIMITREM10 = MAX(CARDINAL) MOD 10;
693 WHILE NextChar(InputText) IN spaces DO
696 ch := NextChar(InputText);
697 safedigit := SAFELIMITREM10;
699 IF (ch >= '0') AND (ch <= '9') THEN
700 WHILE (ch >= '0') & (ch <= '9') DO
701 chvalue := ORD(ch) - ORD('0');
702 IF (card > SAFELIMITDIV10) OR
703 ( (card = SAFELIMITDIV10) AND
704 (chvalue > safedigit)) THEN
705 Message("cardinal too large");
708 card := 10*card + chvalue;
710 ch := NextChar(InputText);
714 Message("cardinal expected");
719 PROCEDURE ReadReal(InputText: Text; VAR real: REAL);
722 ReadLongReal(InputText, x1);
726 PROCEDURE ReadLongReal(InputText: Text; VAR real: LONGREAL);
733 PROCEDURE inch(): CHAR;
738 RETURN NextChar(InputText);
744 WHILE NextChar(InputText) IN spaces DO
747 ch := NextChar(InputText);
748 IF (ch ='+') OR (ch = '-') THEN
751 IF (ch >= '0') AND (ch <= '9') THEN
752 WHILE (ch >= '0') AND (ch <= '9') DO
757 IF (ch >= '0') AND (ch <= '9') THEN
758 WHILE (ch >= '0') AND (ch <= '9') DO
765 IF ok AND (ch = 'E') THEN
767 IF (ch ='+') OR (ch = '-') THEN
770 IF (ch >= '0') AND (ch <= '9') THEN
771 WHILE (ch >= '0') AND (ch <= '9') DO
783 StringToLongReal(buf, real, ok);
786 Message("Illegal real");
791 PROCEDURE WriteCardinal(OutputText: Text; card: CARDINAL; width: CARDINAL);
795 ConvertCardinal(card, 1, buf);
796 WriteString(OutputText, buf, width);
799 PROCEDURE WriteInteger(OutputText: Text; int: INTEGER; width: CARDINAL);
803 ConvertInteger(int, 1, buf);
804 WriteString(OutputText, buf, width);
807 PROCEDURE WriteBoolean(OutputText: Text; bool: BOOLEAN; width: CARDINAL);
810 WriteString(OutputText, " TRUE", width);
812 WriteString(OutputText, "FALSE", width);
816 PROCEDURE WriteReal(OutputText: Text; real: REAL; width, nfrac: CARDINAL);
818 WriteLongReal(OutputText, LONG(real), width, nfrac)
821 PROCEDURE WriteLongReal(OutputText: Text; real: LONGREAL; width, nfrac: CARDINAL);
827 IF width > SIZE(buf) THEN
831 LongRealToString(real, width, nfrac, buf, ok);
833 IF width < 9 THEN width := 9; END;
835 digits := 7 - INTEGER(width);
837 digits := 6 - INTEGER(width);
839 LongRealToString(real, width, digits, buf, ok);
841 WriteString(OutputText, buf, 0);
844 PROCEDURE WriteString(OutputText: Text; str: ARRAY OF CHAR; width: CARDINAL);
848 WHILE (index <= HIGH(str)) AND (str[index] # Eos) DO
851 WHILE index < width DO
852 WriteChar(OutputText, " ");
856 WHILE (index <= HIGH(str)) AND (str[index] # Eos) DO
857 WriteChar(OutputText, str[index]);
862 BEGIN (* PascalIO initialization *)
864 stream := InputStream;
870 stream := OutputStream;
877 Input^.next := Output;
881 \0RealInOut.mod
\0\0\0\0\0\ 2\ 2¤
\ 1\0\02
\b(*
882 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
883 See the copyright notice in the ACK home directory, in the file "Copyright".
887 IMPLEMENTATION MODULE RealInOut;
889 Module: InOut for REAL numbers
890 Author: Ceriel J.H. Jacobs
891 Version: $Id: RealInOut.mod,v 1.11 1994/06/24 12:49:31 ceriel Exp $
894 FROM InOut IMPORT ReadString, WriteString, WriteOct;
895 FROM Traps IMPORT Message;
896 FROM SYSTEM IMPORT WORD;
897 FROM RealConversions IMPORT
898 LongRealToString, StringToLongReal;
901 MAXWIDTH = MAXNDIG+7;
902 TYPE RBUF = ARRAY [0..MAXWIDTH+1] OF CHAR;
904 PROCEDURE WriteReal(arg: REAL; ndigits: CARDINAL);
906 WriteLongReal(LONG(arg), ndigits)
909 PROCEDURE WriteLongReal(arg: LONGREAL; ndigits: CARDINAL);
914 IF ndigits > MAXWIDTH THEN ndigits := MAXWIDTH; END;
915 IF ndigits < 10 THEN ndigits := 10; END;
916 LongRealToString(arg, ndigits, -INTEGER(ndigits - 7), buf, ok);
920 PROCEDURE WriteFixPt(arg: REAL; n, k: CARDINAL);
922 WriteLongFixPt(LONG(arg), n, k)
925 PROCEDURE WriteLongFixPt(arg: LONGREAL; n, k: CARDINAL);
930 IF n > MAXWIDTH THEN n := MAXWIDTH END;
931 LongRealToString(arg, n, k, buf, ok);
935 PROCEDURE ReadReal(VAR x: REAL);
942 PROCEDURE ReadLongReal(VAR x: LONGREAL);
943 VAR Buf: ARRAY[0..512] OF CHAR;
948 StringToLongReal(Buf, x, ok);
950 Message("real expected");
956 PROCEDURE wroct(x: ARRAY OF WORD);
959 FOR i := 0 TO HIGH(x) DO
960 WriteOct(CARDINAL(x[i]), 0);
965 PROCEDURE WriteRealOct(x: REAL);
970 PROCEDURE WriteLongRealOct(x: LONGREAL);
973 END WriteLongRealOct;
978 InOut.mod
\0mod
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0´
\1d(*
979 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
980 See the copyright notice in the ACK home directory, in the file "Copyright".
984 IMPLEMENTATION MODULE InOut ;
986 Module: Wirth's Input/Output module
987 Author: Ceriel J.H. Jacobs
988 Version: $Id: InOut.mod,v 1.19 1994/06/24 12:48:49 ceriel Exp $
992 FROM Conversions IMPORT
993 ConvertCardinal, ConvertInteger,
994 ConvertOctal, ConvertHex;
995 FROM Traps IMPORT Message;
999 TYPE numbuf = ARRAY[0..255] OF CHAR;
1001 VAR unread: BOOLEAN;
1003 CurrIn, CurrOut: Streams.Stream;
1004 result: Streams.StreamResult;
1006 PROCEDURE Read(VAR c : CHAR);
1014 Streams.Read(CurrIn, c, result);
1015 Done := result = Streams.succeeded;
1019 PROCEDURE UnRead(ch: CHAR);
1025 PROCEDURE Write(c: CHAR);
1027 Streams.Write(CurrOut, c, result);
1030 PROCEDURE OpenInput(defext: ARRAY OF CHAR);
1031 VAR namebuf : ARRAY [1..128] OF CHAR;
1033 IF CurrIn # Streams.InputStream THEN
1034 Streams.CloseStream(CurrIn, result);
1036 MakeFileName("Name of input file: ", defext, namebuf);
1037 IF NOT Done THEN RETURN; END;
1041 PROCEDURE OpenInputFile(filename: ARRAY OF CHAR);
1043 IF CurrIn # Streams.InputStream THEN
1044 Streams.CloseStream(CurrIn, result);
1046 openinput(filename);
1049 PROCEDURE openinput(namebuf: ARRAY OF CHAR);
1051 IF (namebuf[0] = '-') AND (namebuf[1] = 0C) THEN
1052 CurrIn := Streams.InputStream;
1055 Streams.OpenStream(CurrIn, namebuf, Streams.text,
1056 Streams.reading, result);
1057 Done := result = Streams.succeeded;
1061 PROCEDURE CloseInput;
1063 IF CurrIn # Streams.InputStream THEN
1064 Streams.CloseStream(CurrIn, result);
1066 CurrIn := Streams.InputStream;
1069 PROCEDURE OpenOutput(defext: ARRAY OF CHAR);
1070 VAR namebuf : ARRAY [1..128] OF CHAR;
1072 IF CurrOut # Streams.OutputStream THEN
1073 Streams.CloseStream(CurrOut, result);
1075 MakeFileName("Name of output file: ", defext, namebuf);
1076 IF NOT Done THEN RETURN; END;
1077 openoutput(namebuf);
1080 PROCEDURE OpenOutputFile(filename: ARRAY OF CHAR);
1082 IF CurrOut # Streams.OutputStream THEN
1083 Streams.CloseStream(CurrOut, result);
1085 openoutput(filename);
1088 PROCEDURE openoutput(namebuf: ARRAY OF CHAR);
1090 IF (namebuf[1] = '-') AND (namebuf[2] = 0C) THEN
1091 CurrOut := Streams.OutputStream;
1094 Streams.OpenStream(CurrOut, namebuf, Streams.text,
1095 Streams.writing, result);
1096 Done := result = Streams.succeeded;
1100 PROCEDURE CloseOutput;
1102 IF CurrOut # Streams.OutputStream THEN
1103 Streams.CloseStream(CurrOut, result);
1105 CurrOut := Streams.OutputStream;
1108 PROCEDURE MakeFileName(prompt, defext : ARRAY OF CHAR;
1109 VAR buf : ARRAY OF CHAR);
1114 IF Streams.isatty(Streams.InputStream, result) THEN
1115 XWriteString(prompt);
1119 WHILE buf[i] # 0C DO i := i + 1 END;
1122 IF buf[i] = '.' THEN
1123 FOR j := 0 TO HIGH(defext) DO
1125 buf[i] := defext[j];
1134 PROCEDURE ReadInt(VAR integ : INTEGER);
1136 SAFELIMITDIV10 = MAX(INTEGER) DIV 10;
1137 SAFELIMITREM10 = MAX(INTEGER) MOD 10;
1140 ibuf = ARRAY itype OF CHAR;
1144 safedigit: [0 .. 9];
1154 IF buf[index] = '-' THEN
1157 ELSIF buf[index] = '+' THEN
1164 safedigit := SAFELIMITREM10;
1165 IF neg THEN safedigit := safedigit + 1 END;
1167 WHILE (buf[index] >= '0') & (buf[index] <= '9') DO
1168 chvalue := ORD(buf[index]) - ORD('0');
1169 IF (int > SAFELIMITDIV10) OR
1170 ( (int = SAFELIMITDIV10) AND
1171 (chvalue > safedigit)) THEN
1172 Message("integer too large");
1175 int := 10*int + VAL(INTEGER, chvalue);
1184 IF buf[index] > " " THEN
1185 Message("illegal integer");
1191 PROCEDURE ReadCard(VAR card : CARDINAL);
1193 SAFELIMITDIV10 = MAX(CARDINAL) DIV 10;
1194 SAFELIMITREM10 = MAX(CARDINAL) MOD 10;
1198 ibuf = ARRAY itype OF CHAR;
1204 safedigit: [0 .. 9];
1208 IF NOT Done THEN RETURN; END;
1210 safedigit := SAFELIMITREM10;
1212 WHILE (buf[index] >= '0') & (buf[index] <= '9') DO
1213 chvalue := ORD(buf[index]) - ORD('0');
1214 IF (int > SAFELIMITDIV10) OR
1215 ( (int = SAFELIMITDIV10) AND
1216 (chvalue > safedigit)) THEN
1217 Message("cardinal too large");
1220 int := 10*int + chvalue;
1224 IF buf[index] > " " THEN
1225 Message("illegal cardinal");
1232 PROCEDURE ReadString(VAR s : ARRAY OF CHAR);
1233 TYPE charset = SET OF CHAR;
1241 UNTIL NOT (ch IN charset{' ', TAB, 12C, 15C});
1249 IF i <= HIGH(s) THEN
1251 IF (NOT Done) OR (ch <= " ") THEN
1256 UNTIL (NOT Done) OR (ch <= " ");
1257 IF Done THEN UnRead(ch); END;
1260 PROCEDURE XReadString(VAR s : ARRAY OF CHAR);
1267 Streams.Read(Streams.InputStream, ch, result);
1268 IF result # Streams.succeeded THEN
1282 PROCEDURE XWriteString(s: ARRAY OF CHAR);
1287 IF (i <= HIGH(s)) AND (s[i] # 0C) THEN
1288 Streams.Write(Streams.OutputStream, s[i], result);
1296 PROCEDURE WriteCard(card, width : CARDINAL);
1300 ConvertCardinal(card, width, buf);
1304 PROCEDURE WriteInt(int : INTEGER; width : CARDINAL);
1308 ConvertInteger(int, width, buf);
1312 PROCEDURE WriteHex(card, width : CARDINAL);
1316 ConvertHex(card, width, buf);
1325 PROCEDURE WriteOct(card, width : CARDINAL);
1329 ConvertOctal(card, width, buf);
1333 PROCEDURE WriteString(str : ARRAY OF CHAR);
1338 WHILE (nbytes <= HIGH(str)) AND (str[nbytes] # 0C) DO
1344 BEGIN (* InOut initialization *)
1345 CurrIn := Streams.InputStream;
1346 CurrOut := Streams.OutputStream;
1349 Streams.mod
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\05&#
1351 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
1352 See the copyright notice in the ACK home directory, in the file "Copyright".
1356 IMPLEMENTATION MODULE Streams;
1358 Module: Stream Input/Output
1359 Author: Ceriel J.H. Jacobs
1360 Version: $Id: Streams.mod,v 1.12 1994/06/24 12:49:57 ceriel Exp $
1362 Implementation for Unix
1365 FROM SYSTEM IMPORT BYTE, ADR;
1366 FROM Epilogue IMPORT CallAtEnd;
1367 FROM Storage IMPORT Allocate, Available;
1368 FROM StripUnix IMPORT
1369 open, close, lseek, read, write, creat, ioctl;
1371 CONST BUFSIZ = 1024; (* tunable *)
1376 buffering: StreamBuffering;
1379 cnt, maxcnt: INTEGER;
1380 bufferedcnt: INTEGER;
1381 buf: ARRAY[1..BUFSIZ] OF BYTE;
1383 Stream = POINTER TO IOB;
1385 ibuf, obuf, ebuf: IOB;
1388 PROCEDURE getstruct(VAR stream: Stream);
1391 WHILE (stream # NIL) AND (stream^.kind # none) DO
1392 stream := stream^.next;
1394 IF stream = NIL THEN
1395 IF NOT Available(SIZE(IOB)) THEN
1398 Allocate(stream,SIZE(IOB));
1399 stream^.next := head;
1404 PROCEDURE freestruct(stream: Stream);
1406 stream^.kind := none;
1409 PROCEDURE OpenStream(VAR stream: Stream;
1410 filename: ARRAY OF CHAR;
1413 VAR result: StreamResult);
1418 result := illegaloperation;
1422 IF stream = NIL THEN
1427 FOR i := 0 TO HIGH(filename) DO
1428 buf[i+1] := BYTE(filename[i]);
1430 buf[HIGH(filename)+2] := BYTE(0C);
1432 IF (mode = reading) THEN
1433 fd := open(ADR(stream^.buf), 0);
1436 IF (mode = appending) THEN
1437 fd := open(ADR(stream^.buf), 1);
1439 IF (lseek(fd, 0D , 2) < 0D) THEN ; END;
1443 fd := creat(ADR(stream^.buf), 666B);
1447 result := openfailed;
1452 result := succeeded;
1453 stream^.fildes := fd;
1454 stream^.kind := kind;
1455 stream^.mode := mode;
1456 stream^.buffering := blockbuffered;
1457 stream^.bufferedcnt := BUFSIZ;
1458 stream^.maxcnt := 0;
1459 stream^.eof := FALSE;
1460 IF mode = reading THEN
1467 PROCEDURE SetStreamBuffering( stream: Stream;
1469 VAR result: StreamResult);
1471 result := succeeded;
1472 IF (stream = NIL) OR (stream^.kind = none) THEN
1476 IF (stream^.mode = reading) OR
1477 ((b = linebuffered) AND (stream^.kind = binary)) THEN
1478 result := illegaloperation;
1481 FlushStream(stream, result);
1482 IF b = unbuffered THEN
1483 stream^.bufferedcnt := 1;
1485 stream^.buffering := b;
1486 END SetStreamBuffering;
1488 PROCEDURE FlushStream(stream: Stream; VAR result: StreamResult);
1491 result := succeeded;
1492 IF (stream = NIL) OR (stream^.kind = none) THEN
1497 IF mode = reading THEN
1498 result := illegaloperation;
1504 IF write(fildes, ADR(buf), cnt1) < 0 THEN END;
1509 PROCEDURE CloseStream(VAR stream: Stream; VAR result: StreamResult);
1511 IF (stream # NIL) AND (stream^.kind # none) THEN
1512 result := succeeded;
1513 IF stream^.mode # reading THEN
1514 FlushStream(stream, result);
1516 IF close(stream^.fildes) < 0 THEN ; END;
1524 PROCEDURE EndOfStream(stream: Stream; VAR result: StreamResult): BOOLEAN;
1526 result := succeeded;
1527 IF (stream = NIL) OR (stream^.kind = none) THEN
1531 IF stream^.mode # reading THEN
1532 result := illegaloperation;
1535 IF stream^.eof THEN RETURN TRUE; END;
1536 RETURN (CHAR(NextByte(stream)) = 0C) AND stream^.eof;
1539 PROCEDURE FlushLineBuffers();
1541 result: StreamResult;
1545 IF (s^.kind # none) AND (s^.buffering = linebuffered) THEN
1546 FlushStream(s, result);
1550 END FlushLineBuffers;
1552 PROCEDURE NextByte(stream: Stream): BYTE;
1556 IF cnt <= maxcnt THEN
1559 IF eof THEN RETURN BYTE(0C); END;
1560 IF stream = InputStream THEN
1563 maxcnt := read(fildes, ADR(buf), bufferedcnt);
1576 PROCEDURE Read(stream: Stream; VAR ch: CHAR; VAR result: StreamResult);
1580 EoF := EndOfStream(stream, result);
1581 IF result # succeeded THEN RETURN; END;
1583 result := endoffile;
1587 ch := CHAR(buf[cnt]);
1592 PROCEDURE ReadByte(stream: Stream; VAR byte: BYTE; VAR result: StreamResult);
1596 EoF := EndOfStream(stream, result);
1597 IF result # succeeded THEN RETURN; END;
1599 result := endoffile;
1608 PROCEDURE ReadBytes(stream: Stream;
1609 VAR bytes: ARRAY OF BYTE;
1610 VAR result: StreamResult);
1613 FOR i := 0 TO HIGH(bytes) DO
1614 ReadByte(stream, bytes[i], result);
1618 PROCEDURE Write(stream: Stream; ch: CHAR; VAR result: StreamResult);
1620 IF (stream = NIL) OR (stream^.kind = none) THEN
1624 IF (stream^.kind # text) OR (stream^.mode = reading) THEN
1625 result := illegaloperation;
1630 buf[cnt] := BYTE(ch);
1631 IF (cnt >= bufferedcnt) OR
1632 ((ch = 12C) AND (buffering = linebuffered))
1634 FlushStream(stream, result);
1639 PROCEDURE WriteByte(stream: Stream; byte: BYTE; VAR result: StreamResult);
1641 IF (stream = NIL) OR (stream^.kind = none) THEN
1645 IF (stream^.kind # binary) OR (stream^.mode = reading) THEN
1646 result := illegaloperation;
1652 IF cnt >= bufferedcnt THEN
1653 FlushStream(stream, result);
1658 PROCEDURE WriteBytes(stream: Stream; bytes: ARRAY OF BYTE; VAR result: StreamResult);
1661 FOR i := 0 TO HIGH(bytes) DO
1662 WriteByte(stream, bytes[i], result);
1668 result: StreamResult;
1673 CloseStream(h1, result);
1678 PROCEDURE GetPosition(s: Stream; VAR position: LONGINT;
1679 VAR result: StreamResult);
1681 IF (s = NIL) OR (s^.kind = none) THEN
1682 result := illegaloperation;
1685 IF (s^.mode # reading) THEN FlushStream(s, result); END;
1686 position := lseek(s^.fildes, 0D, 1);
1687 IF position < 0D THEN
1688 result := illegaloperation;
1691 IF s^.mode = reading THEN
1692 position := position + LONG(s^.maxcnt - s^.cnt + 1);
1696 PROCEDURE SetPosition(s: Stream; position: LONGINT; VAR result: StreamResult);
1697 VAR currpos: LONGINT;
1700 IF (s = NIL) OR (s^.kind = none) THEN
1704 IF (s^.mode # reading) THEN
1705 FlushStream(s, result);
1710 IF s^.mode = appending THEN
1711 currpos := lseek(s^.fildes, 0D, 1);
1712 IF currpos < 0D THEN
1713 result := illegaloperation;
1717 IF position < currpos THEN
1718 result := illegaloperation;
1721 currpos := lseek(s^.fildes, position, 0);
1722 IF currpos < 0D THEN
1723 result := illegaloperation;
1726 result := succeeded;
1729 PROCEDURE isatty(stream: Stream; VAR result: StreamResult): BOOLEAN;
1730 VAR buf: ARRAY[1..100] OF CHAR;
1732 IF (stream = NIL) OR (stream^.kind = none) THEN
1737 RETURN ioctl(stream^.fildes, INTEGER(ORD('T') * 256 + 1), ADR(buf)) >= 0;
1740 RETURN ioctl(stream^.fildes, INTEGER(ORD('t') * 256 + 8 + 6*65536 + 40000000H), ADR(buf)) >= 0;
1742 RETURN ioctl(stream^.fildes, INTEGER(ORD('t') * 256 + 8), ADR(buf)) >= 0;
1747 PROCEDURE InitStreams;
1748 VAR result: StreamResult;
1750 InputStream := ADR(ibuf);
1751 OutputStream := ADR(obuf);
1752 ErrorStream := ADR(ebuf);
1761 bufferedcnt := BUFSIZ;
1771 bufferedcnt := BUFSIZ;
1772 IF isatty(OutputStream, result) THEN
1773 buffering := linebuffered;
1775 buffering := blockbuffered;
1786 bufferedcnt := BUFSIZ;
1787 IF isatty(ErrorStream, result) THEN
1788 buffering := linebuffered;
1790 buffering := blockbuffered;
1793 head := InputStream;
1794 IF CallAtEnd(EndIt) THEN ; END;
1800 \0Terminal.mod
\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ý
\a#
1802 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
1803 See the copyright notice in the ACK home directory, in the file "Copyright".
1807 IMPLEMENTATION MODULE Terminal;
1809 Module: Input/Output to/from terminals
1810 Author: Ceriel J.H. Jacobs
1811 Version: $Id: Terminal.mod,v 1.5 1994/06/24 12:50:19 ceriel Exp $
1813 Implementation for Unix.
1815 FROM SYSTEM IMPORT ADR;
1817 FROM Unix IMPORT read, write, open, fcntl;
1819 FROM Unix IMPORT read, write, open, ioctl;
1821 VAR fildes: INTEGER;
1824 tty: ARRAY[0..8] OF CHAR;
1826 PROCEDURE Read(VAR ch: CHAR);
1832 IF read(fildes, ADR(ch), 1) < 0 THEN
1839 PROCEDURE BusyRead(VAR ch: CHAR);
1847 l := fcntl(fildes, (*FGETFL*) 3, 0);
1850 l + (*ONDELAY*) 2) < 0 THEN
1853 IF read(fildes, ADR(ch), 1) = 0 THEN
1858 IF fcntl(fildes, (*FSETFL*)4, l) < 0 THEN
1863 IF ioctl(fildes, INTEGER(ORD('f')*256+127+4*65536+40000000H), ADR(l)) < 0 THEN
1865 IF ioctl(fildes, INTEGER(ORD('f')*256+127), ADR(l)) < 0 THEN
1873 IF read(fildes, ADR(ch), 1) < 0 THEN
1882 PROCEDURE ReadAgain;
1887 PROCEDURE Write(ch: CHAR);
1889 IF write(fildes, ADR(ch), 1) < 0 THEN
1899 PROCEDURE WriteString(s: ARRAY OF CHAR);
1903 WHILE (i <= HIGH(s)) & (s[i] # 0C) DO
1911 fildes := open(ADR(tty), 2);
1914 fMathLib0.mod
\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0®
\ 4(*
1915 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
1916 See the copyright notice in the ACK home directory, in the file "Copyright".
1920 IMPLEMENTATION MODULE MathLib0;
1922 Module: Some mathematical functions
1923 Author: Ceriel J.H. Jacobs
1924 Version: $Id: MathLib0.mod,v 1.10 1994/06/24 12:48:58 ceriel Exp $
1929 PROCEDURE cos(arg: REAL): REAL;
1931 RETURN Mathlib.cos(arg);
1934 PROCEDURE sin(arg: REAL): REAL;
1936 RETURN Mathlib.sin(arg);
1939 PROCEDURE arctan(arg: REAL): REAL;
1941 RETURN Mathlib.arctan(arg);
1944 PROCEDURE sqrt(arg: REAL): REAL;
1946 RETURN Mathlib.sqrt(arg);
1949 PROCEDURE ln(arg: REAL): REAL;
1951 RETURN Mathlib.ln(arg);
1954 PROCEDURE exp(arg: REAL): REAL;
1956 RETURN Mathlib.exp(arg);
1959 PROCEDURE entier(x: REAL): INTEGER;
1964 IF FLOAT(i) = -x THEN
1973 PROCEDURE real(x: INTEGER): REAL;
1983 Mathlib.mod
\0\0\0\0\0\0\0\ 2\ 2¤
\ 1\0\0C1(*
1984 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
1985 See the copyright notice in the ACK home directory, in the file "Copyright".
1989 IMPLEMENTATION MODULE Mathlib;
1991 Module: Mathematical functions
1992 Author: Ceriel J.H. Jacobs
1993 Version: $Id: Mathlib.mod,v 1.10 1994/06/24 12:49:05 ceriel Exp $
1996 FROM EM IMPORT FIF, FEF;
1997 FROM Traps IMPORT Message;
2000 OneRadianInDegrees = 57.295779513082320876798155D;
2001 OneDegreeInRadians = 0.017453292519943295769237D;
2002 OneOverSqrt2 = 0.70710678118654752440084436210484904D;
2004 (* basic functions *)
2006 PROCEDURE pow(x: REAL; i: INTEGER): REAL;
2008 RETURN SHORT(longpow(LONG(x), i));
2011 PROCEDURE longpow(x: LONGREAL; i: INTEGER): LONGREAL;
2017 val := longexp(longln(-x) * ri);
2018 IF ODD(i) THEN RETURN -val;
2024 RETURN longexp(longln(x) * ri);
2028 PROCEDURE sqrt(x: REAL): REAL;
2030 RETURN SHORT(longsqrt(LONG(x)));
2033 PROCEDURE longsqrt(x: LONGREAL): LONGREAL;
2040 Message("sqrt: negative argument");
2048 * this wont work on 1's comp
2051 temp := 2.0D * temp;
2054 temp := 0.5D*(1.0D + temp);
2057 temp := temp * 16384.0D;
2061 temp := temp / 16384.0D;
2065 temp := temp * 2.0D;
2069 temp := temp / 2.0D;
2073 temp := 0.5D*(temp + x/temp);
2078 PROCEDURE ldexp(x:LONGREAL; n: INTEGER): LONGREAL;
2099 PROCEDURE exp(x: REAL): REAL;
2101 RETURN SHORT(longexp(LONG(x)));
2104 PROCEDURE longexp(x: LONGREAL): LONGREAL;
2105 (* Algorithm and coefficients from:
2106 "Software manual for the elementary functions"
2107 by W.J. Cody and W. Waite, Prentice-Hall, 1980
2110 p0 = 0.25000000000000000000D+00;
2111 p1 = 0.75753180159422776666D-02;
2112 p2 = 0.31555192765684646356D-04;
2113 q0 = 0.50000000000000000000D+00;
2114 q1 = 0.56817302698551221787D-01;
2115 q2 = 0.63121894374398503557D-03;
2116 q3 = 0.75104028399870046114D-06;
2121 xn, g, x1, x2: LONGREAL;
2127 n := TRUNC(x/longln2 + 0.5D);
2129 x1 := FLOATD(TRUNCD(x));
2131 g := ((x1 - xn * 0.693359375D)+x2) - xn * (-2.1219444005469058277D-4);
2137 x := g*((p2*xn+p1)*xn+p0);
2139 RETURN ldexp(0.5D + x/((((q3*xn+q2)*xn+q1)*xn+q0) - x), n);
2142 PROCEDURE ln(x: REAL): REAL; (* natural log *)
2144 RETURN SHORT(longln(LONG(x)));
2147 PROCEDURE longln(x: LONGREAL): LONGREAL; (* natural log *)
2148 (* Algorithm and coefficients from:
2149 "Software manual for the elementary functions"
2150 by W.J. Cody and W. Waite, Prentice-Hall, 1980
2153 p0 = -0.64124943423745581147D+02;
2154 p1 = 0.16383943563021534222D+02;
2155 p2 = -0.78956112887491257267D+00;
2156 q0 = -0.76949932108494879777D+03;
2157 q1 = 0.31203222091924532844D+03;
2158 q2 = -0.35667977739034646171D+02;
2162 z, znum, zden, w: LONGREAL;
2166 Message("ln: argument <= 0");
2170 IF x > OneOverSqrt2 THEN
2171 znum := (x - 0.5D) - 0.5D;
2172 zden := x * 0.5D + 0.5D;
2175 zden := znum * 0.5D + 0.5D;
2180 x := z + z * w * (((p2*w+p1)*w+p0)/(((q3*w+q2)*w+q1)*w+q0));
2182 x := x + z * (-2.121944400546905827679D-4);
2183 RETURN x + z * 0.693359375D;
2186 PROCEDURE log(x: REAL): REAL; (* log with base 10 *)
2188 RETURN SHORT(longlog(LONG(x)));
2191 PROCEDURE longlog(x: LONGREAL): LONGREAL; (* log with base 10 *)
2193 RETURN longln(x)/longln10;
2196 (* trigonometric functions; arguments in radians *)
2198 PROCEDURE sin(x: REAL): REAL;
2200 RETURN SHORT(longsin(LONG(x)));
2203 PROCEDURE sinus(x: LONGREAL; cosflag: BOOLEAN) : LONGREAL;
2204 (* Algorithm and coefficients from:
2205 "Software manual for the elementary functions"
2206 by W.J. Cody and W. Waite, Prentice-Hall, 1980
2209 r0 = -0.16666666666666665052D+00;
2210 r1 = 0.83333333333331650314D-02;
2211 r2 = -0.19841269841201840457D-03;
2212 r3 = 0.27557319210152756119D-05;
2213 r4 = -0.25052106798274584544D-07;
2214 r5 = 0.16058936490371589114D-09;
2215 r6 = -0.76429178068910467734D-12;
2216 r7 = 0.27204790957888846175D-14;
2218 A2 = -8.908910206761537356617D-6;
2220 x1, x2, y : LONGREAL;
2234 y := y / longpi + 0.5D;
2236 IF FIF(y, 1.0D, y) < 0.0D THEN ; END;
2237 IF FIF(y, 0.5D, x1) # 0.0D THEN neg := NOT neg END;
2238 IF cosflag THEN y := y - 0.5D END;
2239 x2 := FIF(x, 1.0, x1);
2249 x := x + x * y * (((((((r7*y+r6)*y+r5)*y+r4)*y+r3)*y+r2)*y+r1)*y+r0);
2250 IF neg THEN RETURN -x END;
2254 PROCEDURE longsin(x: LONGREAL): LONGREAL;
2256 RETURN sinus(x, FALSE);
2259 PROCEDURE cos(x: REAL): REAL;
2261 RETURN SHORT(longcos(LONG(x)));
2264 PROCEDURE longcos(x: LONGREAL): LONGREAL;
2266 IF x < 0.0D THEN x := -x; END;
2267 RETURN sinus(x, TRUE);
2270 PROCEDURE tan(x: REAL): REAL;
2272 RETURN SHORT(longtan(LONG(x)));
2275 PROCEDURE longtan(x: LONGREAL): LONGREAL;
2276 (* Algorithm and coefficients from:
2277 "Software manual for the elementary functions"
2278 by W.J. Cody and W. Waite, Prentice-Hall, 1980
2282 p1 = -0.13338350006421960681D+00;
2283 p2 = 0.34248878235890589960D-02;
2284 p3 = -0.17861707342254426711D-04;
2287 q1 = -0.46671683339755294240D+00;
2288 q2 = 0.25663832289440112864D-01;
2289 q3 = -0.31181531907010027307D-03;
2290 q4 = 0.49819433993786512270D-06;
2292 A1 = 1.57080078125D;
2293 A2 = -4.454455103380768678308D-06;
2295 VAR y, x1, x2: LONGREAL;
2299 negative := x < 0.0D;
2300 y := x / longhalfpi + 0.5D;
2302 (* Use extended precision to calculate reduced argument.
2303 Here we used 12 bits of the mantissa for a1.
2304 Also split x in integer part x1 and fraction part x2.
2306 IF FIF(y, 1.0D, y) < 0.0D THEN ; END;
2307 invert := FIF(y, 0.5D, x1) # 0.0D;
2308 x2 := FIF(x, 1.0D, x1);
2314 x := x + x * y * ((p3*y+p2)*y+p1);
2315 y := (((q4*y+q3)*y+q2)*y+q1)*y+q0;
2316 IF negative THEN x := -x END;
2317 IF invert THEN RETURN -y/x END;
2321 PROCEDURE arcsin(x: REAL): REAL;
2323 RETURN SHORT(longarcsin(LONG(x)));
2326 PROCEDURE arcsincos(x: LONGREAL; cosfl: BOOLEAN): LONGREAL;
2328 p0 = -0.27368494524164255994D+02;
2329 p1 = 0.57208227877891731407D+02;
2330 p2 = -0.39688862997540877339D+02;
2331 p3 = 0.10152522233806463645D+02;
2332 p4 = -0.69674573447350646411D+00;
2334 q0 = -0.16421096714498560795D+03;
2335 q1 = 0.41714430248260412556D+03;
2336 q2 = -0.38186303361750149284D+03;
2337 q3 = 0.15095270841030604719D+03;
2338 q4 = -0.23823859153670238830D+02;
2345 negative := x < 0.0D;
2346 IF negative THEN x := -x; END;
2350 Message("arcsin or arccos: argument > 1");
2353 g := 0.5D - 0.5D * x;
2361 ((((p4*g+p3)*g+p2)*g+p1)*g+p0)/(((((q5*g+q4)*g+q3)*g+q2)*g+q1)*g+q0);
2362 IF cosfl AND NOT negative THEN x := -x END;
2363 IF cosfl = NOT big THEN
2364 x := (x + longquartpi) + longquartpi;
2365 ELSIF cosfl AND negative AND big THEN
2366 x := (x + longhalfpi) + longhalfpi;
2368 IF negative AND NOT cosfl THEN x := -x END;
2372 PROCEDURE longarcsin(x: LONGREAL): LONGREAL;
2374 RETURN arcsincos(x, FALSE);
2377 PROCEDURE arccos(x: REAL): REAL;
2379 RETURN SHORT(longarccos(LONG(x)));
2382 PROCEDURE longarccos(x: LONGREAL): LONGREAL;
2384 RETURN arcsincos(x, TRUE);
2387 PROCEDURE arctan(x: REAL): REAL;
2389 RETURN SHORT(longarctan(LONG(x)));
2392 VAR A: ARRAY[0..3] OF LONGREAL;
2393 arctaninit: BOOLEAN;
2395 PROCEDURE longarctan(x: LONGREAL): LONGREAL;
2396 (* Algorithm and coefficients from:
2397 "Software manual for the elementary functions"
2398 by W.J. Cody and W. Waite, Prentice-Hall, 1980
2401 p0 = -0.13688768894191926929D+02;
2402 p1 = -0.20505855195861651981D+02;
2403 p2 = -0.84946240351320683534D+01;
2404 p3 = -0.83758299368150059274D+00;
2405 q0 = 0.41066306682575781263D+02;
2406 q1 = 0.86157349597130242515D+02;
2407 q2 = 0.59578436142597344465D+02;
2408 q3 = 0.15024001160028576121D+02;
2415 IF NOT arctaninit THEN
2418 A[1] := 0.52359877559829887307710723554658381D; (* p1/6 *)
2420 A[3] := 1.04719755119659774615421446109316763D; (* pi/3 *)
2433 IF x > 0.26794919243112270647D (* 2-sqrt(3) *) THEN
2435 x := (((0.73205080756887729353D*x-0.5D)-0.5D)+x)/
2436 (1.73205080756887729353D + x);
2439 x := x + x * g * (((p3*g+p2)*g+p1)*g+p0) / ((((q4*g+q3)*g+q2)*g+q1)*g+q0);
2440 IF n > 1 THEN x := -x END;
2442 IF neg THEN RETURN -x; END;
2446 (* hyperbolic functions *)
2447 (* The C math library has better implementations for some of these, but
2448 they depend on some properties of the floating point implementation,
2449 and, for now, we don't want that in the Modula-2 system.
2452 PROCEDURE sinh(x: REAL): REAL;
2454 RETURN SHORT(longsinh(LONG(x)));
2457 PROCEDURE longsinh(x: LONGREAL): LONGREAL;
2461 RETURN (expx - 1.0D/expx)/2.0D;
2464 PROCEDURE cosh(x: REAL): REAL;
2466 RETURN SHORT(longcosh(LONG(x)));
2469 PROCEDURE longcosh(x: LONGREAL): LONGREAL;
2473 RETURN (expx + 1.0D/expx)/2.0D;
2476 PROCEDURE tanh(x: REAL): REAL;
2478 RETURN SHORT(longtanh(LONG(x)));
2481 PROCEDURE longtanh(x: LONGREAL): LONGREAL;
2485 RETURN (expx - 1.0D/expx) / (expx + 1.0D/expx);
2488 PROCEDURE arcsinh(x: REAL): REAL;
2490 RETURN SHORT(longarcsinh(LONG(x)));
2493 PROCEDURE longarcsinh(x: LONGREAL): LONGREAL;
2501 x := longln(x + longsqrt(x*x+1.0D));
2502 IF neg THEN RETURN -x; END;
2506 PROCEDURE arccosh(x: REAL): REAL;
2508 RETURN SHORT(longarccosh(LONG(x)));
2511 PROCEDURE longarccosh(x: LONGREAL): LONGREAL;
2514 Message("arccosh: argument < 1");
2517 RETURN longln(x + longsqrt(x*x - 1.0D));
2520 PROCEDURE arctanh(x: REAL): REAL;
2522 RETURN SHORT(longarctanh(LONG(x)));
2525 PROCEDURE longarctanh(x: LONGREAL): LONGREAL;
2527 IF (x <= -1.0D) OR (x >= 1.0D) THEN
2528 Message("arctanh: ABS(argument) >= 1");
2531 RETURN longln((1.0D + x)/(1.0D - x)) / 2.0D;
2536 PROCEDURE RadianToDegree(x: REAL): REAL;
2538 RETURN SHORT(longRadianToDegree(LONG(x)));
2541 PROCEDURE longRadianToDegree(x: LONGREAL): LONGREAL;
2543 RETURN x * OneRadianInDegrees;
2544 END longRadianToDegree;
2546 PROCEDURE DegreeToRadian(x: REAL): REAL;
2548 RETURN SHORT(longDegreeToRadian(LONG(x)));
2551 PROCEDURE longDegreeToRadian(x: LONGREAL): LONGREAL;
2553 RETURN x * OneDegreeInRadians;
2554 END longDegreeToRadian;
2557 arctaninit := FALSE;
2559 dProcesses.mod
\0\0\0\0\0\ 2\ 2¤
\ 1\0\01
\a(*$R-*)
2560 IMPLEMENTATION MODULE Processes [1];
2563 From: "Programming in Modula-2", 3rd, corrected edition, by N. Wirth
2564 Version: $Id: Processes.mod,v 1.7 1994/06/24 12:49:18 ceriel Exp $
2567 FROM SYSTEM IMPORT ADDRESS, TSIZE, NEWPROCESS, TRANSFER;
2568 FROM Storage IMPORT Allocate;
2569 FROM Traps IMPORT Message;
2571 TYPE SIGNAL = POINTER TO ProcessDescriptor;
2574 RECORD next: SIGNAL; (* ring *)
2575 queue: SIGNAL; (* queue of waiting processes *)
2580 VAR cp: SIGNAL; (* current process *)
2582 PROCEDURE StartProcess(P: PROC; n: CARDINAL);
2588 Allocate(cp, TSIZE(ProcessDescriptor));
2595 NEWPROCESS(P, wsp, n, cp^.cor);
2596 TRANSFER(s0^.cor, cp^.cor);
2599 PROCEDURE SEND(VAR s: SIGNAL);
2610 TRANSFER(s0^.cor, cp^.cor);
2614 PROCEDURE WAIT(VAR s: SIGNAL);
2617 (* insert cp in queue s *)
2635 Message("deadlock");
2639 TRANSFER(s0^.cor, cp^.cor)
2642 PROCEDURE Awaited(s: SIGNAL): BOOLEAN;
2647 PROCEDURE Init(VAR s: SIGNAL);
2653 Allocate(cp, TSIZE(ProcessDescriptor));
2660 iRealConver.mod
\0\0\0\0\ 2\ 2¤
\ 1\0\0ß
\1c(*
2661 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
2662 See the copyright notice in the ACK home directory, in the file "Copyright".
2666 IMPLEMENTATION MODULE RealConversions;
2668 Module: string-to-real and real-to-string conversions
2669 Author: Ceriel J.H. Jacobs
2670 Version: $Id: RealConver.mod,v 1.17 1997/01/27 14:06:51 ceriel Exp $
2674 PROCEDURE RealToString(arg: REAL;
2675 width, digits: INTEGER;
2676 VAR str: ARRAY OF CHAR;
2679 LongRealToString(LONG(arg), width, digits, str, ok);
2689 VAR Powers10: ARRAY[1..6] OF Powers;
2691 PROCEDURE LongRealToString(arg: LONGREAL;
2692 width, digits: INTEGER;
2693 VAR str: ARRAY OF CHAR;
2695 VAR pointpos: INTEGER;
2699 ind1, ind2 : CARDINAL;
2712 IF (HIGH(str) < ndigits + 3) THEN
2713 str[0] := 0C; ok := FALSE; RETURN
2717 IF sign THEN r := -r END;
2719 IF (r <> 0.0D) AND NOT (r / 10.0D < r) THEN
2720 (* assume Nan or Infinity *)
2738 WHILE r*pval < 10.0D DO
2745 (* Now, we have r in [1.0, 10.0) *)
2751 IF NOT ecvtflag THEN
2752 IF INTEGER(ind2) + pointpos <= 0 THEN
2755 ind2 := INTEGER(ind2) + pointpos
2758 IF ind2 > HIGH(str) THEN
2763 WHILE ind1 < ind2 DO
2764 str[ind1] := CHR(TRUNC(r)+ORD('0'));
2765 r := 10.0D * (r - FLOATD(TRUNC(r)));
2771 str[ind2] := CHR(ORD(str[ind2])+5);
2772 WHILE str[ind2] > '9' DO
2776 str[ind2] := CHR(ORD(str[ind2])+1);
2780 IF NOT ecvtflag THEN
2781 IF ind1 > 0 THEN str[ind1] := '0'; END;
2786 IF (NOT ecvtflag) AND (ind1 = 0) THEN
2787 str[0] := CHR(ORD(str[0])-5);
2792 FOR i := ind1 TO 2 BY -1 DO
2798 FOR i := ind1 TO 1 BY -1 DO
2804 IF (ind1 + 4) > HIGH(str) THEN
2809 str[ind1] := 'E'; INC(ind1);
2810 IF arg # 0.0D THEN DEC(pointpos); END;
2811 IF pointpos < 0 THEN
2812 pointpos := -pointpos;
2818 str[ind1] := CHR(ORD('0') + CARDINAL(pointpos DIV 100));
2819 pointpos := pointpos MOD 100;
2821 str[ind1] := CHR(ORD('0') + CARDINAL(pointpos DIV 10));
2823 str[ind1] := CHR(ORD('0') + CARDINAL(pointpos MOD 10));
2825 IF pointpos <= 0 THEN
2826 FOR i := ind1 TO 1 BY -1 DO
2827 str[i+CARDINAL(-pointpos)] := str[i-1];
2829 FOR i := 0 TO CARDINAL(-pointpos) DO
2832 ind1 := ind1 + CARDINAL(1 - pointpos);
2835 FOR i := ind1 TO CARDINAL(pointpos+1) BY -1 DO
2839 str[pointpos] := 0C;
2840 ind1 := pointpos - 1;
2842 str[pointpos] := '.';
2843 IF INTEGER(ind1) > pointpos+INTEGER(ndigits) THEN
2844 ind1 := pointpos+INTEGER(ndigits);
2846 str[pointpos+INTEGER(ndigits)+1] := 0C;
2849 FOR i := ind1 TO 0 BY -1 DO
2856 IF (ind1+1) <= HIGH(str) THEN str[ind1+1] := 0C; END;
2857 IF ind1 >= CARDINAL(width) THEN
2864 IF (width > 0) AND (ind1 < CARDINAL(width)) THEN
2865 FOR i := ind1 TO 0 BY -1 DO
2866 str[i + CARDINAL(width) - ind1] := str[i];
2868 FOR i := 0 TO CARDINAL(width)-(ind1+1) DO
2871 ind1 := CARDINAL(width);
2872 IF (ind1+1) <= HIGH(str) THEN
2873 FOR ind1 := ind1+1 TO HIGH(str) DO
2879 END LongRealToString;
2882 PROCEDURE StringToReal(str: ARRAY OF CHAR;
2883 VAR r: REAL; VAR ok: BOOLEAN);
2886 StringToLongReal(str, x, ok);
2892 PROCEDURE StringToLongReal(str: ARRAY OF CHAR;
2893 VAR r: LONGREAL; VAR ok: BOOLEAN);
2895 TYPE SETOFCHAR = SET OF CHAR;
2896 VAR pow10 : INTEGER;
2910 WHILE (str[iB] = ' ') OR (str[iB] = CHR(9)) DO
2912 IF iB > HIGH(str) THEN
2917 IF str[iB] = '-' THEN signed := TRUE; INC(iB)
2918 ELSIF str[iB] = '+' THEN INC(iB)
2920 ch := str[iB]; INC(iB);
2921 IF NOT (ch IN SETOFCHAR{'0'..'9'}) THEN ok := FALSE; RETURN END;
2923 IF r>BIG THEN INC(pow10) ELSE r:= 10.0D*r+FLOATD(ORD(ch)-ORD('0')) END;
2924 IF iB <= HIGH(str) THEN
2925 ch := str[iB]; INC(iB);
2927 UNTIL (iB > HIGH(str)) OR NOT (ch IN SETOFCHAR{'0'..'9'});
2928 IF (ch = '.') AND (iB <= HIGH(str)) THEN
2929 ch := str[iB]; INC(iB);
2930 IF NOT (ch IN SETOFCHAR{'0'..'9'}) THEN ok := FALSE; RETURN END;
2933 r := 10.0D * r + FLOATD(ORD(ch)-ORD('0'));
2936 IF iB <= HIGH(str) THEN
2937 ch := str[iB]; INC(iB);
2939 UNTIL (iB > HIGH(str)) OR NOT (ch IN SETOFCHAR{'0'..'9'});
2942 IF iB > HIGH(str) THEN
2946 ch := str[iB]; INC(iB);
2950 IF (ch = '-') OR (ch = '+') THEN
2951 signedexp := ch = '-';
2952 IF iB > HIGH(str) THEN
2956 ch := str[iB]; INC(iB);
2959 IF NOT (ch IN SETOFCHAR{'0'..'9'}) THEN ok := FALSE; RETURN END;
2961 i := i*10 + INTEGER(ORD(ch) - ORD('0'));
2962 IF iB <= HIGH(str) THEN
2963 ch := str[iB]; INC(iB);
2965 UNTIL (iB > HIGH(str)) OR NOT (ch IN SETOFCHAR{'0'..'9'});
2966 IF signedexp THEN i := -i END;
2969 IF pow10 < 0 THEN i := -pow10; ELSE i := pow10; END;
2973 e := e * 10000000000.0D;
2985 IF signed THEN r := -r; END;
2986 IF (iB <= HIGH(str)) AND (ORD(ch) > ORD(' ')) THEN ok := FALSE; END
2987 END StringToLongReal;
2990 WITH Powers10[1] DO pval := 1.0D32; rpval := 1.0D-32; exp := 32 END;
2991 WITH Powers10[2] DO pval := 1.0D16; rpval := 1.0D-16; exp := 16 END;
2992 WITH Powers10[3] DO pval := 1.0D8; rpval := 1.0D-8; exp := 8 END;
2993 WITH Powers10[4] DO pval := 1.0D4; rpval := 1.0D-4; exp := 4 END;
2994 WITH Powers10[5] DO pval := 1.0D2; rpval := 1.0D-2; exp := 2 END;
2995 WITH Powers10[6] DO pval := 1.0D1; rpval := 1.0D-1; exp := 1 END;
2996 END RealConversions.
2997 Storage.mod
\0od
\0\0\0\0\ 2\ 2¤
\ 1\0\0v
\1d(*
2998 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
2999 See the copyright notice in the ACK home directory, in the file "Copyright".
3003 IMPLEMENTATION MODULE Storage;
3005 Module: Dynamic Storage Allocation
3006 Author: Ceriel J.H. Jacobs
3007 Adapted from a version in C by Hans Tebra
3008 Version: $Id: Storage.mod,v 1.17 1994/06/24 12:49:47 ceriel Exp $
3010 (* This storage manager maintains an array of lists of objects with the
3011 same size. Commonly used sizes have their own bucket. The larger ones
3012 are put in a single list.
3014 FROM Unix IMPORT sbrk, ILLBREAK;
3015 FROM SYSTEM IMPORT ADDRESS, ADR;
3016 FROM Traps IMPORT Message;
3031 END; (* A type with high alignment requirements *)
3032 BucketPtr = POINTER TO Bucket;
3037 BNEXT: BucketPtr; (* next free Bucket *)
3038 BSIZE: CARDINAL; | (* size of user part in UNITs *)
3039 TRUE: BXX: ALIGNTYPE
3045 UNIT = SIZE(ALIGNTYPE);
3048 FreeLists: ARRAY[0..NLISTS] OF BucketPtr; (* small blocks *)
3049 Llist: BucketPtr; (* others *)
3050 Compacted: BOOLEAN; (* avoid recursive reorganization *)
3051 FirstBlock: BucketPtr;
3054 PROCEDURE MyAllocate(size: CARDINAL) : ADDRESS;
3058 pc: POINTER TO CHAR;
3061 IF size > CARDINAL(MAX(INTEGER)-2*UNIT + 1) THEN
3064 nu := (size + (UNIT-1)) DIV UNIT;
3068 IF nu <= NLISTS THEN
3070 IF FreeLists[b] # NIL THEN
3073 FreeLists[b] := p^.BNEXT;
3075 IF p^.BSIZE * UNIT # size THEN
3076 pc := ADR(p^.BSTORE) + size;
3080 RETURN ADR(p^.BSTORE);
3083 (* Search for a block with >= 2 units more than requested.
3084 We pay for an additional header when the block is split.
3086 FOR b := b+2 TO NLISTS DO
3087 IF FreeLists[b] # NIL THEN
3089 FreeLists[b] := q^.BNEXT;
3090 p := ADDRESS(q) + (nu+1)*UNIT;
3091 (* p indicates the block that must be given
3094 p^.BSIZE := q^.BSIZE - nu - 1;
3095 p^.BNEXT := FreeLists[p^.BSIZE];
3096 FreeLists[p^.BSIZE] := p;
3099 IF q^.BSIZE * UNIT # size THEN
3100 pc := ADR(q^.BSTORE) + size;
3104 RETURN ADR(q^.BSTORE);
3112 WHILE (p # NIL) AND (p^.BSIZE < nu) DO
3118 (* p^.BSIZE >= nu *)
3119 IF p^.BSIZE <= nu + NLISTS + 1 THEN
3120 (* Remove p from this list *)
3121 IF q # NIL THEN q^.BNEXT := p^.BNEXT
3122 ELSE Llist := p^.BNEXT;
3125 IF p^.BSIZE > nu + 1 THEN
3127 tail goes to FreeLists area
3129 q := ADDRESS(p) + (nu+1)*UNIT;
3130 q^.BSIZE := p^.BSIZE -nu -1;
3131 q^.BNEXT := FreeLists[q^.BSIZE];
3132 FreeLists[q^.BSIZE] := q;
3135 IF p^.BSIZE * UNIT # size THEN
3136 pc := ADR(p^.BSTORE) + size;
3140 RETURN ADR(p^.BSTORE);
3142 (* Give part of tail of original block.
3143 Block stays in this list.
3145 q := ADDRESS(p) + (p^.BSIZE-nu)*UNIT;
3147 p^.BSIZE := p^.BSIZE - nu - 1;
3149 IF q^.BSIZE * UNIT # size THEN
3150 pc := ADR(q^.BSTORE) + size;
3154 RETURN ADR(q^.BSTORE);
3159 (* reorganization did not yield sufficient memory *)
3163 brk := sbrk(UNIT * (nu + 1));
3164 IF brk = ILLBREAK THEN
3167 brk := MyAllocate(size);
3175 IF p^.BSIZE * UNIT # size THEN
3176 pc := ADR(p^.BSTORE) + size;
3180 RETURN ADR(p^.BSTORE);
3183 PROCEDURE ALLOCATE(VAR a: ADDRESS; size: CARDINAL);
3188 PROCEDURE Allocate(VAR a: ADDRESS; size: CARDINAL);
3190 a := MyAllocate(size);
3192 Message("out of core");
3197 PROCEDURE Available(size: CARDINAL): BOOLEAN;
3200 a:= MyAllocate(size);
3202 Deallocate(a, size);
3208 PROCEDURE DEALLOCATE(VAR a: ADDRESS; size: CARDINAL);
3210 Deallocate(a, size);
3213 PROCEDURE Deallocate(VAR a: ADDRESS; size: CARDINAL);
3215 pc: POINTER TO CHAR;
3218 Message("(Warning) Deallocate: NIL pointer deallocated");
3222 IF (p^.BNEXT # BucketPtr(USED)) THEN
3223 Message("(Warning) Deallocate: area already deallocated or heap corrupted");
3228 IF BSIZE # size THEN
3229 Message("(Warning) Deallocate: wrong size or heap corrupted");
3231 BSIZE := (size + (UNIT - 1)) DIV UNIT;
3232 IF (BSIZE*UNIT # size) THEN
3234 IF pc^ # MAGICC THEN
3235 Message("(Warning) Deallocate: heap corrupted");
3238 IF BSIZE <= NLISTS THEN
3239 BNEXT := FreeLists[BSIZE];
3240 FreeLists[BSIZE] := p;
3249 PROCEDURE ReOrganize();
3250 VAR lastblock: BucketPtr;
3255 FOR i := 1 TO NLISTS DO
3258 IF ADDRESS(b) > ADDRESS(lastblock) THEN
3262 b^.BNEXT := NIL; (* temporary free mark *)
3269 IF ADDRESS(b) > ADDRESS(lastblock) THEN
3277 (* Now, all free blocks have b^.BNEXT = NIL *)
3280 WHILE ADDRESS(b) < ADDRESS(lastblock) DO
3282 be := ADDRESS(b)+(b^.BSIZE+1)*UNIT;
3283 IF b^.BNEXT # NIL THEN
3284 (* this block is not free *)
3287 IF ADDRESS(be) > ADDRESS(lastblock) THEN
3291 IF be^.BNEXT # NIL THEN
3292 (* next block is not free *)
3295 (* this block and the next one are free,
3296 so merge them, but only if it is not too big
3298 IF MAX(CARDINAL) - b^.BSIZE > be^.BSIZE THEN
3299 b^.BSIZE := b^.BSIZE + be^.BSIZE + 1;
3307 (* clear all free lists *)
3308 FOR i := 1 TO NLISTS DO FreeLists[i] := NIL; END;
3311 (* collect free blocks in them again *)
3313 WHILE ADDRESS(b) <= ADDRESS(lastblock) DO
3316 IF BSIZE <= NLISTS THEN
3317 BNEXT := FreeLists[BSIZE];
3318 FreeLists[BSIZE] := b;
3323 b := ADDRESS(b) + (BSIZE+1) * UNIT;
3326 ((BSIZE + (UNIT - 1)) DIV UNIT + 1) * UNIT;
3332 PROCEDURE InitStorage();
3336 FOR i := 1 TO NLISTS DO
3337 FreeLists[i] := NIL;
3341 brk := sbrk(UNIT - brk MOD UNIT);
3342 FirstBlock := sbrk(0);
3350 Conversion.mod
\0\0\0\0\ 2\ 2¤
\ 1\0\0!
\a(*
3351 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3352 See the copyright notice in the ACK home directory, in the file "Copyright".
3356 IMPLEMENTATION MODULE Conversions;
3358 Module: numeric-to-string conversions
3359 Author: Ceriel J.H. Jacobs
3360 Version: $Id: Conversion.mod,v 1.8 1994/06/24 12:48:32 ceriel Exp $
3363 PROCEDURE ConvertNum(num, len, base: CARDINAL;
3365 VAR str: ARRAY OF CHAR);
3368 tmp: ARRAY [0..20] OF CHAR;
3373 num := num DIV base;
3375 tmp[i] := CHR(r + ORD('0'));
3377 tmp[i] := CHR(r - 10 + ORD('A'));
3385 IF len > HIGH(str) + 1 THEN len := HIGH(str) + 1; END;
3386 IF i > HIGH(str) + 1 THEN i := HIGH(str) + 1; END;
3388 WHILE len > i DO str[r] := ' '; INC(r); DEC(len); END;
3389 WHILE i > 0 DO str[r] := tmp[i-1]; DEC(i); INC(r); END;
3390 WHILE r <= HIGH(str) DO
3396 PROCEDURE ConvertOctal(num, len: CARDINAL; VAR str: ARRAY OF CHAR);
3398 ConvertNum(num, len, 8, FALSE, str);
3401 PROCEDURE ConvertHex(num, len: CARDINAL; VAR str: ARRAY OF CHAR);
3403 ConvertNum(num, len, 16, FALSE, str);
3406 PROCEDURE ConvertCardinal(num, len: CARDINAL; VAR str: ARRAY OF CHAR);
3408 ConvertNum(num, len, 10, FALSE, str);
3409 END ConvertCardinal;
3411 PROCEDURE ConvertInteger(num: INTEGER;
3413 VAR str: ARRAY OF CHAR);
3415 IF (num < 0) AND (num >= -MAX(INTEGER)) THEN
3416 ConvertNum(-num, len, 10, TRUE, str);
3418 ConvertNum(CARDINAL(num), len, 10, num < 0, str);
3423 ISemaphores.mod
\0\0\0\0\ 2\ 2¤
\ 1\0\0è
\b(*
3424 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3425 See the copyright notice in the ACK home directory, in the file "Copyright".
3429 IMPLEMENTATION MODULE Semaphores [1];
3431 Module: Processes with semaphores
3432 Author: Ceriel J.H. Jacobs
3433 Version: $Id: Semaphores.mod,v 1.7 1994/06/24 12:49:41 ceriel Exp $
3435 Quasi-concurrency implementation
3438 FROM SYSTEM IMPORT ADDRESS, NEWPROCESS, TRANSFER;
3439 FROM Storage IMPORT Allocate;
3440 FROM random IMPORT Uniform;
3441 FROM Traps IMPORT Message;
3443 TYPE Sema = POINTER TO Semaphore;
3444 Processes = POINTER TO Process;
3450 RECORD next: Processes;
3455 VAR cp: Processes; (* current process *)
3457 PROCEDURE StartProcess(P: PROC; n: CARDINAL);
3463 Allocate(cp, SIZE(Process));
3469 NEWPROCESS(P, wsp, n, cp^.proc);
3470 TRANSFER(s0^.proc, cp^.proc);
3473 PROCEDURE Up(VAR s: Sema);
3475 s^.level := s^.level + 1;
3479 PROCEDURE Down(VAR s: Sema);
3481 IF s^.level = 0 THEN
3484 s^.level := s^.level - 1;
3489 PROCEDURE NewSema(n: CARDINAL): Sema;
3492 Allocate(s, SIZE(Semaphore));
3497 PROCEDURE Level(s: Sema): CARDINAL;
3502 PROCEDURE ReSchedule;
3511 IF Runnable(cp) THEN
3513 IF i = 0 THEN EXIT END;
3515 IF (cp = s0) AND (j = i) THEN
3517 Message("deadlock");
3521 IF cp # s0 THEN TRANSFER(s0^.proc, cp^.proc); END;
3524 PROCEDURE Runnable(p: Processes): BOOLEAN;
3526 IF p^.waiting = NIL THEN RETURN TRUE; END;
3527 IF p^.waiting^.level > 0 THEN
3528 p^.waiting^.level := p^.waiting^.level - 1;
3535 Allocate(cp, SIZE(Process));
3541 random.mod
\0mod
\0\0\0\0\ 2\ 2¤
\ 1\0\0»
\ 4(*
3542 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3543 See the copyright notice in the ACK home directory, in the file "Copyright".
3547 IMPLEMENTATION MODULE random;
3549 Module: random numbers
3550 Author: Ceriel J.H. Jacobs
3551 Version: $Id: random.mod,v 1.8 1994/06/24 12:51:27 ceriel Exp $
3554 FROM Unix IMPORT getpid, time;
3555 TYPE index = [1..55];
3557 VAR X: ARRAY index OF CARDINAL;
3561 PROCEDURE Random(): CARDINAL;
3563 IF k-1 <= 0 THEN k := 55; ELSE DEC(k) END;
3564 IF j-1 <= 0 THEN j := 55; ELSE DEC(j) END;
3565 X[k] := X[k] + X[j];
3569 PROCEDURE Uniform (lwb, upb: CARDINAL): CARDINAL;
3571 IF upb <= lwb THEN RETURN lwb; END;
3572 RETURN lwb + (Random() MOD (upb - lwb + 1));
3575 PROCEDURE StartSeed(seed: CARDINAL);
3579 seed := 1297 * seed + 123;
3583 j := tm MOD 55D + 1D;
3586 j := tm MOD 55D + 1D;
3597 StartSeed(CARDINAL(getpid()) * X[1]);
3599 (Strings.mod
\0od
\0\0\0\0\ 2\ 2¤
\ 1\0\0î
\10(*
3600 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3601 See the copyright notice in the ACK home directory, in the file "Copyright".
3605 IMPLEMENTATION MODULE Strings;
3607 Module: String manipulations
3608 Author: Ceriel J.H. Jacobs
3609 Version: $Id: Strings.mod,v 1.6 1994/06/24 12:50:03 ceriel Exp $
3612 PROCEDURE Assign(source: ARRAY OF CHAR; VAR dest: ARRAY OF CHAR);
3613 (* Assign string source to dest
3618 max := HIGH(source);
3619 IF HIGH(dest) < max THEN max := HIGH(dest); END;
3621 WHILE (i <= max) AND (source[i] # 0C) DO
3622 dest[i] := source[i];
3625 IF i < HIGH(dest) THEN dest[i] := 0C; END;
3628 PROCEDURE Insert(substr: ARRAY OF CHAR; VAR str: ARRAY OF CHAR; inx: CARDINAL);
3629 (* Insert the string substr into str, starting at str[inx].
3630 If inx is equal to or greater than Length(str) then substr is appended
3633 VAR sublen, length, i: CARDINAL;
3635 sublen := Length(substr);
3636 IF sublen = 0 THEN RETURN; END;
3637 length := Length(str);
3638 IF inx > length THEN inx := length; END;
3640 IF i + sublen - 1 > HIGH(str) THEN i := HIGH(str); END;
3642 str[i+sublen-1] := str[i-1];
3645 FOR i := 0 TO sublen - 1 DO
3646 IF i + inx <= HIGH(str) THEN
3647 str[i + inx] := substr[i];
3652 IF length + sublen <= HIGH(str) THEN
3653 str[length + sublen] := 0C;
3657 PROCEDURE Delete(VAR str: ARRAY OF CHAR; inx, len: CARDINAL);
3658 (* Delete len characters from str, starting at str[inx].
3659 If inx >= Length(str) then nothing happens.
3660 If there are not len characters to delete, characters to the end of the
3663 VAR length: CARDINAL;
3665 IF len = 0 THEN RETURN; END;
3666 length := Length(str);
3667 IF inx >= length THEN RETURN; END;
3668 WHILE inx + len < length DO
3669 str[inx] := str[inx + len];
3675 PROCEDURE Pos(substr, str: ARRAY OF CHAR): CARDINAL;
3676 (* Return the index into str of the first occurrence of substr.
3677 Pos returns a value greater than HIGH(str) of no occurrence is found.
3679 VAR i, j, max, subl: CARDINAL;
3682 subl := Length(substr);
3683 IF subl > max THEN RETURN HIGH(str) + 1; END;
3684 IF subl = 0 THEN RETURN 0; END;
3686 FOR i := 0 TO max DO
3688 WHILE (j <= subl-1) AND (str[i+j] = substr[j]) DO
3691 IF j = subl THEN RETURN i; END;
3693 RETURN HIGH(str) + 1;
3696 PROCEDURE Copy(str: ARRAY OF CHAR;
3698 VAR result: ARRAY OF CHAR);
3699 (* Copy at most len characters from str into result, starting at str[inx].
3703 IF Length(str) <= inx THEN RETURN END;
3706 IF i > HIGH(result) THEN RETURN; END;
3707 IF len = 0 THEN EXIT; END;
3708 IF inx > HIGH(str) THEN EXIT; END;
3709 result[i] := str[inx];
3710 INC(i); INC(inx); DEC(len);
3712 IF i <= HIGH(result) THEN result[i] := 0C; END;
3715 PROCEDURE Concat(s1, s2: ARRAY OF CHAR; VAR result: ARRAY OF CHAR);
3716 (* Concatenate two strings.
3721 WHILE (i <= HIGH(s1)) AND (s1[i] # 0C) DO
3722 IF i > HIGH(result) THEN RETURN END;
3727 WHILE (j <= HIGH(s2)) AND (s2[j] # 0C) DO
3728 IF i > HIGH(result) THEN RETURN END;
3733 IF i <= HIGH(result) THEN result[i] := 0C; END;
3736 PROCEDURE Length(str: ARRAY OF CHAR): CARDINAL;
3737 (* Return number of characters in str.
3742 WHILE (i <= HIGH(str)) DO
3743 IF str[i] = 0C THEN RETURN i; END;
3749 PROCEDURE CompareStr(s1, s2: ARRAY OF CHAR): INTEGER;
3750 (* Compare two strings, return -1 if s1 < s2, 0 if s1 = s2, and 1 if s1 > s2.
3756 IF HIGH(s2) < max THEN max := HIGH(s2); END;
3759 IF s1[i] < s2[i] THEN RETURN -1; END;
3760 IF s1[i] > s2[i] THEN RETURN 1; END;
3761 IF s1[i] = 0C THEN RETURN 0; END;
3764 IF (i <= HIGH(s1)) AND (s1[i] # 0C) THEN RETURN 1; END;
3765 IF (i <= HIGH(s2)) AND (s2[i] # 0C) THEN RETURN -1; END;
3770 ArraySort.mod
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0×
\10(*
3771 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3772 See the copyright notice in the ACK home directory, in the file "Copyright".
3776 IMPLEMENTATION MODULE ArraySort;
3778 Module: Array sorting module.
3779 Author: Ceriel J.H. Jacobs
3780 Version: $Id: ArraySort.mod,v 1.4 1994/06/24 12:48:19 ceriel Exp $
3782 FROM SYSTEM IMPORT ADDRESS, BYTE; (* no generics in Modula-2, sorry *)
3784 TYPE BytePtr = POINTER TO BYTE;
3786 VAR compareproc: CompareProc;
3788 PROCEDURE Sort(base: ADDRESS; (* address of array *)
3789 nel: CARDINAL; (* number of elements in array *)
3790 size: CARDINAL; (* size of each element *)
3791 compar: CompareProc); (* the comparison procedure *)
3793 compareproc := compar;
3794 qsort(base, base+(nel-1)*size, size);
3797 PROCEDURE qsort(a1, a2: ADDRESS; size: CARDINAL);
3798 (* Implemented with quick-sort, with some extra's *)
3799 VAR left, right, lefteq, righteq: ADDRESS;
3806 lefteq := a1 + size * (((a2 - a1) + size) DIV (2 * size));
3809 Pick an element in the middle of the array.
3810 We will collect the equals around it.
3811 "lefteq" and "righteq" indicate the left and right
3812 bounds of the equals respectively.
3813 Smaller elements end up left of it, larger elements end
3818 IF left >= lefteq THEN EXIT END;
3819 cmp := compareproc(left, lefteq);
3820 IF cmp = greater THEN EXIT END;
3822 left := left + size;
3824 (* equal, so exchange with the element
3825 to the left of the "equal"-interval.
3827 lefteq := lefteq - size;
3828 exchange(left, lefteq, size);
3833 IF right <= righteq THEN EXIT END;
3834 cmp := compareproc(right, righteq);
3836 IF left < lefteq THEN
3837 (* larger one at the left,
3840 exchange(left,right,size);
3841 left := left + size;
3842 right := right - size;
3847 no more room at the left part, so we
3848 move the "equal-interval" one place to the
3849 right, and the smaller element to the
3851 This is best expressed as a three-way
3854 righteq := righteq + size;
3855 threewayexchange(left, righteq, right,
3857 lefteq := lefteq + size;
3859 ELSIF cmp = equal THEN
3860 (* equal, zo exchange with the element
3861 to the right of the "equal"
3864 righteq := righteq + size;
3865 exchange(right, righteq, size);
3867 (* leave it where it is *)
3868 right := right - size;
3871 IF (NOT mainloop) THEN
3872 IF left >= lefteq THEN
3873 (* sort "smaller" part *)
3874 qsort(a1, lefteq - size, size);
3875 (* and now the "larger" part, saving a
3876 procedure call, because of this big
3879 a1 := righteq + size;
3880 EXIT; (* from the LOOP *)
3882 (* larger element to the left, but no more room,
3883 so move the "equal-interval" one place to the
3884 left, and the larger element to the right
3887 lefteq := lefteq - size;
3888 threewayexchange(right, lefteq, left, size);
3889 righteq := righteq - size;
3896 PROCEDURE exchange(a,b: BytePtr; size : CARDINAL);
3903 a := ADDRESS(a) + 1;
3905 b := ADDRESS(b) + 1;
3909 PROCEDURE threewayexchange(p,q,r: BytePtr; size: CARDINAL);
3916 p := ADDRESS(p) + 1;
3918 r := ADDRESS(r) + 1;
3920 q := ADDRESS(q) + 1;
3922 END threewayexchange;
3925 pcatch.c
\0t.mod
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\9f /*
3926 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3927 See the copyright notice in the ACK home directory, in the file "Copyright".
3931 Module: default modula-2 trap handler
3932 Author: Ceriel J.H. Jacobs
3933 Version: $Id: catch.c,v 1.25 1994/11/14 11:51:24 ceriel Exp $
3936 #include <m2_traps.h>
3939 static struct errm {
3943 { EARRAY, "array bound error"},
3944 { ERANGE, "range bound error"},
3945 { ESET, "set bound error"},
3946 { EIOVFL, "integer overflow"},
3947 { EFOVFL, "real overflow"},
3948 { EFUNFL, "real underflow"},
3949 { EIDIVZ, "divide by 0"},
3950 { EFDIVZ, "divide by 0.0"},
3951 { EIUND, "undefined integer"},
3952 { EFUND, "undefined real"},
3953 { ECONV, "conversion error"},
3955 { ESTACK, "stack overflow"},
3956 { EHEAP, "heap overflow"},
3957 { EILLINS, "illegal instruction"},
3958 { EODDZ, "illegal size argument"},
3959 { ECASE, "case error"},
3960 { EMEMFLT, "addressing non existent memory"},
3961 { EBADPTR, "bad pointer used"},
3962 { EBADPC, "program counter out of range"},
3963 { EBADLAE, "bad argument of lae"},
3964 { EBADMON, "bad monitor call"},
3965 { EBADLIN, "argument if LIN too high"},
3966 { EBADGTO, "GTO descriptor error"},
3968 { M2_TOOLARGE, "stack size of process too large"},
3969 { M2_TOOMANY, "too many nested traps + handlers"},
3970 { M2_NORESULT, "no RETURN from function procedure"},
3971 { M2_UOVFL, "cardinal overflow"},
3972 { M2_FORCH, "(warning) FOR-loop control variable was changed in the body"},
3973 { M2_UUVFL, "cardinal underflow"},
3974 { M2_INTERNAL, "internal error; ask an expert for help"},
3975 { M2_UNIXSIG, "got a unix signal"},
3982 register struct errm *ep = &errors[0];
3985 register char *p, *s;
3987 while (ep->errno != trapno && ep->errmes != 0) ep++;
3988 if (p = ep->errmes) {
3990 _Traps__Message(ep->errmes, 0, (int) (p - ep->errmes), 1);
3994 static char q[] = "error number xxxxxxxxxxxxx";
4003 *s++ = i % 10 + '0';
4005 while (s > buf) *p++ = *--s;
4007 _Traps__Message(q, 0, (int) (p - q), 1);
4009 #if !defined(__em24) && !defined(__em44) && !defined(__em22)
4010 if (trapno == M2_UNIXSIG) {
4012 signal(__signo, SIG_DFL);
4014 kill(getpid(), __signo);
4018 if (trapno != M2_FORCH) {
4024 Traps.mod
\0mod
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\13\b(*
4025 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4026 See the copyright notice in the ACK home directory, in the file "Copyright".
4030 IMPLEMENTATION MODULE Traps;
4032 Module: Facility for handling traps
4033 Author: Ceriel J.H. Jacobs
4034 Version: $Id: Traps.mod,v 1.8 1994/06/24 12:50:25 ceriel Exp $
4037 FROM EM IMPORT SIG, LINO, FILN, TRP;
4038 FROM Unix IMPORT write;
4039 FROM SYSTEM IMPORT ADDRESS, ADR;
4040 FROM Arguments IMPORT
4043 PROCEDURE InstallTrapHandler(t: TrapHandler): TrapHandler;
4044 (* Install a new trap handler, and return the previous one.
4045 Parameter of trap handler is the trap number.
4049 END InstallTrapHandler;
4051 PROCEDURE Message(str: ARRAY OF CHAR);
4052 (* Write message "str" on standard error, preceeded by filename and
4053 linenumber if possible
4055 VAR p: POINTER TO CHAR;
4058 buf, buf2: ARRAY [0..255] OF CHAR;
4068 p := ADDRESS(p) + 1;
4072 IF write(2, ADR(buf), i) < 0 THEN END;
4075 IF write(2, ADR(buf), l-1) < 0 THEN END;
4081 buf[0] := ','; buf[1] := ' ';
4082 buf[2] := 'l'; buf[3] := 'i'; buf[4] := 'n'; buf[5] := 'e';
4091 buf2[j] := CHR(CARDINAL(lino) MOD 10 + ORD('0'));
4092 lino := lino DIV 10;
4103 IF write(2, ADR(buf), i+2) < 0 THEN END;
4105 WHILE (i <= HIGH(str)) AND (str[i] # 0C) DO
4108 IF write(2, ADR(str), i) < 0 THEN END;
4110 IF write(2, ADR(buf), 1) < 0 THEN END;
4113 PROCEDURE Trap(n: INTEGER);
4114 (* cause trap number "n" to occur *)
4120 ;XXTermcap.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0õ(/*
4121 * termcap.c 1.1 20/7/87 agc Joypace Ltd
4123 * Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
4124 * This file may be freely distributed provided that this notice
4127 * A public domain implementation of the termcap(3) routines.
4129 * Made fully functional by Ceriel J.H. Jacobs.
4132 * - does not check termcap entry sizes
4133 * - not fully tested
4138 #define ISSPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
4139 #define ISDIGIT(x) ((x) >= '0' && (x) <= '9')
4141 short ospeed = 0; /* output speed */
4142 char PC = 0; /* padding character */
4143 char *BC = 0; /* back cursor movement */
4144 char *UP = 0; /* up cursor movement */
4146 static char *capab = 0; /* the capability itself */
4147 static int check_for_tc();
4148 static int match_name();
4152 /* Some things from C-library, needed here because the C-library is not
4153 loaded with Modula-2 programs
4158 register char *s1, *s2;
4160 /* Append s2 to the end of s1. */
4162 char *original = s1;
4164 /* Find the end of s1. */
4165 while (*s1 != 0) s1++;
4167 /* Now copy s2 to the end of s1. */
4168 while (*s1++ = *s2++) /* nothing */ ;
4174 register char *s1, *s2;
4176 /* Copy s2 to s1. */
4177 char *original = s1;
4179 while (*s1++ = *s2++) /* nothing */;
4187 /* Return length of s. */
4191 while (*s != 0) s++;
4192 return(s - original);
4197 register char *s1, *s2;
4199 /* Compare 2 strings. */
4203 if (!*s1) return -1;
4207 if (*s1++ == 0) return(0);
4214 register char *s1, *s2;
4217 /* Compare two strings, but at most n characters. */
4221 if (!*s1) return -1;
4225 if (*s1++ == 0) break;
4233 register char *name;
4235 extern char **environ;
4236 register char **v = environ, *p, *q;
4238 if (v == 0 || name == 0) return 0;
4239 while ((p = *v++) != 0) {
4241 while (*q && *q++ == *p++) /* nothing */ ;
4242 if (*q || *p != '=') continue;
4249 fgets(buf, count, fd)
4252 static char bf[1024];
4254 static char *pbf = &bf[0];
4255 register char *c = buf;
4259 if (pbf >= &bf[cnt]) {
4260 if ((cnt = read(fd, bf, 1024)) <= 0) {
4261 if (c == buf) return (char *) NULL;
4278 * tgetent - get the termcap entry for terminal name, and put it
4279 * in bp (which must be an array of 1024 chars). Returns 1 if
4280 * termcap entry found, 0 if not found, and -1 if file not found.
4290 short len = strlen(name);
4294 if ((file = getenv("TERMCAP")) != (char *) NULL) {
4296 (cp = getenv("TERM")) != NULL && strcmp(name, cp) == 0) {
4297 (void) strcpy(bp, file);
4300 else file = "/etc/termcap";
4302 file = "/etc/termcap";
4303 if ((fp = open(file, 0)) < 0) {
4307 while (fgets(buf, 1024, fp) != NULL) {
4308 if (buf[0] == '#') continue;
4309 while (*(cp = &buf[strlen(buf) - 2]) == '\\')
4310 if (fgets(cp, 1024, fp) == NULL)
4312 if (match_name(buf, name)) {
4315 if(check_for_tc() == 0) {
4328 * Compare the terminal name with each termcap entry name; Return 1 if a
4332 match_name(buf, name)
4336 register char *tp = buf;
4340 for (np = name; *np && *tp == *np; np++, tp++) { }
4341 if (*np == 0 && (*tp == '|' || *tp == ':' || *tp == 0))
4343 while (*tp != 0 && *tp != '|' && *tp != ':') tp++;
4344 if (*tp++ != '|') return (0);
4349 * Handle tc= definitions recursively.
4354 static int count = 0;
4355 char *savcapab = capab;
4357 char terminalname[128];
4358 register char *p = capab + strlen(capab) - 2, *q;
4362 return(0); /* no : in termcap entry */
4363 if (p[1] != 't' || p[2] != 'c')
4366 return(0); /* recursion in tc= definitions */
4369 strcpy(terminalname, &p[4]);
4371 while (*q && *q != ':') q++;
4373 if (tgetent(buf, terminalname) != 1) {
4378 for (q = buf; *q && *q != ':'; q++) { }
4385 * tgetnum - get the numeric terminal capability corresponding
4386 * to id. Returns the value, -1 if invalid.
4395 if ((cp = capab) == NULL || id == NULL || *cp == 0)
4397 while (*++cp && *cp != ':')
4401 while (ISSPACE(*cp))
4403 if (strncmp(cp, id, CAPABLEN) == 0) {
4404 while (*cp && *cp != ':' && *cp != '#')
4408 for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++)
4409 ret = ret * 10 + *cp - '0';
4412 while (*cp && *cp != ':')
4419 * tgetflag - get the boolean flag corresponding to id. Returns -1
4420 * if invalid, 0 if the flag is not in termcap entry, or 1 if it is
4429 if ((cp = capab) == NULL || id == NULL || *cp == 0)
4431 while (*++cp && *cp != ':')
4435 while (ISSPACE(*cp))
4437 if (strncmp(cp, id, CAPABLEN) == 0)
4439 while (*cp && *cp != ':')
4446 * tgetstr - get the string capability corresponding to id and place
4447 * it in area (advancing area at same time). Expand escape sequences
4448 * etc. Returns the string, or NULL if it can't do it.
4459 if ((cp = capab) == NULL || id == NULL || *cp == 0)
4461 while (*++cp != ':')
4465 while (ISSPACE(*cp))
4467 if (strncmp(cp, id, CAPABLEN) == 0) {
4468 while (*cp && *cp != ':' && *cp != '=')
4472 for (ret = *area, cp++; *cp && *cp != ':' ; (*area)++, cp++)
4475 **area = *++cp - 'A' + 1;
4501 for (i=0 ; *cp && ISDIGIT(*cp) ; cp++)
4502 i = i * 8 + *cp - '0';
4518 while (*cp && *cp != ':')
4525 * tgoto - given the cursor motion string cm, make up the string
4526 * for the cursor to go to (destcol, destline), and return the string.
4527 * Returns "OOPS" if something's gone wrong, or the string otherwise.
4530 tgoto(cm, destcol, destline)
4536 static char ret[32];
4538 int *dp = &destline;
4543 for (rp = ret ; *cm ; cm++) {
4558 if (*cm == '+') *dp = *dp + *++cm;
4565 /* filter these out */
4566 if (dp == &destcol || swapped || UP) {
4567 strcat(added, dp == &destcol || swapped ?
4577 dp = (dp == &destline) ? &destcol : NULL;
4585 swapped = 1 - swapped;
4605 *dp = 16 * (*dp / 10) + *dp % 10;
4611 *dp = *dp - 2 * (*dp % 16);
4620 dp = (dp == &destline) ? &destcol : NULL;
4621 if (numval >= 100) {
4622 *rp++ = '0' + numval / 100;
4624 else if (*cm == '3') {
4628 *rp++ = '0' + ((numval%100)/10);
4630 else if (*cm == '3' || *cm == '2') {
4633 *rp++ = '0' + (numval%10);
4646 static int tens_of_ms_p_char[] = { /* index as returned by gtty */
4647 /* assume 10 bits per char */
4648 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 2
4651 * tputs - put the string cp out onto the terminal, using the function
4652 * outc. Also handle padding.
4655 tputs(cp, affcnt, outc)
4663 while (ISDIGIT(*cp)) {
4664 delay = delay * 10 + (*cp++ - '0');
4670 delay += *cp++ - '0';
4672 while (ISDIGIT(*cp)) cp++;
4682 ospeed < (sizeof tens_of_ms_p_char / sizeof tens_of_ms_p_char[0])) {
4683 delay = (delay + tens_of_ms_p_char[ospeed] - 1) /
4684 tens_of_ms_p_char[ospeed];
4685 while (delay--) (*outc)(PC);
4691 * That's all, folks...
4693 rdvi.c
\0cap.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0c
\ 4/*
4694 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4695 See the copyright notice in the ACK home directory, in the file "Copyright".
4699 Module: implementation of DIV and MOD
4700 Author: Ceriel J.H. Jacobs
4701 Version: $Id: dvi.c,v 1.2 1994/06/24 12:51:01 ceriel Exp $
4702 Reason: We cannot use DVI and RMI, because DVI rounds towards 0
4703 and Modula-2 requires truncation
4712 if (j == 0) TRP(EIDIVZ);
4713 if ((i < 0) != (j < 0)) {
4716 return -((i+j-1)/j);
4725 if (j == 0) TRP(EIDIVZ);
4726 if ((i < 0) != (j < 0)) {
4729 return -((i+j-1)/j);
4738 if (j == 0) TRP(EIDIVZ);
4739 if (i == 0) return 0;
4740 if ((i < 0) != (j < 0)) {
4743 return j*((i+j-1)/j)-i;
4752 if (j == 0) TRP(EIDIVZ);
4753 if (i == 0) return 0L;
4754 if ((i < 0) != (j < 0)) {
4757 return j*((i+j-1)/j)-i;
4761 eArguments.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\0\ 5/*
4762 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4763 See the copyright notice in the ACK home directory, in the file "Copyright".
4767 Module: Access to program arguments and environment
4768 Author: Ceriel J.H. Jacobs
4769 Version: $Id: Arguments.c,v 1.6 1994/06/24 12:48:10 ceriel Exp $
4772 extern char **argv, **environ;
4774 unsigned int _Arguments__Argc;
4778 register char *s1, *s2;
4781 while (*s1 == *s2++) s1++;
4782 if (*s1 == '\0' && *(s2-1) == '=') return s2;
4787 scopy(src, dst, max)
4788 register char *src, *dst;
4791 register unsigned int i = 0;
4793 while (*src && i <= max) {
4807 _Arguments__Argc = argc;
4811 _Arguments__Argv(n, argument, l, u, s)
4816 if (n >= argc) return 0;
4817 return scopy(argv[n], argument, u);
4821 _Arguments__GetEnv(name, nn, nu, ns, value, l, u, s)
4825 register char **p = environ;
4826 register char *v = 0;
4828 while (*p && !(v = findname(name, *p++))) {
4832 return scopy(v, value, u);
4834 LtoUset.e
\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0R
\ 5#
4836 ; (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4837 ; See the copyright notice in the ACK home directory, in the file "Copyright".
4840 ; Module: Compute non-constant set displays
4841 ; Author: Ceriel J.H. Jacobs
4842 ; Version: $Id: LtoUset.e,v 1.5 1994/06/24 12:48:53 ceriel Exp $
4844 mes 2,EM_WSIZE,EM_PSIZE
4846 ; LtoUset is called for set displays containing { expr1 .. expr2 }.
4847 ; It has six parameters, of which the caller must pop five:
4848 ; - The set in which bits must be set.
4849 ; - the lower bound of the set type.
4850 ; - The set size in bytes.
4851 ; - The upper bound of set elements, specified by the set-type.
4852 ; - "expr2", the upper bound
4853 ; - "expr1", the lower bound
4855 #define SETBASE 5*EM_WSIZE
4856 #define SETLOW 4*EM_WSIZE
4857 #define SETSIZE 3*EM_WSIZE
4858 #define USETSIZ 2*EM_WSIZE
4859 #define LWB EM_WSIZE
4863 lal SETBASE ; address of initial set
4865 los EM_WSIZE ; load initial set
4870 lol UPB ; high bound
4878 zgt *2 ; while low <= high
4881 set ? ; create [low]
4883 ior ? ; merge with initial set
4892 sts EM_WSIZE ; store result over initial set
4895 StrAss.c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\1a\ 2/*
4896 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4897 See the copyright notice in the ACK home directory, in the file "Copyright".
4901 Module: assign string to character array, with possible 0-byte
4903 Author: Ceriel J.H. Jacobs
4904 Version: $Id: StrAss.c,v 1.4 1994/06/24 12:49:51 ceriel Exp $
4906 StringAssign(dstsiz, srcsiz, dstaddr, srcaddr)
4907 register char *dstaddr, *srcaddr;
4909 while (srcsiz > 0) {
4910 *dstaddr++ = *srcaddr++;
4918 cap.c
\0.c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\89\ 1/*
4919 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4920 See the copyright notice in the ACK home directory, in the file "Copyright".
4924 Module: cap; implementation of CAP
4925 Author: Ceriel J.H. Jacobs
4926 Version: $Id: cap.c,v 1.3 1994/06/24 12:50:52 ceriel Exp $
4932 register unsigned *p = &u;
4934 if (*p >= 'a' && *p <= 'z') *p += 'A'-'a';
4936 rabsd.c
\0c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0o
\ 1/*
4937 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4938 See the copyright notice in the ACK home directory, in the file "Copyright".
4942 Module: double abs function
4943 Author: Ceriel J.H. Jacobs
4944 Version: $Id: absd.c,v 1.4 1994/06/24 12:50:35 ceriel Exp $
4951 return i >= 0 ? i : -i;
4954 absf.e
\0c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ï
\ 1#
4956 ; (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4957 ; See the copyright notice in the ACK home directory, in the file "Copyright".
4960 ; Module: REAL abs function
4961 ; Author: Ceriel J.H. Jacobs
4962 ; Version: $Id: absf.e,v 1.4 1994/06/24 12:50:38 ceriel Exp $
4964 mes 2,EM_WSIZE,EM_PSIZE
4984 absi.c
\0c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0H
\ 1/*
4985 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
4986 See the copyright notice in the ACK home directory, in the file "Copyright".
4990 Module: integer abs function
4991 Author: Ceriel J.H. Jacobs
4992 Version: $Id: absi.c,v 1.4 1994/06/24 12:50:42 ceriel Exp $
4997 return i >= 0 ? i : -i;
4999 absl.c
\0c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0U
\ 1/*
5000 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5001 See the copyright notice in the ACK home directory, in the file "Copyright".
5005 Module: longint abs function
5006 Author: Ceriel J.H. Jacobs
5007 Version: $Id: absl.c,v 1.4 1994/06/24 12:50:46 ceriel Exp $
5013 return i >= 0 ? i : -i;
5015 mhalt.c
\0c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0k
\ 2/*
5016 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5017 See the copyright notice in the ACK home directory, in the file "Copyright".
5021 Module: program termination routines
5022 Author: Ceriel J.H. Jacobs
5023 Version: $Id: halt.c,v 1.12 1994/06/24 12:51:04 ceriel Exp $
5027 static int callindex = 0;
5028 static int (*proclist[MAXPROCS])();
5032 while (--callindex >= 0)
5033 (*proclist[callindex])();
5040 if (callindex >= MAXPROCS) {
5043 proclist[callindex++] = p;
5052 SYSTEM.c
\0\0c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0u
\f/*
5053 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5054 See the copyright notice in the ACK home directory, in the file "Copyright".
5059 Author: Ceriel J.H. Jacobs
5060 Version: $Id: SYSTEM.c,v 1.4 1994/06/24 12:49:34 ceriel Exp $
5064 An implementation of the Modula-2 NEWPROCESS and TRANSFER facilities
5065 using the topsize, topsave, and topload facilities.
5066 For each coroutine, a proc structure is built. For the main routine,
5067 a static space is declared to save its stack. For the other coroutines,
5068 the user specifies this space.
5071 #include <m2_traps.h>
5073 #define MAXMAIN 2048
5076 unsigned size; /* size of saved stackframe(s) */
5077 int (*proc)(); /* address of coroutine procedure */
5078 char *brk; /* stack break of this coroutine */
5081 extern unsigned topsize();
5083 static struct proc mainproc[MAXMAIN/sizeof(struct proc) + 1];
5085 static struct proc *curproc = 0;/* current coroutine */
5086 extern char *MainLB; /* stack break of main routine */
5088 _SYSTEM__NEWPROCESS(p, a, n, p1)
5089 int (*p)(); /* coroutine procedure */
5090 struct proc *a; /* pointer to area for saved stack-frame */
5091 unsigned n; /* size of this area */
5092 struct proc **p1; /* where to leave coroutine descriptor,
5093 in this implementation the address of
5094 the area for saved stack-frame(s) */
5096 /* This procedure creates a new coroutine, but does not
5097 transfer control to it. The routine "topsize" will compute the
5098 stack break, which will be the local base of this routine.
5099 Notice that we can do this because we do not need the stack
5100 above this point for this coroutine. In Modula-2, coroutines
5101 must be level 0 procedures without parameters.
5104 unsigned sz = topsize(&brk);
5106 if (sz + sizeof(struct proc) > n) {
5107 /* not enough space */
5114 if (topsave(brk, a+1))
5115 /* stack frame saved; now just return */
5118 /* We get here through the first transfer to the coroutine
5120 This also means that curproc is now set to this coroutine.
5121 We cannot trust the parameters anymore.
5122 Just call the coroutine procedure.
5124 (*(curproc->proc))();
5130 _SYSTEM__TRANSFER(a, b)
5131 struct proc **a, **b;
5133 /* transfer from one coroutine to another, saving the current
5134 descriptor in the space indicated by "a", and transfering to
5135 the coroutine in descriptor "b".
5140 /* the current coroutine is the main process;
5141 initialize a coroutine descriptor for it ...
5143 mainproc[0].brk = MainLB;
5144 mainproc[0].size = sizeof(mainproc);
5145 curproc = &mainproc[0];
5147 *a = curproc; /* save current descriptor in "a" */
5148 if (*b == curproc) {
5149 /* transfer to itself is a no-op */
5152 size = topsize(&(curproc->brk));
5153 if (size + sizeof(struct proc) > curproc->size) {
5156 if (topsave(curproc->brk, curproc+1)) {
5157 /* stack top saved. Now restore context of target
5162 /* we never get here ... */
5164 /* but we do get here, when a transfer is done to the coroutine in "a".
5167 {par_misc.e
\0\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\11\r#
5169 ; (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5170 ; See the copyright notice in the ACK home directory, in the file "Copyright".
5174 ; Module: coroutine primitives
5175 ; Author: Kees Bot, Edwin Scheffer, Ceriel Jacobs
5176 ; Version: $Id: par_misc.e,v 1.7 1994/06/24 12:51:18 ceriel Exp $
5179 mes 2,EM_WSIZE,EM_PSIZE
5181 ; topsize takes care of two things:
5182 ; - given a stack-break,
5183 ; it computes the size of the chunk of memory needed to save the stack;
5184 ; - also, if this stack-break = 0, it creates one, assuming that caller is
5187 ; This implementation assumes a continuous stack growing downwards
5202 pro $topsize2, 3*EM_WSIZE+3*EM_PSIZE
5204 pro $topsize, 3*EM_WSIZE+3*EM_PSIZE
5206 ; local space for line-number, ignoremask, filename, stack-break, size,
5207 ; and stack-pointer (see the topsave routine)
5211 loi EM_PSIZE ; stack-break or 0
5216 dch ; local base of caller
5218 dch ; because of the extra layer
5227 lpb ; convert this local base to an argument base.
5228 ; An implementation of a sort of "topsize" EM
5229 ; instruction should take a local base, and save
5232 lor 1 ; stack-break SP
5233 sbs EM_WSIZE ; stack-break-SP
5234 ret EM_WSIZE ; return size of block to be saved
5235 end 3*EM_WSIZE+3*EM_PSIZE
5255 lae 4 ; load line number and file name
5260 loi EM_PSIZE ; stack-break
5265 adu EM_WSIZE ; gives size
5268 lor 1 ; SP (the SP BEFORE pushing)
5269 lor 1 ; SP (address of stack top to save)
5273 bls EM_WSIZE ; move whole block
5274 asp 3*EM_PSIZE+3*EM_WSIZE ; remove the lot from the stack
5276 ret EM_WSIZE ; return 1
5302 sti EM_PSIZE ; saved parameter
5309 loi EM_PSIZE ; compare target SP with current LB to see if we must
5311 cmp ; find another LB first
5313 dch ; just follow dynamic chain to make sure we find
5321 loi EM_PSIZE ; load indirect to
5323 asp -EM_PSIZE ; to stop int from complaining about non-existent memory
5325 loi EM_PSIZE ; source address
5327 adp EM_PSIZE ; destination address
5331 loi EM_WSIZE ; size of block
5333 asp EM_PSIZE+EM_WSIZE ; drop size + SP
5334 str 0 ; restore local base
5338 ste 0 ; line and file
5343 init.c
\0c.e
\0\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0)
\ 5/*
5344 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5345 See the copyright notice in the ACK home directory, in the file "Copyright".
5349 Module: initialization and some global vars
5350 Author: Ceriel J.H. Jacobs
5351 Version: $Id: init.c,v 1.9 1994/06/24 12:51:11 ceriel Exp $
5356 #include <m2_traps.h>
5358 /* map unix signals onto EM traps */
5361 sigtrp(M2_UNIXSIG, SIGHUP);
5362 sigtrp(M2_UNIXSIG, SIGINT);
5363 sigtrp(M2_UNIXSIG, SIGQUIT);
5364 sigtrp(EILLINS, SIGILL);
5365 sigtrp(M2_UNIXSIG, SIGTRAP);
5366 sigtrp(M2_UNIXSIG, SIGIOT);
5367 sigtrp(M2_UNIXSIG, SIGEMT);
5368 sigtrp(M2_UNIXSIG, SIGFPE);
5369 sigtrp(M2_UNIXSIG, SIGBUS);
5370 sigtrp(M2_UNIXSIG, SIGSEGV);
5371 sigtrp(EBADMON, SIGSYS);
5372 sigtrp(M2_UNIXSIG, SIGPIPE);
5373 sigtrp(M2_UNIXSIG, SIGALRM);
5374 sigtrp(M2_UNIXSIG, SIGTERM);
5376 #if defined(__em22) || defined(__em24) || defined(__em44)
5382 static int blablabla; /* We cannot use end, because then also
5383 bss allocated for the systemcall lib
5384 would be overwritten. Lets hope that
5390 extern char *bkillbss;
5391 register char *p = (char *) &bkillbss;
5393 while (p < (char *) &blablabla) *p++ = 0x66;
5399 int (*handler)() = catch;
5400 char **argv = 0, **environ = 0;
5403 sigtrp.c
\0e
\0\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\1e\a/*
5404 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5405 See the copyright notice in the ACK home directory, in the file "Copyright".
5409 Module: Mapping of Unix signals to EM traps
5410 (only when not using the MON instruction)
5411 Author: Ceriel J.H. Jacobs
5412 Version: $Id: sigtrp.c,v 1.8 1994/06/24 12:51:47 ceriel Exp $
5415 #if !defined(__em22) && !defined(__em24) && !defined(__em44)
5417 #define EM_trap(n) TRP(n) /* define to whatever is needed to cause the trap */
5424 static int __traps[] = {
5425 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
5426 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
5427 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
5433 signal(signo,__ctchsig);
5435 sigsetmask(sigblock(0) & ~(1<<(signo - 1)));
5438 EM_trap(__traps[signo]);
5442 sigtrp(trapno, signo)
5444 /* Let Unix signal signo cause EM trap trapno to occur.
5445 If trapno = -2, restore default,
5446 If trapno = -3, ignore.
5447 Return old trapnumber.
5448 Careful, this could be -2 or -3; But return value of -1
5449 indicates failure, with error number in errno.
5452 void (*ctch)() = __ctchsig;
5456 if (signo <= 0 || signo >= sizeof(__traps)/sizeof(__traps[0])) {
5463 else if (trapno == -2)
5465 else if (trapno >= 0 && trapno <= 252)
5472 oldtrap = __traps[signo];
5474 if ((oldctch = signal(signo, ctch)) == (void (*)())-1) /* errno set by signal */
5477 else if (oldctch == SIG_IGN) {
5478 signal(signo, SIG_IGN);
5480 else __traps[signo] = trapno;
5485 store.c
\0\0e
\0\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0å
\ 3/*
5486 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5487 See the copyright notice in the ACK home directory, in the file "Copyright".
5491 Module: store values from stack, byte by byte
5492 Author: Ceriel J.H. Jacobs
5493 Version: $Id: store.c,v 1.6 1994/06/24 12:51:53 ceriel Exp $
5496 #include <m2_traps.h>
5499 #define EM_WSIZE _EM_WSIZE
5500 #define EM_PSIZE _EM_PSIZE
5503 #if EM_WSIZE==EM_PSIZE
5504 typedef unsigned pcnt;
5510 register char *addr;
5513 /* Make sure, that a value with a size that could have been
5514 handled by the LOI instruction is handled as if it was
5515 loaded with the LOI instruction.
5517 register char *q = (char *) &p;
5520 if (siz < EM_WSIZE && EM_WSIZE % siz == 0) {
5521 /* as long as EM_WSIZE <= 4 ... */
5522 if (siz != 2) TRP(M2_INTERNAL); /* internal error */
5523 *((unsigned short *) (&t[0])) = *((unsigned *) q);
5526 while (siz--) *addr++ = *q++;
5528 oconfarray.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0²
\ 5/*
5529 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5530 See the copyright notice in the ACK home directory, in the file "Copyright".
5534 Module: runtime support for conformant arrays
5535 Author: Ceriel J.H. Jacobs
5536 Version: $Id: confarray.c,v 1.11 1994/06/24 12:50:58 ceriel Exp $
5538 #include <m2_traps.h>
5541 #define EM_WSIZE _EM_WSIZE
5542 #define EM_PSIZE _EM_PSIZE
5545 #if EM_WSIZE==EM_PSIZE
5546 typedef unsigned pcnt;
5548 typedef unsigned long pcnt;
5554 unsigned int highminlow;
5558 static struct descr *descrs[10];
5559 static struct descr **ppdescr = descrs;
5562 new_stackptr(pdscr, a)
5563 struct descr *pdscr;
5565 register struct descr *pdescr = pdscr;
5566 pcnt size = (((pdescr->highminlow + 1) * pdescr->size +
5567 (EM_WSIZE - 1)) & ~(EM_WSIZE - 1));
5569 if (ppdescr >= &descrs[10]) {
5570 /* to many nested traps + handlers ! */
5573 *ppdescr++ = pdescr;
5574 if ((char *) &a - (char *) &pdscr > 0) {
5575 /* stack grows downwards */
5584 register char *p = pp;
5590 sz = ((*ppdescr)->highminlow + 1) * (*ppdescr)->size;
5592 if ((char *) &a - (char *) &pp > 0) {
5593 (*ppdescr)->addr = q = (char *) &a;
5595 else (*ppdescr)->addr = q = (char *) &a -
5596 ((sz + (EM_WSIZE - 1)) & ~ (EM_WSIZE - 1));
5598 while (sz--) *q++ = *p++;
5600 load.c
\0ay.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\a\ 4/*
5601 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5602 See the copyright notice in the ACK home directory, in the file "Copyright".
5606 Module: get value on stack, byte by byte
5607 Author: Ceriel J.H. Jacobs
5608 Version: $Id: load.c,v 1.6 1994/06/24 12:51:14 ceriel Exp $
5611 #include <m2_traps.h>
5614 #define EM_WSIZE _EM_WSIZE
5615 #define EM_PSIZE _EM_PSIZE
5618 #if EM_WSIZE==EM_PSIZE
5619 typedef unsigned pcnt;
5625 register char *addr;
5628 /* Make sure, that a value with a size that could have been
5629 handled by the LOI instruction ends up at the same place,
5630 where it would, were the LOI instruction used.
5632 register char *q = (char *) &p;
5635 if (siz < EM_WSIZE && EM_WSIZE % siz == 0) {
5636 /* as long as EM_WSIZE <= 4 ... */
5637 if (siz != 2) TRP(M2_INTERNAL); /* internal error */
5640 while (siz--) *q++ = *addr++;
5642 *((unsigned *)(&p)) = *((unsigned short *) (&t[0]));
5645 dblockmove.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Ü
\ 1/*
5646 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5647 See the copyright notice in the ACK home directory, in the file "Copyright".
5652 Author: Ceriel J.H. Jacobs
5653 Version: $Id: blockmove.c,v 1.4 1994/06/24 12:50:49 ceriel Exp $
5656 #if _EM_WSIZE==_EM_PSIZE
5657 typedef unsigned pcnt;
5659 typedef unsigned long pcnt;
5662 blockmove(siz, dst, src)
5664 register char *dst, *src;
5666 while (siz--) *dst++ = *src++;
5668 stackprio.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0Í
\ 1/*
5669 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5670 See the copyright notice in the ACK home directory, in the file "Copyright".
5674 Module: Dummy priority routines
5675 Author: Ceriel J.H. Jacobs
5676 Version: $Id: stackprio.c,v 1.5 1994/06/24 12:51:50 ceriel Exp $
5679 static unsigned prio = 0;
5684 unsigned old = prio;
5686 if (n > prio) prio = n;
5695 +ucheck.c
\0.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0H
\ 4/*
5696 * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5697 * See the copyright notice in the ACK home directory, in the file "Copyright".
5700 * Module: CARDINAL operations with overflow checking
5701 * Author: Ceriel J.H. Jacobs
5702 * Version: $Id: ucheck.c,v 1.4 1994/06/24 12:51:56 ceriel Exp $
5706 #define EM_WSIZE _EM_WSIZE
5709 #define EM_LSIZE _EM_LSIZE
5712 #include <m2_traps.h>
5714 #define MAXCARD ((unsigned)-1)
5715 #if EM_WSIZE < EM_LSIZE
5716 #define MAXLONGCARD ((unsigned long) -1L)
5722 if (MAXCARD - a < b) TRP(M2_UOVFL);
5725 #if EM_WSIZE < EM_LSIZE
5729 if (MAXLONGCARD - a < b) TRP(M2_UOVFL);
5736 if (a != 0 && MAXCARD/a < b) TRP(M2_UOVFL);
5739 #if EM_WSIZE < EM_LSIZE
5743 if (a != 0 && MAXLONGCARD/a < b) TRP(M2_UOVFL);
5750 if (b < a) TRP(M2_UUVFL);
5753 #if EM_WSIZE < EM_LSIZE
5757 if (b < a) TRP(M2_UUVFL);
5760 rcka.c
\0c
\0.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0%
\ 2/*
5761 * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5762 * See the copyright notice in the ACK home directory, in the file "Copyright".
5765 * Module: range checks for INTEGER, now for array indexing
5766 * Author: Ceriel J.H. Jacobs
5767 * Version: $Id: rcka.c,v 1.2 1994/06/24 12:51:30 ceriel Exp $
5774 struct array_descr {
5781 struct array_descr *descr;
5783 if (indx < 0 || indx > descr->n_elts_min_one) TRP(EARRAY);
5786 rcku.c
\0c
\0.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0û
\ 1/*
5787 * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5788 * See the copyright notice in the ACK home directory, in the file "Copyright".
5791 * Module: range checks for CARDINAL
5792 * Author: Ceriel J.H. Jacobs
5793 * Version: $Id: rcku.c,v 1.3 1994/06/24 12:51:40 ceriel Exp $
5800 struct range_descr {
5805 struct range_descr *descr;
5808 if (val < descr->low || val > descr->high) TRP(ERANGE);
5810 xrcki.c
\0c
\0.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0å
\ 1/*
5811 * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5812 * See the copyright notice in the ACK home directory, in the file "Copyright".
5815 * Module: range checks for INTEGER
5816 * Author: Ceriel J.H. Jacobs
5817 * Version: $Id: rcki.c,v 1.2 1994/06/24 12:51:33 ceriel Exp $
5824 struct range_descr {
5829 struct range_descr *descr;
5831 if (val < descr->low || val > descr->high) TRP(ERANGE);
5833 >rckul.c
\0\0.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0\a\ 2/*
5834 * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5835 * See the copyright notice in the ACK home directory, in the file "Copyright".
5838 * Module: range checks for LONGCARD
5839 * Author: Ceriel J.H. Jacobs
5840 * Version: $Id: rckul.c,v 1.3 1994/06/24 12:51:43 ceriel Exp $
5847 struct range_descr {
5848 unsigned long low, high;
5852 struct range_descr *descr;
5855 if (val < descr->low || val > descr->high) TRP(ERANGE);
5857 _rckil.c
\0\0.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0ô
\ 1/*
5858 * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5859 * See the copyright notice in the ACK home directory, in the file "Copyright".
5862 * Module: range checks for LONGINT
5863 * Author: Ceriel J.H. Jacobs
5864 * Version: $Id: rckil.c,v 1.3 1994/06/24 12:51:37 ceriel Exp $
5871 struct range_descr {
5876 struct range_descr *descr;
5879 if (val < descr->low || val > descr->high) TRP(ERANGE);
5881 EM.e
\0.c
\0\0.c
\0d
\0\0\0\0\0\ 2\ 2¤
\ 1\0\0%
\a#
5883 ; (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
5884 ; See the copyright notice in the ACK home directory, in the file "Copyright".
5887 ; Module: Interface to some EM instructions and data
5888 ; Author: Ceriel J.H. Jacobs
5889 ; Version: $Id: EM.e,v 1.6 1994/06/24 12:48:39 ceriel Exp $
5891 mes 2,EM_WSIZE,EM_PSIZE
5894 #define ARG2 EM_DSIZE
5895 #define IRES 2*EM_DSIZE
5897 ; FIF is called with three parameters:
5898 ; - address of integer part result (IRES)
5899 ; - float two (ARG2)
5900 ; - float one (ARG1)
5901 ; and returns an EM_DSIZE-byte floating point number
5903 ; PROCEDURE FIF(ARG1, ARG2: LONGREAL; VAR IRES: LONGREAL) : LONGREAL;
5917 #define ERES EM_DSIZE
5919 ; FEF is called with two parameters:
5920 ; - address of base 2 exponent result (ERES)
5921 ; - floating point number to be split (FARG)
5922 ; and returns an EM_DSIZE-byte floating point number (the mantissa)
5924 ; PROCEDURE FEF(FARG: LONGREAL; VAR ERES: integer): LONGREAL;
5939 ; TRP is called with one parameter:
5940 ; - trap number (TRAP)
5942 ; PROCEDURE TRP(trapno: INTEGER);
5953 ; SIG is called with one parameter:
5954 ; - procedure instance identifier (PROC)
5955 ; and returns the old traphandler.