begin ! ! !********************************************************************* ! ! MORE COMMENTS AND SWITCH SYSFUN(232) - SYSFUN(280) TIDIED UP ! !********************************************************************* ! ! CHANNEL USAGE ! ST01 - T#DUMP ! ST02 - LOGNAM ! ST03 - T#TEMP ! SM04 - LOGOFILE ! SM06 - T#LOGOSTK ! SM07 - LOGOMON ! SM08 - BFILE ! SM10 - JUNK FILE ! !***************************************** ! GRAPHICS LINKAGE !***************************************** ! external integer fn spec conv(integer x) external routine spec vecorpoint(integer i, j, k, l) external routine spec pause external routine spec load42(string (63) file) external routine spec set42(integer nm) external routine spec clear42 external routine spec ch3(integer char) external routine spec mode42(integer n) external routine spec lbr external routine spec rbr ! PARENTHESIS const integer initgraphp = X'202E' ! START OF DISPLAY SPACE ! extrinsic integer graphp42 extrinsic integer cur42mode extrinsic integer ddata, dstart, dlast, graphp !POINTERS TO GT42 CORE extrinsic integer vectorm, pointm, charm !EMAS GT42 EXEC INSTRUCTIONS extrinsic integer bleep, chtxt, chpic, gradv, add2, set, add1, setn, wait, pmov, clr, ack !GT42EXECINSTRUCTIONS ! own integer pen = X'4000', normal = X'9E54', djump = X'E000', frametime = 50 const integer corebottom = X'3FF0' const integer call = 0, posnat = X'C000', lineto = X'8000' integer textflag, gmode, curpic, curmovie, curframe, defpicture, C curmode, frameflag, grablist, picturepointer const integer turtlestart = X'201A' const string (17) gt42exec = "ECMI05.EXEC26" own integer showturtle42 = 1 ! ! MOVIE AREA ! record format picdir(C integer ptr, ptr42, x, y, faddr, moved, mode, lastmovetime) own record (picdir) array index42(0 : 1022) string (10) savepromp own integer capflag = 0 ! USED TO GENERATE CAPTIONS ! ! ! integer xcrane, ycrane, hdcrane const integer cranemark = X'000F0000', cranemask = X'FFFF0000' !*************************************************** external routine spec dresume(integer lnb, pc, addr18) external routine spec reroutecontingency(integer ep, class, long integer mask, routine name rr, integer name flag) external integer fn spec readid(integer adr) external routine spec edinner(integer st, sl, sc1, sc2, awsp, C integer name l) external routine spec disconnect(string (63) s) external routine spec closesm(integer ch) external string fn spec uinfs(integer type) record format f(C integer ad, type, dst, dend, size, rup, eep, mode, cons, arch, C string (6) trans, string (8) date, time, C integer count, spare1, spare2) external routine spec finfo(string (15) s, integer lev, C record (f) name r, integer name flag) external routine spec fill(integer len, addr, val) external routine spec move(integer length, from, to) external string fn spec date external routine spec list(string (63) s) external string fn spec time external long real fn spec cputime external integer fn spec smaddr(integer chann, integer name length) external routine spec define(string (65) s) external routine spec permit(string (65) s) external routine spec newsmfile(string (63) s) external routine spec cherish(string (63) s) external routine spec prompt(string (15) m) external routine spec destroy(string (65) s) external routine spec closestream(integer ch) external real fn spec random(integer name i, integer j) external string fn spec interrupt external routine spec rename(string (65) s) external routine spec clear(string (65) s) record format rf(integer conad, type, start, end) external routine spec connect(string (31) file, C integer mode, hole, prot, record (rf) name r, integer name flag) routine spec baderror(string (80) errmess, integer culprit) routine spec applyusr(integer envir, fun, tstflg, val, C integer name severity) routine spec nooline(integer n) routine spec prstring(string (255) word) integer fn spec unstack integer fn spec checkstack routine spec printlist(integer list) routine spec printel(integer i) integer fn spec hd(integer list) integer fn spec tl(integer list) routine spec printline(integer line) integer fn spec readline routine spec logo(integer stktop, envir, severity) routine spec dump(string (80) errmess) routine spec getpage(integer flag) integer flength, fstart ! FOR FILE MAPPING string (6) emasuser ! AS A STRING const integer maxsource = 50000 ! ! ! ! THE FOLLOWING DECLARATIONS ARE CONCERNED WITH TRAPPING TIME EXCEEDED ! AND RESETTING THE LOCAL TIME LIMIT, AND DEALING WITH CONSOLE INTS ! %EXTERNALROUTINESPEC GETTIM(%INTEGERNAME I) external routine spec signal(integer ep, parm, extra, C integer name flag) !@#$ %EXTERNALROUTINESPEC SVC(%RECORDNAME P) !@#$ %RECORDFORMAT PARM(%SHORTINTEGER DEST,DUM1,%C INTEGER DUM2,!@#$ DUM3,ARG1,ARG2,ARG3,ARG4) !@#$ %RECORD P(PARM) !%STRINGNAME INTCHAR !%OWNINTEGERARRAY SAVE(1:26) !%OWNINTEGERARRAY RR(4:15) own integer i, k, flag, adump, r3 ! ! ! ! WORD AREA AND NUMBER DECLARATIONS ! byte integer array inbuff(0 : 500) integer inptr, headin, unusedhd string array name wa string (64) array format sform1(0 : 1022) ! WORD TABLE own integer wm = 1, nm = 4 ! WORD MARKER,NUMBER MARKER own integer t8 = X'FF000000' integer numtop, numbot ! NUMBER RANGE DELIMITERS own integer maxint = X'7FFFFFFF' ! MAXIMUM INTEGER ALLOWED BY IMP own integer ranseed = 50003 string (64) name work1 integer logotime integer array intstr(1 : 20) string (4) space4 integer name hashval, lbrak, rbrak, dots, empty, undef, and, repeat, C apply, do, comma, quote, lpar, rpar, minus, if, then, else, close, C while, unminus, ift, iff, true, false, end, delete, undo, undos, to, C err, logoname, def, langbrks, rangbrks, quit, break, space1, C tab, enel, start, finish, comment integer array names(1 : 100) ! CONTAINS HASHED VALUES OF ! SPECHARS AND RESERVED NAMES own integer array spechar(1 : 14) = ':', '<', '>', '''', '(', ')', C '*', '+', ',', '-', '/', '=', '[', ']' integer prnum string (4) promp integer evalimit, evalcnt, parselimit, parsecnt ! ! FUNCTION SPEC INFO IS HELD IN ARRAY FNVAL WHICH IS ! PARALLEL TO WA AND IS ACCESSED DIRECTLY USING ! WORD INDEX. ! EACH ENTRY IN FNVAL WILL BE ONE OF THE FOLLOWING.... ! ! FNVAL ENTRY ! FUNCTION TYPE B4 B3 B2 B1 ! 1) SYSTEM PREFIX TRACEFLAG/1 ARGNO SWITCH......... ! 2) SYSTEM INFIX TRACEFLAG/2 PREC. SWITCH........ ! 3) SYSTEM INTERP 4 - SWITCH - ! 4) USER PREFIX TRACEFLAG/8 LA(INDEX) ARGNO ! 5) UNDEFINED 0 0 0 0 ! ! FNTEXT HOLDS POINTERS TO START OF TEXT OF FN ! FNLEN HOLDS THE LENGTH OF THE FN TEXT (IN BYTES) ! ! ! FUNCTION SPEC AREA DECLARATIONS ! byte integer array format parseform(0 : 1022) byte integer array name fnparse integer array name fnval, oldfn, assocwa, fntext, fnlen integer array format intform1(0 : 1022) ! OLDFN HAS OLD FNVAL ENTRY WHEN FN REDEFINED. ! ASSOCWA HAS OBJECT ASSOCIATION POINTER INTO LIST SPACE. ! ASSOCWA USED ONLY BY MAKEASSOC,GETASSOC,AND REMASSOC own integer syspre = X'1000000', infix = X'2000000', C interp = X'4000000', userpre = X'8000000' own integer b3b = X'7F0000', b2 = X'FFFF', b4 = X'3F000000', C m16 = X'FFFF00' own integer traceflg = X'C0000000', unmask = X'3FFFFFFF' own integer trace1 = X'40000000', trace2 = X'80000000' own integer restart = 0 ! SET BY BADERROR FOR REINIT integer indent ! ! ! ! USER STACK DECLARATIONS ! integer array name stk integer stktop, stkpnt ! ! ! SYSTEM STACK DECLARATONS ! integer array name systk integer array format intform2(1 : 2000) integer systkpnt ! ! ! ! LIST AREA DECLARATIONS ! integer array name la integer array format intform3(1 : 65536) ! ALL LIST STRUCTURE IS CONSTRUCED IN LA. ! LA IS DIVIDED INTO THREE PARTS. THE FIRST AND SECOND PARTS ARE ! USED AS THE TWO SEMISPACES FOR LISTS GENERATED BY THE USER AND BY ! THE INPUT READER. ONLY ONE SEMISPACE IS ACTIVE AT ONE TIME, THE ! COLLECTOR COPYING FROM ONE TO THE OTHER. ! THE THIRD PART IS USED FOR FUNCTION DEFINITIONS AND IS NEVER ! COLLECTED. byte integer array name source byte integer array format sourceform(0 : 50000) integer linenumlist integer level, fndefn, sourceptr, parlevel, condflag, diagflag, plevel, C goflag own integer la1b = 1, la1t = 24576, la2b = 24577, la2t = 49152, C lafnb = 49153, lafnt = 65536 ! TOP AND BOTTOM VALUES OF VARIOUS LIST SPACES integer clectflg ! GARBAGE COLLECT FLAG integer listop, lpoint, lpoint1, labase, semisize ! LPOINT IS FREE POINTER TO COLLECTABLE LIST AREA ! LPOINT1 IS FREE POINTER TO UNCOLLECTABLE AREA ! LABASE IS BASE OF CURRENT SEMISPACE ! SEMISIZE IS SIZE OF SEMISPACE ! real cfract ! GARBAGE COLLECT WHEN CFRACT OF SPACE USED integer quoteon, blevel ! USED BY LIST READER integer name nil string (1) sep ! USED BY PRINTER own string (1) stermin = " " ! NL ASSSTRING own integer termin = 10 ! NL AS SYMBOL integer charout integer enuf own integer lm = 2 ! ! ! ! ENVIRONMENT DECLARATIONS ! integer array name bname, bvalue integer array format intform4(1023 : 3000) integer array format intform5(0 : 3000) integer basenvir, topmark ! ! ! ! INFERENCE SYSTEM DECLARATIONS ! integer name factkeys, infkeys, impkeys, fact, implies, toinfer integer name database, imprules, infrules !DATABASE,IMPRULES AND INFRULES ARE LOGO WORDS WHOSE ! BVALUES HOLD A LIST OF THE ASSERTED FACTS, IMPLIED RULES ! AND INFERRED RULES RESPECTIVELY. ! ALL INFERENCE RULES ARE ALSO HELD IN ASSOCIATIONS. ! FACTKEYS,IMPKEYS AND INFKEYS ARE LOGO WORDS WHOSE ! BVALUES HOLD LISTS OF THE NAMES OF ASSOCIATION ! SETS FOR FACTS, IMPLIED RULES AND INFERRED RULES RESPECTIVELY ! FACT, IMPLIES AND TOINFER ARE ATTRIBUTES WITHIN EACH ! ASSOCIATION SET integer name thinkaloud, new, vbl, not ! THINKALOUD IS A LOGO VARIABLE SET TO TRUE OR FALSE BY THE USER integer genos integer array dbase, implinks, inflinks(1 : 3) ! THE FIRST ELEMENT OF DBASE, IMPLINKS AND INFLINKS HOLDS ! THE LOGO WORD DATABASE, IMPRULES AND INFRULES RESPCTIVELY. ! THE 2ND ELEMENT CONTAINS THE LOGO WORD FACT, IMPLIES ! AND TOINFER RESPECTIVELY. ! THE 3RD ELEMENT HOLDS THE LOGO WORD FACTKEYS,IMPKEYS AND ! INFKEYS RESPECTIVELY. ! ! ! ! ERROR AND USER INTERUPPT RECOVERY ! ! ERROR RECOVERY IS CONTROLLED BY THREE FLAGS - JUMPFLAG,JUMPOUT ! AND SENDFLAG. ! JUMPFLAG=1 WITH SENDFLAG=0 TRIGGERS A SEQUENCE OF RETURNS FROM THE ! ERROR ROUTINE TO THE LAST ACTIVATION OF LOGO. ! RETURNS THRU LOGO TO EARLIER ACTIVATIONS IS CONTROLLED BY JUMPOUT ! IF JUMPOUT =0 NO RETURN PAST THE LAST ACTIVATION OCCURS. THIS IS THE ! CASE FOR SIMPLE ERRORS (IE OUTSIDE USER FUNS). ! IF JUMPOUT=-1 A NORMAL RETURN THRU THE LAST LOGO IS OBTAINED. THIS ! CAUSES THE LAST SUSPENDED PROCESS TO BE CONTINUED. JUMPOUT IS SET ! TO -1 BY LOGO FUN CONTINUE. ! IF JUMPOUT>0 ,THAT MANY LOGOS ARE RETURNED FROM. JUMPOUT IS SET ! TO N BY ABORT N, AND TO 100 BY QUIT. ! WHENEVER BASE LEVEL IS REACHED (WHEN PROMPT NUMBER IS 1), THE SETTING ! OF JUMPOUT IS IGNORED. ! ! JUMPFLAG=1 WITH SENDFLAG>0 TRIGGERS A SERIES OF RETURNS FROM THE ! ERROR ROUTINE TO THE LAST ACTIVATION OF APPLYUSR. ! RETURNS THRU APPLYUSR ARE CONTROLLED BY THE ACTUAL VALUE ! OF SENDFLAG, THAT MANY RETURNS BEING MADE. THIS IS USED TO SEND BACK ! A USER SUPPLIED VALUE AS THE RESULT OF A NAMED USERFUN IN THE ! CURRENT NEST. SENDFLAG IS SET BY SENDBACK IN APPLYSYS. ! ! integer jumpflag, jumpout, sendflag, libload, superjmp integer quitflag, holdflag ! USER INT FLAGS ! integer name quitotop ! LOGO VARIABLE, SET TO TRUE OR FALSE BY THE USER ! DETERMINES WHETHER OR NOT TO ENTER THE PRIMEVAL FUNCTION RECUSIVELY, ! AFTER THE OCCURENCE OF AN ERROR ! DEFAULT IS TRUE - RETURN TO TOP LEVEL ! ! ! ! WORD AREA ! ! WORDS (EXCLUDING NUMBERS) ARE HELD UNIQUELY IN STRING ARRAY WA ! AND ARE REPRESENTED BY AN INTEGER CARRYING THE WORD MARKER AND THE ! INDEX IN WA. ! NUMBERS ARE REPRESENTED BY AN INTEGER CARRYING THE ! BINARY VALUE OF THE NUMBER IN THE TOP THREE BYTES AND THE ! NUMBER MARKER IN THE BOTTOM BYTE. ! FUNCTION PUT IS USED TO TRANSFORM WORDS INCLUDING NUMBERS ! TO INTERNAL FORM. IF THE WORD IS A NUMBER IT IS CONVERTED TO ! BINARY OTHERWISE IT IS HASHED. ! FUNCTION HASH PLACES A WORD INTO WA. AN OPEN HASH IS USED STARTING ! WITH A KEY GENERATD BY FUNCTION HASHFUN. THE KEY IS INCREMENTED ! WHEN NECESSARY BY 1, IN ORDER TO KEEP THE SEARCH AREA TO A PAGE ! OR SO. ! ! ! ! FILING SYSTEM VARIABLES ! own integer tty = 0, disc = 1, srce = 2 integer device, index, newfn, cactfile, flen, filstart, tstart, sindex integer mdp, mdind, udp, txtp string (64) userfile string (20) maswrite, masread, masfile const string (7) masnum = "ECMI05." own string (8) array sysfiles(1 : 2) = "LOGALERT", "EXEC26" string (6) owner byte integer name mdents, tmdents, udents, tudents byte integer name mdnext, tmdnext, udnext, tudnext byte integer name txtnext, ttxtnext, endtxt, tendtxt byte integer array name txtents, ttxtents, endind, tendind string array name udnam, tudnam, funnam, tfunnam byte integer array name txtind, ttxtind byte integer array name fntxt, tfntxt, udpage, tudpage, txtpage, ttxtpage string (64) array format df(1 : 62) string (64) array format ff(1 : 60) byte integer array format xf(1 : 60) byte integer array format pf(1 : 62) byte integer array format sf(1 : 2) byte integer array format nf(1 : 2, 1:60) byte integer array format tf(0 : 4092) ! ! ! ! SPECIAL OUTPUT DEVICE VARS ! integer tdev ! DEVICE NUMBER ALLOCATED ELSE 0 own string (10) C array tdevnames(1 : 8) = "PLOTTERA", "PLOTTERB", "DISPLAY", "TURTLE", C "TAPE", "MUSIC", "MECCANO", "GT42" real xturtle, yturtle integer hdturtle, penturtle ! TURTLE STATE own integer hootbit = X'8080', penbit = X'4000', fdbits = X'2800', C bdbits = X'1800', rtbits = X'3800', ltbits = X'800', C pindlbit = X'1000', pindrbit = X'4000' integer name up, down ! UP DOWN AS LOGO WORDS TO SET PENTURTLE byte integer array binbuff(0 : 13) ! BUFFER FOR BINARY OUTPUT integer addrbinbuff ! ADDRESS PF BINBUFF(1) ! ! PARSE DECLARATIONS ! const integer qu = X'10', dts = X'20', fnm = X'40', lp = X'80', C markermask = X'FFFFFF0F', intr = -1, fault = -2 ! ! ! CODE INSERTED TO MONITOR HASHFN ! LOGO COMMAND HASHINFO ! integer array hashinfo(0 : 1022) integer hash1023, hash1024 ! ! HASHINFO IS PARALLEL TO WA ! HASH1023 HOLDS TOTAL NO OF ACCESSES OF WA ! HASH1024 HOLDS TOTAL NO OF WORDS HASHED ! integer fn hash(string (64) word) integer wpoint, fullmark, hash string (64) w ! integer fn hashfun work1 = space4 ! FIRST FOUR CHARS OF WORD USED. FILL WITH SPACES work1 = word ! IN CASE ACTUAL WORD LESS THAN FOUR result = hashval - 1023 * (hashval // 1023) ! HASHVAL IS EQUIVALENCED TO FIRST FOUR CHARS OF WORK1 IN INITIALISE end ! END HASHFUN ! fullmark = 0 ! USED TO TELL IF TABLE FULL wpoint = hashfun ! GENERATE KEY hash = wpoint lp: w = wa(wpoint) ! RETRIEVE WORD AT KEY hash1023 = hash1023 + 1 if w = "?" then start ! NOT YET USED SO wa(wpoint) = word ! PLACE WORD hashinfo(wpoint) = hash hash1024 = hash1024 + 1 result = wpoint << 8 ! wm ! AND RETURN INDEX finish if w = word then start hash1024 = hash1024 + 1 result = wpoint << 8 ! wm ! ALREADY ENTERED finish wpoint = wpoint + 1 ! NOT AT KEY POSITION SO INCREMENT if wpoint > 1022 then start ! TAKE MODULO AND CHECK FOR WA FUL if fullmark = 1 then baderror("WORD AREA OVERFLOW", empty) else C start fullmark = 1 wpoint = 0 finish finish -> lp end ! END HASH ! integer fn put(string (64) word) ! WORD IS A STRING OF ALPHANUMERIC CHARS ONLY ! IF THEY ARE ALL NUMERIC,THE STRING IS CONVERTED TO A NUMBER ! OTHERWISE THE WORD IS HASHED. ! A NEGATIVE NUMBER IN STRING FORM SHOULD NOT EXIST IN THE ! SYSTEM, BUT IN ANY CASE WOULD NOT BE CONVERTED TO A NUMBER HERE. integer num, i, j, char, toolong byte integer array strbyte(0 : 64) string(addr(strbyte(0))) = word i = strbyte(0) if i > 7 then toolong = 1 else toolong = 0 num = 0 j = 1 if word = "" then result = hash(word) while i > 0 cycle char = strbyte(i) if 47 < char < 58 then start if toolong = 1 then start i = i - 1 num = numtop + 1 finish else start num = num + (char - 48) * j j = j * 10 i = i - 1 finish finish else result = hash(word) repeat if num > numtop then start prstring("NUMBER OUTSIDE RANGE.") space prstring("MAX. SUBSTITUTED") nooline(1) num = numtop finish result = num << 8 ! nm end ! END PUT ! ! ! ! SERVICE ROUTINES ! string (64) fn numtostr(integer num) ! NUM WILL ALWAYS BE POSITIVE NUMBER IN STANDARD FORM AND IN ! RANGE. IT IS CONVERTED TO A STRING BUT IS NOT HASHED SICE ! THIS CONVERSION WILL ONLY BE CARRIED OUT BY CHAR FUNS PRIOR ! TO A CHAR MANIPULATION WHOSE RESULT WILL BE HASHED own integer array tens(1 : 7) = C 1000000, 100000, 10000, 1000, 100, 10, 1 integer i, j, k, l, wind, mark byte integer array word(0 : 64) wind = 1 mark = 0 num = num >> 8 cycle i = 1, 1, 7 j = tens(i) k = j l = 0 while num >= k cycle k = k + j l = l + 1 mark = 1 repeat num = num - k + j if mark = 1 then start word(wind) = l + 48 wind = wind + 1 finish repeat if wind = 1 then start ! NUMBER WAS ZERO word(wind) = 48 wind = 2 finish word(0) = wind - 1 result = string(addr(word(0))) end ! END NUMTOSTR ! routine cluserfl !DISCONNECTS CURRENT FILE closesm(4) clear("4") disconnect(masfile) end ! END CLUSERFL ! routine getmaster ! CONNECTS MASTER FILE define("4,LOGOFILE") filstart = smaddr(4, flen) end ! END GETMASTER ! routine freemaster ! DISCONNECTS MASTER FILE IN WRITE AND RECONNECTS IN READ closesm(4) permit(masread) unless cactfile = 2 then getmaster end ! END FREEMASTER ! integer fn status(string (15) filename, integer level) ! FINDS CONNECT STATUS OF FILENAME record (f) r integer flag, res finfo("NOFILE", 0, r, flag) finfo(filename, level, r, flag) if flag > 0 then result = -flag res = r_mode if r_cons = 0 then result = 0 result = res end ! END STATUS ! ! routine spec printfnline(integer name sptr) routine baderror(string (80) errmess, integer culprit) integer funlist, fun, ptr real fail17 if tdev = 8 then set42(chtxt) nooline(1) prstring(errmess) space printel(culprit) nooline(1) dump(errmess) restart = 1 ! FOR REINIT prstring("SAVING NEW FUNCTIONS IN TEMPORARY FILE") nooline(1) define("3,T#TEMP") selectoutput(3) device = tty funlist = newfn while funlist # nil cycle ptr = fntext(hd(funlist) >> 8) until source(fun) = 'E' and source(fun + 1) = 'N' C and source(fun + 2) = 'D' cycle fun = ptr printfnline(ptr) repeat funlist = tl(funlist) repeat prstring("GETTY") nooline(1) selectoutput(0) prstring("SAVED") nooline(1) closestream(3) cluserfl closesm(6) clear("6") destroy("T#LOGOSTK") fail17 = 1.0 / 0 ! FAILS FAULT17 end ! END BADERROR ! integer fn time100 long real x x = cputime result = int(cputime * 100) end ! END TIME100 ! ! ! ! FILING SYSTEM MAPPING ROUTINES ! routine mdmap(integer mdstart) ! MAPS A PAGE IN MASTER DIRECTOR FORMAT mdents == byteinteger(mdstart + 1) mdnext == byteinteger(mdstart + 3) udnam == array(mdstart + 4, df) udpage == array(mdstart + 4034, pf) end ! END MDMAP ! routine tmdmap(integer start) tmdents == byteinteger(start + 1) tmdnext == byteinteger(start + 3) tudnam == array(start + 4, df) tudpage == array(start + 4034, pf) end !END TMDMAP ! routine udmap(integer udstart) ! MAPS A PAGE IN USER DIRECTORY FORMAT udents == byteinteger(udstart + 5) udnext == byteinteger(udstart + 7) funnam == array(udstart + 8, ff) txtpage == array(udstart + 3908, xf) txtind == array(udstart + 3968, nf) end !END UDMAP ! routine tudmap(integer start) tudents == byteinteger(start + 5) tudnext == byteinteger(start + 7) tfunnam == array(start + 8, ff) ttxtpage == array(start + 3908, xf) ttxtind == array(start + 3968, nf) end ! END TUDMAP ! routine txtmap(integer txtstart) ! MAPS A PAGE IN TEXT FORMAT txtents == array(txtstart, sf) txtnext == byteinteger(txtstart + 3) fntxt == array(txtstart + 3, tf) end !END TXTMAP ! ! routine ttxtmap(integer start) ttxtents == array(start, sf) ttxtnext == byteinteger(start + 3) tfntxt == array(start + 3, tf) end ! routine endmap ! MAPS LAST TEXT PAGE POINTERS endtxt == byteinteger(filstart + 4097) endind == array(filstart + 4098, sf) end ! END ENDMAP ! routine tendmap tendtxt == byteinteger(tstart + 4097) tendind == array(tstart + 4098, sf) end !END TENDMAP ! integer fn shortint(byte integer name index) ! RETURNS INTEGER VALUE HELD IN 2 BYTE ARRAY, INDEX result = index << 8 ! byteinteger(addr(index) + 1) end ! END SHORTINT ! routine setshortint(byte integer name name, integer value) ! PUTS VALUE INTO 2 BYTE ARRAY, NAME name = value >> 8 byteinteger(addr(name) + 1) = value & X'FF' end ! END SETSHORTINT ! routine mapend ! MAPS LASR TEXT PAGE txtp = endtxt unless txtp = 0 then txtmap(filstart + txtp * 4096) if txtp = 0 or shortint(endind(1)) = 4093 then start getpage(4) endtxt = txtp endind(1) = 0 endind(2) = 1 finish index = shortint(endind(1)) end !END MAPEND ! routine getudp udp = udpage(mdind) udmap(filstart + udp * 4096) end ! routine gettxtp(integer ind) txtp = txtpage(ind) txtmap(filstart + txtp * 4096) end ! ! ! ! LIST AREA AND LISTPRO PRIMITIVES ! ! LIST STRUCTURE IS HELD IN INTEGER ARRAY LA. A LIST IS REPRESENTED ! BY TWO ADJACENT ELEMENTS OF LA - THE FIRST POINTING TO THE HEAD ! THE SECOND POINTING TO THE TAIL. EACH ELEMENT CARRIES A MARKER ! IDENTIFYING IT AS A LIST ,A WORD OR A NUMBER. ! THE NULL LIST IS REPRESENTED BY A POINTER TO THE WORD "NIL" ! IN THE WORD AREA. ! ABSOLUTE POINTERS ARE USED IN LA AND ARE THUS ALWAYS POSITIVE, ! A LIST IS ADDRESSED BY AN INTEGER CARRYING A LIST MARKER AND A ! POINTER TO ITS FIRST LA ELEMENT - I.E. ITS HEAD. ! ! integer fn hd(integer list) ! RETRIIEVES HEAD OF LIST if list & lm = 0 or list = nil C then baderror("NON-LIST ARG FOR HEAD - ", list) result = la(list >> 8) end ! END HD ! routine rephead(integer list, newhead) ! UPDATES HEAD OF LIST if list & lm = 0 or list = nil C then baderror("NON-LIST ARG FOR REPHEAD", list) la(list >> 8) = newhead end ! END REPHEAD ! integer fn tl(integer list) ! RETRIEVES TAIL OF LIST if list & lm = 0 or list = nil C then baderror("NON-LIST ARG FOR TAIL - ", list) result = la(list >> 8 + 1) end ! END TL ! routine reptail(integer list, newtail) if list & lm = 0 or list = nil C then baderror("NONLIST FIRST ARG FOR REPTAIL - ", list) if newtail & lm = 0 C then baderror("NON-LIST SECOND ARG FOR REPTAIL - ", newtail) la(list >> 8 + 1) = newtail end ! END REPTAIL ! integer fn cons(integer x, list) ! CONSTRUCTS LIST WITH HEAD X integer i ! AND TAIL LIST i = lpoint if list & lm = 0 then baderror("NON-LIST SECOND ARG FOR CONS - ", list) la(lpoint) = x la(lpoint + 1) = list lpoint = lpoint + 2 if (lpoint - labase) > cfract * semisize then clectflg = 1 ! SET COLLECT FLAG result = i << 8 ! lm end ! END CONS ! integer fn cons1(integer x, list) ! CONS1 COSTRUCTS LIST WITH HEAD X AND TAIL LIST IN UNCOLLECTABLE SPACE ! I.E. FUNCTION SPACE. IT IS IDENTICAL TO CONS EXCEPT THAT ! IT USES LPOINT1 INSTEAD OF LPOINT AS THE FREE POINTER integer i i = lpoint1 if lpoint1 >= (lafnt - 1) then baderror("FNSPACE OVERFLOW", empty) if list & lm = 0 C then baderror("NON-LIST SECOND ARG FOR CONS1 - ", list) la(lpoint1) = x la(lpoint1 + 1) = list lpoint1 = lpoint1 + 2 result = i << 8 ! lm end ! END CONS1 ! integer fn consg(integer x, list) ! PATCH ROUTINE FOR ADDING STANDARD ! EMAS NUMBERS TO LISTS ! result = cons(x << 8 ! nm, list) end ! integer fn without(integer item, list) ! REMOVES "ITEM" FROM "LIST" ! ! result = nil if list = nil result = cons(hd(list), without(item, tl(list))) if item # hd(list) result = without(item, tl(list)) ! REMOVE ITEM end integer fn amongq(integer item, list) result = 0 if list = nil result = 1 if item = hd(list) result = amongq(item, tl(list)) end ! integer fn appendl(integer l1, l2) ! APPENDS L1 - L2 ! SIMILAR TO ! *1: SENTENCE :L1 :L2 ! WHERE L1 AND L2 ARE LISTS ! ! USED IN PICTURE FUNCTION "CUT" ! integer l3 l3 = nil ! CLEAR WORKSPACE l3 = cons(hd(l1), l3) and l1 = tl(l1) while l1 # nil !REVERSECOPYL1INTOL3 l2 = cons(hd(l3), l2) and l3 = tl(l3) while l3 # nil !ANDSTICKONFRONTOFL2 result = l2 end ! integer fn fromlist(integer item, list) integer newlist if hd(list) = item then result = tl(list) newlist = list while tl(newlist) # nil cycle if hd(tl(newlist)) = item then start reptail(newlist, tl(tl(newlist))) ! ALTERS LIST result = list finish newlist = tl(newlist) repeat result = list end ! END OF FROMLIST ! ! ! ! ! GARBAGE COLLECTOR ! ! COLLECTION IS CARRIED OUT IF REQUIRED ON ENTRY TO EVAL ! WHEN MOST USER LIST STRUCTURE IS REFERENCED FROM THE USER STACK OR ! FROM THE ENVIRONMENT. WHERE NECESSARY, LIST REFERENCES FROM LOCAL ! IMP VARIABLES ARE TRANSFERRED TO THE SYSTEM STACK. ! COLLECTION INVOLVES ALTERING LABASE TO POINT TO THE BASE OF THE NEW ! SEMISPACEAND COPYING ALL ACTIVE LIST STRUCTURE TO THAT SEMISPACE. ! routine collect(integer envir) integer name freepointer integer staddr, len integer i, item, usedbefore, usedafter, collected ! integer fn gencopy(integer list) ! COPIES LIST STRUCTURE AS IS,INCLUDING CIRCULAR/BLAM LISTS. ! IT ALTERS THE STRUCTURE IT IS COPYING FROM AND SO MAY ONLY BE ! USED WITHIN THE GARBAGE COLLECTOR . integer newlist, head, tail if list & lm # lm or list = nil or (list >> 8) >= lafnb then C result = list ! WORD,NUMBER OR LIST IN UNCOLLECTABLE SPACE if hd(list) = -1 then result = tl(list) ! ALREADY COPIED head = hd(list) tail = tl(list) newlist = cons(nil, nil) ! SPACE FOR COPY IN NEW SEMISPACE rephead(list, -1) ! INSERT COPY MARKER reptail(list, newlist) ! INSERT ADDR OF COPY IN TAIL reptail(newlist, gencopy(tail)) rephead(newlist, gencopy(head)) result = newlist end ! END GENCOPY ! usedbefore = lpoint - labase if labase = la1b then labase = la2b else labase = la1b ! FLIP SEMISPACE lpoint = labase ! CONS NOW WORKS IN NEW SEMISPACE cycle i = 0, 1, basenvir item = bvalue(i) if item # 0 then bvalue(i) = gencopy(item) item = assocwa(i) if item # nil then assocwa(i) = gencopy(item) repeat if envir > basenvir then start cycle i = basenvir, 1, envir bvalue(i) = gencopy(bvalue(i)) repeat finish if stkpnt > 0 then start cycle i = 1, 1, stkpnt stk(i) = gencopy(stk(i)) repeat finish if systkpnt > 0 then start cycle i = 1, 1, systkpnt systk(i) = gencopy(systk(i)) repeat finish newfn = gencopy(newfn) ! COLLECT PICTURE LIST AREA NOW cycle i = 0, 1, 1022 if index42(i)_ptr # 0 then index42(i)_ptr = gencopy(index42(i)_ptr) repeat curpic = gencopy(curpic) curframe = gencopy(curframe) curmovie = gencopy(curmovie) ! usedafter = lpoint - labase if status(masnum . "LOGOMON", 0) >= 0 then start define("7," . masnum . "LOGOMON") staddr = smaddr(7, len) freepointer == integer(staddr) if freepointer + 48 > len then -> close staddr = staddr + freepointer freepointer = freepointer + 48 string(staddr) = time . date string(staddr + 19) = emasuser integer(staddr + 28) = usedbefore integer(staddr + 32) = envir - basenvir integer(staddr + 36) = stkpnt integer(staddr + 40) = systkpnt integer(staddr + 44) = usedafter close: closesm(7) clear("7") disconnect(masnum . "LOGOMON") finish clectflg = 0 collected = usedbefore - usedafter if collected < 100 C then baderror("TOO FEW LIST CELLS COLLECTED", collected << 8 ! nm) end ! END COLLECT ! integer fn copy(integer list) ! USED TO COPY FROM UNCOLLECTABEL(FNSPACE) TO COLLECTABLE SPACE integer mark mark = list & X'F0' if list & lm # lm or list & markermask = nil then result = list result = cons(copy(hd(list)), copy(tl(list))) ! mark end ! END COPY ! integer fn move1(integer list) ! MOVE1 IS USED TO COPY LIST STRUCTURE CREATED BY THE READER IN ! COLLECTABLE SPACE TO UNCOLLECTABLE SPACE. NO CIRCULAR/BLAM LISTS ! integer fn copy1(integer list) integer mark mark = list & X'F0' if list & lm # lm or list & markermask = nil then result = list result = cons1(copy1(hd(list)), copy1(tl(list))) ! mark end ! END COPY1 ! if list & lm # lm then baderror("NON-LIST ARG FOR MOVE1 - ", list) if (list >> 8) >= lafnb then result = list ! ALREADY IN FNSPACE result = copy1(list) end ! END MOVE ! integer fn reverse(integer list) integer list1 list1 = nil while list & markermask # nil cycle list1 = cons(hd(list), list1) list = tl(list) repeat result = list1 end ! END REVERSE ! integer fn reverse1(integer list) integer list1 list1 = nil while list & markermask # nil cycle list1 = cons1(hd(list), list1) list = tl(list) repeat result = list1 end ! OF REVERSE1 ! ! ! ! ENVIRONMENT ! ! VARIABLE BINDINGS ARE HELD AS (NAME,VALUE) PAIRS IN ARRAYS ! BNAME AND BVALUE. THE CURRENT ENVIRONMENT IS DEFINED BY ENVIR ! WHICH POINTS TO THE TOP OF THE LAST ENVIRONMEBT CREATED, ! OR IS EQUAL TO 1022 IF ONLY THE BASE ENVIRONMENT EXISTS. ! WHENEVER A LOGO FUN IS APPLIED, THE PARAMETER NAMES AND LOCAL ! NAMES ARE INSERTED IN A NEWLY CREATED ENVIRONMENT TOGETHER WITH ! A SINGLE DIAGNOSTIC RECORD (THE FIRST) WHICH HAS 0 AS ITS NAME ! COMPONENT. ! SUCH LOCAL ENVIRONMENTS ARE CREATED UPWARDS FROM 1023. ! BVALUE(0-1022) IS USED FOR THE BASE ENVIRONMENT VALUES. ! THIS PART OF BVALUE IS PARALLEL TO WA AND IS ACCESSED ! BY DIRECT APPLICATION OF THE WORD INDEX. ! BASENVIR IS USED TO REFER TO THE BASE ENVIR ! VARIABLE UNDEF CONTAINS A POINTER TO THE WORD "UNDEF" IN THE WORD ! AREA. ! FUNCTION UNSTACK RETREIVES THE TOP ELEMENT FROM THE LOGO STACK. ! VARIABLE NIL POINTS TO THE EMPTY LIST-THE WORD "NIL". ! VARIABLE DOTS POINTS TO THE WORD ':'. ! ! integer fn findbind(integer name, envir) ! FINDS A BINDING IN AN ENVIRONMENT. IF CALLED WITH ENVIR<=1022,ONLY ! THE GLOBAL ENVIRONMENT IS INTERROGATED. local: while envir > 1022 cycle if bname(envir) = 0 then start ! SKIP DIAGNOSTIC RECORD AT START envir = envir - 1 -> local finish if bname(envir) = name then result = envir ! FOUND IT envir = envir - 1 repeat name = name >> 8 ! NOT LOCAL SO TRY GLOBAL if bvalue(name) = 0 then result = undef else result = name end ! END FINDBIND ! routine setval(integer name, value, envir) ! UPDATES A BINDING IF ONE EXISTS,OTHERWISE CREATES A NEW GLOBAL BINDING integer binding binding = findbind(name, envir) if binding = undef then start ! NOT YET DEFINED bvalue(name >> 8) = value ! SO CREATE IT GLOBALLY finish else bvalue(binding) = value ! ALREADY DEFINED SO UPDATE IT end ! END SETVAL ! integer fn getval(integer name, envir) ! RETRIEVES A BINDING integer binding binding = findbind(name, envir) if binding = undef then result = undef else result = bvalue(binding) end ! END GETVAL ! integer fn setbind(integer parmlist, envir) ! BINDS PARMATER NAMES AND ARGS IN NEW ENVIRONMENT ! PARAMETER NAMES ARE IN PARMLIST IN ORDER. ! ARG VALUES ARE ON STACK while parmlist # nil cycle if envir = 3000 then baderror("ENVIRONMENT OVERFLOW", empty) envir = envir + 1 bname(envir) = hd(parmlist) if checkstack = fault then result = fault bvalue(envir) = unstack parmlist = tl(parmlist) repeat if envir > topmark then topmark = envir ! TOPMARK USED BY DUMP result = envir end ! END SETBIND ! integer fn makebind(integer parmlist, envir, fname) ! MAKEBIND CREATES NEW LOCAL ENVIRONMENT INSERTING DIAGNOSTIC ! RECORD AND BINDING PARAMETERS if envir = 3000 then baderror("ENVIRONMENT OVERFLOW", empty) envir = envir + 1 bname(envir) = 0 ! DIAGNOSTIC RECORD bvalue(envir) = fname result = setbind(parmlist, envir) end ! END MAKEBIND ! ! ! ! USER STACK MANIPULATION ! integer fn unstack if stkpnt = 0 then baderror("STACK UNDERFLOW", empty) stkpnt = stkpnt - 1 result = stk(stkpnt + 1) end ! END UNSTACK ! routine stack(integer i) if stkpnt = 2000 then baderror("STACK OVERFLOW", empty) stkpnt = stkpnt + 1 stk(stkpnt) = i end ! END STACK; ! integer fn checkstack if stkpnt = 0 then result = fault result = 0 end ! ! ! SYSTEM STACK ! USED TO MAKE REFS TO COLLECTABLE LIST STRUCTURE FROM IMP LOCALS ! AVAILABLE TO THE COLLECTOR. ! integer fn unstksys if systkpnt = 0 then baderror("SYSTACK UNDERFLOW", empty) systkpnt = systkpnt - 1 result = systk(systkpnt + 1) end ! END UNSTKSYS ! routine stksys(integer i) if systkpnt = 2000 then baderror("SYSTACK OVERFLOW", empty) systkpnt = systkpnt + 1 systk(systkpnt) = i end ! END STKSYS ! ! ! ! SYSTEM INPUT/OUTPUT ! ! ALL SYSTEM INPUT IS IN THE FORM OF A LIST WITH OUTERMOST ! BRACKETS IMPLICIT. SPACES AND NOOLINE AT START OF INPUT ARE ! DISCARDED OTHERWISE THEY SERVE TO DELIMIT WORDS. THE LIST IS ! TERMINATED WITH A SEMI COLON ! AT LEVEL 1 (IE USER LEVEL ZERO),THE MINUS CHAR IS LEFT ! AS A SEPARATE WORD. AT ANY OTHER LEVEL IT IS ASSUMED TO BE ! THE UNARY MINUS AND MUST BE FOLLOWED BY A NUMBER. THE NUMBER ! IS THEN CONVERTED TO BINARY AND NEGATED. ! ! routine chkind(integer name index) ! CHECKS INDEX FOR READ ROUTINES if index > shortint(txtents(1)) then start if txtnext = 0 then start baderror("NEXT TEXT PAGE NOT INDICATED", empty) finish txtp = txtnext txtmap(filstart + txtp * 4096) index = 1 finish end !END CHKIND ! ! ! INPUT ROUTINES -- READ SYMBOL FROM INPUT BUFFER ! INPTR IS A POINTER TO CURRENT POSITION IN LINE ! routine lgreadsym(integer name sym) ! READ SYMBOL FROM INPUT BUFFER sym = inbuff(inptr) inptr = inptr + 1 return end ! END LGREAD SYM ! integer fn lgnextsym ! NEXT SYMBOL FROM INPUT BUFFER result = inbuff(inptr) end ! END LGNEXT SYM ! routine lgskipsym ! SKIP SYMBOL IN INPUT BUFFER inptr = inptr + 1 return end ! END LGSKIP SYM ! routine lgreaditem(string name item) ! READ ITEM FROM INPUT BUFFER item = tostring(inbuff(inptr)) inptr = inptr + 1 return end !END LGREAD ITEM ! ! integer fn getitem ! ! READ NEXT LOGO ITEM FROM INPUT BUFFER ! integer sym, skipmark string (2) item string (64) word integer symcount symcount = 0 word = "" skipmark = 0 if quoteon = 1 and (lgnextsym < "0" or "9" < lgnextsym < "A" C or lgnextsym > "Z") then result = empty lp: if lgnextsym = " " then start lgskipsym if symcount = 0 then -> lp else start if skipmark = 1 then nooline(1) result = put(word) finish finish if lgnextsym = '@' then start if symcount = 0 then start lgskipsym ! SKIP @ lgskipsym if lgnextsym = nl ! SKIP NL -> lp finish else start if skipmark = 1 then nooline(1) result = put(word) finish finish if lgnextsym = termin then start ! TERMIN=NL if symcount = 0 then start if level > blevel or parlevel > blevel then start prstring("MISSING RIGHT BRACKET INSERTED") nooline(1) finish level = blevel parlevel = blevel result = rbrak finish else start if skipmark = 1 then nooline(1) result = put(word) finish finish if lgnextsym = lbrak or lgnextsym = rbrak then start if symcount = 0 then start lgreadsym(sym) if sym = lbrak then level = level + 1 else level = level - 1 result = sym finish else start if skipmark = 1 then nooline(1) result = put(word) finish finish if lgnextsym = '-' and level # 1 then start if symcount = 0 then start lgskipsym sym = getitem if sym & nm = 0 then start prstring("INVALID '-' BEFORE ") printel(sym) space prstring("IGNORED") nooline(1) finish else start result = (-sym >> 8) << 8 ! nm finish finish else start if skipmark = 1 then nooline(1) result = put(word) finish finish if lgnextsym < 48 or (lgnextsym > 57 and lgnextsym < 65) C or lgnextsym > 90 then start if symcount = 0 then start lgreaditem(item) if (item = "<" or item = ">") and lgnextsym = '=' then start item = item . "=" lgskipsym finish if item = "<" and lgnextsym = '<' then start item = "<<" lgskipsym finish if item = ">" and lgnextsym = '>' then start item = ">>" lgskipsym finish result = put(item) finish else start if skipmark = 1 then nooline(1) result = put(word) finish finish lgreaditem(item) if symcount = 64 then start if skipmark = 1 then prstring(item) else start skipmark = 1 prstring("EXCESS CHARS IGNORED - ") prstring(item) finish finish else start word = word . item symcount = symcount + 1 finish -> lp end ! END GETITEM ! ! INPUT BUFFER IS THOUGHT OF AS A LIST. ! HEADIN IS THE HEAD OF THE LIST ! TAILIN CAUSES HEADIN TO BE UPDATED TO NEXT ITEM ON LIST ! UNUSEDHD IS A FLAG USED BY PARSE ROUTINES TO CHECK ! WHETHER THE HEAD OF THE INPUT LIST HAS BEEN PROCESSED ! routine tailin headin = getitem unusedhd = 0 end ! OF TAILIN ! ! ! INPUT ROUTINES FROM CURRENT INPUT STREAM ! THIS IS EITHER .TT, SOURCETEXT, FILESTORE ! routine readinsym(integer name sym) ! LOGO READ SYMBOL if device = tty then readsymbol(sym) else start if device = srce then start sym = source(sindex) sindex = sindex + 1 finish else start chkind(index) sym = fntxt(index) index = index + 1 finish finish end ! END OF READ IN SYM ! integer fn nextinsym ! LOGO NEXT SYMBOL if device = tty then result = nextsymbol if device = srce then result = source(sindex) chkind(index) result = fntxt(index) end ! END OF NEXT IN SYM ! routine skipinsym ! LOGO SKIP SYMBOL if device = tty then skipsymbol and return if device = srce then sindex = sindex + 1 else index = index + 1 end ! END OF SKIP IN SYMBOL ! routine readinline(string (15) promp) ! ! READ A LINE FROM CURRENT INPUT STREAM TO INPUT BUFFER ! integer ptr, sym level = blevel parlevel = blevel prompt(promp) ptr = 1 skipinsym while nextinsym = nl until nextinsym = nl cycle if ptr >= 255 then start prstring("LINE TOO LONG") nooline(1) exit finish readinsym(sym) inbuff(ptr) = sym ptr = ptr + 1 if sym = '@' then start while nextinsym # nl cycle skipinsym repeat if ptr >= 255 then start prstring("LINE TOO LONG") nooline(1) exit finish readinsym(sym) inbuff(ptr) = sym ptr = ptr + 1 prompt("C:") finish repeat inbuff(ptr) = nl prompt(promp) inbuff(0) = ptr inptr = 1 headin = getitem unusedhd = 0 if headin = rbrak then readinline(promp) end ! END OF READ LINE ! ! routine copyline ! ! COPY A LINE FROM INPUT BUFFER INTO SOURCE TEXT FILE ! if sourceptr + inbuff(0) > maxsource C then baderror("FILE SOURCE SPACE OVERFLOW", empty) move(inbuff(0), addr(inbuff(1)), addr(source(sourceptr))) sourceptr = sourceptr + inbuff(0) end ! ! integer fn readlist ! ! READ A LIST FROM INPUT BUFFER ! RESULT IS HEAD OF LIST ! integer thispoint, item thispoint = lpoint item = headin tailin !%IF ITEM=QUOTE %THEN QUOTEON=1 %ELSE QUOTEON=0 if item = rbrak then start unusedhd = 1 result = nil finish else start lpoint = lpoint + 2 if (lpoint - labase) > cfract * semisize then clectflg = 1 ! SET FLAG FOR COLLECT if item = lbrak then start la(thispoint) = readlist finish else la(thispoint) = item la(thispoint + 1) = readlist result = thispoint << 8 ! lm finish end ! OF READLIST ! ! integer fn readline blevel = 1 readinline(promp) result = readlist end ! END READLINE ! routine getpage(integer flag) ! GETS A NEW PAGE ! FLAG 1 - NEW MASTER DIRECTORY PAGE ! FLAG 2 - NEW USER DIRECTORY PAGE ! FLAG 4 - NEW TEXT PAGE ! FLAGS MAY BE COMBINED string (10) size integer len, i, j, k i = (flag & 1) + ((flag & 2) // 2) + ((flag & 4) // 4) size = numtostr((flen + 4096 * i) << 8) define("10,T#JUNK") newsmfile("T#JUNK," . size) tstart = smaddr(10, len) cycle i = 0, 4096, flen - 4096 ! COPY OLD FILE TO NEW FILE j = filstart + i k = tstart + i move(4096, j, k) repeat closesm(10) clear("10") closesm(4) clear("4") destroy(masfile) rename("T#JUNK," . masfile) cherish(masfile) permit(masfile . ",,R") permit(maswrite) getmaster mdmap(filstart + mdp * 4096) if flag = 4 then start endmap unless txtp = 0 then txtmap(filstart + txtp * 4096) C and txtnext = len // 4096 - 1 txtp = len // 4096 - 1 txtmap(filstart + txtp * 4096) txtents(1) = 0 txtents(2) = 0 index = 1 txtnext = 0 finish else start if flag = 3 then start mdents = 63 mdnext = len // 4096 - 2 mdp = mdnext mdmap(filstart + mdp * 4096) mdents = 0 finish unless udp = 0 then start udmap(filstart + udp * 4096) udents = 61 udnext = len // 4096 - 1 finish udp = len // 4096 - 1 udmap(filstart + udp * 4096) udents = 0 endmap if udp = 1 then endtxt = 0 and setshortint(endind(1), 1) finish end ! END GETPAGE ! routine nooline(integer n) while n > 0 cycle newline n = n - 1 repeat charout = 0 end ! END NOOLINE ! routine prstring(string (255) word) integer n n = length(word) if (charout + n) > 72 then start newline if word -> (" ") . word then n = n - 1 spaces(3) printstring(word) charout = n + 3 finish else start printstring(word) charout = charout + n finish end ! END PRSTRING ! routine lgprntstr(string (64) word) integer save, newind if device = tty then prstring(word) and return if device = srce then start save = source(sourceptr - 1) string(addr(source(sourceptr - 1))) = word newind = sourceptr + source(sourceptr - 1) source(sourceptr - 1) = save sourceptr = newind finish !%IF 4093-INDEX<LENGTH(WORD) %THEN GETPAGE(4) !SAVE=FNTXT(INDEX-1) !STRING(ADDR(FNTXT(INDEX-1)))=WORD !NEWIND=INDEX+FNTXT(INDEX-1) !FNTXT(INDEX-1)=SAVE !INDEX=NEWIND !TXTENTS=INDEX-1 end ! END LGPRNT STR ! routine lgnewline if device = tty then nooline(1) else lgprntstr(stermin) end ! END LGNEWLINE ! routine printword(string (64) word) if word = "]" or word = ")" then start lgprntstr(word) sep = " " return finish if word = "(" or word = "[" or word = """" or word = ":" then start lgprntstr(sep . word) sep = "" return finish if word = "+" or word = "-" or word = "*" or word = "/" C or word = "<" or word = "<=" or word = ">" or word = ">=" C or word = "=" then start lgprntstr(word) sep = "" return finish lgprntstr(sep . word) sep = " " return end ! END PRINTWORD ! routine printwn(integer i) string (64) word if i & nm = nm then start if i < 0 then word = "-" . numtostr(¬i + 256) C else word = " " . numtostr(i) finish else word = wa((i >> 8) & X'FFFF') printword(word) end ! END PRINTWN ! routine printlcon(integer list) integer i lp: if enuf = 1 or (interrupt = "ENUF" and device = tty) then start enuf = 1 return finish if list = nil then return i = hd(list) if i & lm = lm then printlist(i) else printwn(i) list = tl(list) -> lp end ! END PRINTLCON ! routine printlist(integer list) sep = "" printword("[") printlcon(list) printword("]") end ! END PRINTLIST ! routine printel(integer i) integer j enuf = 0 sep = "" cycle j = 1, 1, 14 if spechar(j) = i then -> spchar repeat if i & lm = lm then printlist(i) else printwn(i) return spchar: printword(tostring(i)) end ! END PRINTEL ! routine printline(integer line) integer head sep = "" if line = nil then start enuf = 0 printlist(nil) finish while line # nil cycle head = hd(line) if head & lm = lm then start enuf = 0 printlist(head) finish else printwn(head) line = tl(line) repeat lgnewline end ! END PRINTLINE ! routine printfnline(integer name sptr) integer sym, i, cont cont = 0 if device = tty then start cycle i = 0, 1, 255 sym = source(sptr + i) printsymbol(sym) if sym = '@' then start cycle sym = source(sptr + i + 1) if sym = nl then exit printsymbol(sym) sptr = sptr + 1 repeat cont = 1 finish else start if sym = nl then start exit unless cont = 1 cont = 0 finish finish repeat finish else start cycle i = 0, 1, 255 if index = 4093 then setshortint(txtents(1), 4092) C and getpage(4) sym = source(sptr + i) fntxt(index) = sym index = index + 1 if sym = '@' then start while source(sptr + i + 1) # nl cycle sptr = sptr + 1 repeat cont = 1 finish if sym = nl then start exit unless cont = 1 cont = 0 finish repeat setshortint(txtents(1), index - 1) finish sptr = sptr + i + 1 if i = 255 then start prstring("LINE TOO LONG - TRUNCATED") if device = tty then printsymbol(nl) else fntxt(index - 1) = nl nooline(1) finish end ! END OF PRINTFNLINE ! routine printhex(byte integer i) const byte integer C array hex(0 : 15) = '0', '1', '2', '3', '4', '5', '6', '7', '8', C '9', 'A', 'B', 'C', 'D', 'E', 'F' integer cyc string (2) h h = "" cycle cyc = 0, 1, 1 h = tostring(hex((i >> (cyc * 4)) & 15)) . h repeat printstring(h) end ! ! ! ! INFERENCE SYSTEM ! routine setupinf bvalue(database >> 8) = nil bvalue(factkeys >> 8) = nil bvalue(imprules >> 8) = nil bvalue(impkeys >> 8) = nil bvalue(infrules >> 8) = nil bvalue(infkeys >> 8) = nil genos = 0 end ! END SETUPINF ! routine initinf dbase(1) = database implinks(1) = imprules inflinks(1) = infrules dbase(2) = fact implinks(2) = implies inflinks(2) = toinfer dbase(3) = factkeys implinks(3) = impkeys inflinks(3) = infkeys setupinf end ! END INITINF ! ! ! ! EVAL AND APPLY ! integer fn findlinenums(integer list) ! ! SEARCHES LINE NUMBER LIST IN USER PROCEDURE FOR THE NUMBER ! THAT IS AT TOP OF STACK ! integer num num = unstack while list # nil cycle if hd(hd(list)) = num then start goflag = 0 stack(num) result = tl(hd(list)) finish list = tl(list) repeat stack(num) result = 0 end ! ! ! integer fn spec checkfnhead(integer name name) routine spec parseerr(integer errmess, culprit) routine edit(integer name name) integer sstart, slen, wsp, lwsp, flag, userfun userfun = name >> 8 sstart = addr(source(fntext(userfun))) ! ADDR OF START OF USER TEXT slen = fnlen(userfun) ! LENGTH OF CURRENT TEXT wsp = addr(source(sourceptr)) ! ADDR OF START OF FREE SPACE lwsp = maxsource - sourceptr + 1 ! LENGTH OF AVAILABLE FREE SPACE prompt(">") edinner(sstart, slen, sstart, slen, wsp, lwsp) ! ENTER ECCE prompt(promp) ! RESET PROMPT fntext(userfun) = sourceptr ! STORE ADDR OF NEW DEFN fnlen(userfun) = lwsp sourceptr = sourceptr + lwsp if lwsp > 4 then start cycle wsp = 5, 1, lwsp if source(sourceptr - wsp) = nl then -> chend repeat finish chend: if source(sourceptr - wsp + 1) = 'E' C and source(sourceptr - wsp + 2) = 'N' C and source(sourceptr - wsp + 3) = 'D' then -> chfnhd insend: if sourceptr + 4 > maxsource C then baderror("SOURCE FILE SPACE OVERFLOW", empty) source(sourceptr) = 'E' source(sourceptr + 1) = 'N' source(sourceptr + 2) = 'D' source(sourceptr + 3) = nl sourceptr = sourceptr + 4 fnlen(userfun) = lwsp + 4 prstring("END INSERTED") nooline(1) chfnhd: flag = checkfnhead(name) ! CHECK NEW PROCEDURE HEADER if flag = fault then fnparse(name >> 8) = 255 end ! ! integer fn spec countargs integer fn checkfnhead(integer name userfun) integer fn, savedev, numargs, res, fnspec res = 0 numargs = 0 fnparse(userfun >> 8) = 0 fnval(userfun >> 8) = userpre savedev = device ! CHECK FIRST LINE device = srce sindex = fntext(userfun >> 8) readinline(promp) device = savedev if headin # to then start ! CHECK THAT DEFN STARTS WITH TO parseerr(-17, userfun) ! INVALID FN DEFN - TO MISSING res = fault -> exit finish tailin fn = headin if fn & wm # wm then start ! CHECK THAT NAME OF PROC IS A WORD parseerr(-14, fn) res = fault -> exit finish if fn # userfun then start ! NAME CHANGED newfn = fromlist(fn, newfn) unless newfn = nil fnspec = fnval(fn >> 8) ! GET SPEC unless fnspec = 0 or fnspec & userpre = userpre then start parseerr(-15, fn) res = fault -> exit finish if fntext(fn >> 8) # 0 C then oldfn(fn >> 8) = fnlen(fn >> 8) << 16 ! fntext(fn >> 8) fntext(fn >> 8) = fntext(userfun >> 8) fnlen(fn >> 8) = fnlen(userfun >> 8) fnparse(fn >> 8) = fnparse(userfun >> 8) fntext(userfun >> 8) = 0 fnlen(userfun >> 8) = 0 fnval(userfun >> 8) = 0 userfun = fn finish tailin numargs = countargs if numargs > 127 then start parseerr(-13, userfun) res = fault -> exit finish if numargs < 0 then res = fault and numargs = 0 exit: fnval(userfun >> 8) = userpre + numargs ! TEMP SPEC TO ALLOW RECURSIVE CALLS result = res end ! integer fn countargs ! ! COUNT NO OF ARGS IN A USER PROCEDURE. ! integer len len = 0 while headin # rbrak cycle -> errlab unless headin = quote tailin -> errlab if headin & wm # wm or headin = rbrak len = len + 1 tailin repeat result = len errlab: parseerr(-16, empty) result = fault end ! OF COUNTARGS ! ! ! ! routine parseerr(integer errmess, culprit) integer savedev, errnum const string (80) array message(1 : 22) = C "NAME MISSING AFTER : ", C "NON-WORD AFTER : - ", C "MISSING >> ", C "MISPLACED CLOSING BRACKET - ", C "MISPLACED INFIX FN ", C "THEN MISSING - ", C "THEN NOT FOUND - ", C "FINISH MISSING - ", C "NO NUMBER ON FN LINE - LINE IGNORED - ", C "ERROR IN FN TYPE ", C "UNDEFINED PROCEDURE ", C "NOT ENOUGH ARGS FOR - ", C "TOO MANY ARGS FOR ", C "TO MUST BE GIVEN A WORD AS PROCEDURE NAME - ", C "YOU CAN'T REDEFINE A SYSTEM PROCEDURE - ", C "INCORRECT FORMAT FOR ARGS ", C "INCORRECT FORMAT FOR FN DEFN - TO MISSING - ", C "RUN OUT OF FILE SPACE ", C "FN DEFN NOT AT OUTER LEVEL", C "LINE IGNORED - ", C "CONDITION CLAUSE MISSING", C "THEN CLAUSE MISSING" errnum = -errmess savedev = device device = tty prstring(message(errnum)) space printel(culprit) nooline(1) device = savedev end ! ! integer fn spec parseline(integer prec) routine evalappl(integer C name envir, fun, curfun, in, tstflg, val, severity) ! ! ENVIR IS THE CURRENT ENVIRONMENT POINTER - 1022 IF OUTSIDE A USER ! FUN AND ONLY BASE ENVIR EXISTS. ! FUN IS THE USER FUN WE ARE CURRENTLY IN - NIL IF OUTSIDE USER ! FUN ! CURFUN IS THE LINE OF THE USER FUN WE ARE CURRENTLY IN - NIL ! IF OUTSIDE USER FUN ! IN CONTAINS THE LINE WE ARE CURRENTLY EVALUATING EITHER FROM ! A USER FUN OR FROM THE TTY ! TSTFLG IS THE CURRENT TEST LOCATION USED BY TEST IFTRUE,ETC ! VAL IS THE LAST VALUE ! SEVERITY IS USED IN APPLYSYS TO TELL IF A CONTINUE ! IS POSSIBLE ! ! THESE PARAMETES ARE CREATED BY LOGO AT BASE LEVEL AND ARE ! RECREATED BY APPLYUSR ON EACH ENTRY TO USER FUN. ! THEY ARE USED FREE BY ROUTINE ERROR FOR DIAGNOSTIC PURPOSES ! AND BY APPLYSYS AND EVAL ! routine spec eval(integer in, integer name eachval) ! ! routine error(string (80) errmess, integer culprit, severity, C integer name in) integer savedev, txtptr if tdev = 8 then set42(chtxt) savedev = device device = tty nooline(1) prstring(errmess) space printel(culprit) nooline(1) if fun = nil then -> err1 ! NOT IN A USER FUN prstring("IN ") printel(hd(tl(hd(fun)))) ! NAME OF USER FUN nooline(1) unless curfun = nil then start txtptr = (hd(curfun) >> 16) & X'FFFF' printfnline(txtptr) !PRINTLINE(HD(CURFUN)); ! CURRENT LINE nooline(1) finish if getval(quitotop, envir) = false then start ! ENTER LOGO RECURSIVELY stksys(in) stksys(val) logo(stkpnt, makebind(nil, envir, logoname), severity) val = unstksys in = unstksys ! IN NEEDS TO BE AVAILABLE TO THE COLLECTOR ONLY IN THE SINGLE !CASE WHERE IT IS THE ARGUMENT PASSED FROM DOLOGO. IN ALL OTHER ! CASES IT WILL BE A REFERENCE TO THE UNCOLLECTABLE FNSPACE. THE ! COLLECTOR CHECKS THAT THE REFERENCES ON SYSTK ARE IN FACT TO ! COLLECTABLE SPACE device = savedev return finish err1: jumpflag = 1 ! TRIGGERS A RETURN TO LOGO in = nil stack(err) device = savedev end ! END ERROR ! routine error1(string (80) errmess, integer culprit) integer savedev savedev = device device = tty prstring(errmess) space printel(culprit) nooline(1) device = savedev end ! END ERROR1 ! integer fn negate(integer i) if i & nm # nm then start prstring("INVALID UNARY MINUS BEFORE ") printel(i) prstring(" IGNORED") nooline(1) result = i finish if i < 0 then result = (-i >> 8 ! t8) << 8 ! nm else C result = (-i >> 8) << 8 ! nm end ! END NEGATE ! ! routine chklist(integer list) integer word if list & lm # lm then start error("NEW CANNOT HAVE A NUMBER AS ARGUMENT - ", list, 1, in) return finish while list # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(list) error("USER INTERRUPT", empty, 0, in) list = unstksys if jumpflag = 1 then return finish word = hd(list) if word & wm # wm then start error(" NEW MUST HAVE A WORD AS ARGUMENT - ", word, 1, in) return finish list = tl(list) repeat end ! END CHKLIST ! ! integer fn listlen(integer list) ! RETURNS LENGTH OF LIST integer len len = 0 while list # nil cycle len = len + 1 list = tl(list) repeat result = len end ! END LISTLEN ! integer fn getmatch(integer name clause, in) ! PLACES ELEMENTS FROM IN INTO CLAUSE UP TO AND INCLUDING MATCHING RPAR ! ENTER WITH LPAR AS HD(IN) integer head, res clause = cons(lpar, clause) in = tl(in) while in # nil cycle head = hd(in) if head = rpar then start in = tl(in) clause = cons(head, clause) result = empty finish if head = lpar then start res = getmatch(clause, in) if res # empty then result = res ! PASS ERROR OUT finish else start ! NEITHER LPAR NOR RPAR SO CONTINUE in = tl(in) clause = cons(head, clause) finish repeat result = rpar ! NO RPAR BEFORE END end ! END GETMATCH ! routine strtrace(integer fn) ! USED TO PRINT FN. NAME ETC WHEN ENTERING A TRACED FN indent = indent + 1 spaces(indent) printstring(">") printel(fn) nooline(1) indent = indent + 1 end ! END STRTRACE ! routine endtrace(integer fn) ! USED TO PRINT FN NAME ETC. WHEN EXITING A TRACED FN indent = indent - 1 spaces(indent) printstring("<") printel(fn) nooline(1) indent = indent - 1 end ! END ENDTRACE ! routine sendbin(byte integer type, n) ! IF TYPE=0, N 16 BIT ARGS ALREADY SET UP IN BINARG1,2,ETC ! IF TYPE=1 N IS IRRELEVANT n = 2 * n binbuff(1) = tdev - 1 binbuff(2) = type if type = 0 then start binbuff(3) = n !@#$ P_ARG3=N+3 finish !@#$ ELSE P_ARG3=2 !@#$ P_DEST=208; ! SVC PUT OUTPUT !@#$ P_ARG1=16; ! CHANNEL 0 WITH BINARY NIT !@#$ P_ARG2=ADDRBINBUFF !@#$ DOSVC:SVC(P) !@#$ %IF P_ARG1<0 %THENSTART; ! ABORTED !@#$ P_ARG1=P_ARG2 !@#$ P_ARG2=P_ARG3 !@#$ P_ARG3=P_ARG4 !@#$ P_DEST=208 !@#$ ->DOSVC !@#$ %FINISH end ! END SENDBIN ! routine binarg(integer argn, val) ! BINARY ARG IS LEAST SIG, 16 BITS OF VAL ! ARG1==BINBUFF(4) AND(5) ! ARG2==BINBUFF(6) AND (7) ! ETC integer i i = 2 * argn + 2 ! BINBUFF LOWER INDEX binbuff(i) = (val >> 8) & X'FF' binbuff(i + 1) = val & X'FF' end ! END BINARG ! routine cleset ! CLEARS AND RSETS TURTLE DEVICE (IE CLEARS H316 Q) if tdev = 8 then clear42 sendbin(1, 0) xturtle = 0 yturtle = 0 hdturtle = 0 penturtle = down end ! END CLESET ! ! ! ! ! ! routine applysys(integer sw, integer name fn, in, eachval) ! routine spec addfact(integer fact, indent) integer fn spec deduceq(integer pattern, indent) integer fn spec tryinfq(integer pat, indent) ! switch sysfun(1:300) switch fdsw, bdsw, leftsw, rightsw, liftsw, dropsw, hootsw, censw, C clsw, whsw, heresw, xcorsw, ycorsw, hdsw, pensw, setxsw, setysw, C sethsw, posw, arclsw, arcrsw, pnsw, rnsw, notesw, playsw, C motasw, motbsw, rotsw, pairsw(0:8) real rw1, rw2 real dx, dy integer xc, yc ! TURTLE WORKSPACE integer arg1, arg2, arg3, arg4, w1, w2, w3, w4 integer savedev, starttext integer cond, tbranch, fbranch, res, condlist real array tstor(1 : 2) ! USED IN "PICTURE" TO HOLD TURTLE COORDS integer array tstori(3 : 4) integer array movierecord(1 : frametime) integer currentmovietime integer name wptr1 integer redef ! USED BY ABBREV string (64) wstr1, wstr2 routine spec vector(real x, y) routine spec calcturtle ! ! integer fn evalstartfin(integer branch) integer lnumbers, polist branch = tl(branch) lnumbers = hd(branch) ! LINE NUMBER LIST branch = tl(branch) evalnextline: polist = tl(hd(branch)) cycle unless polist = nil then start exit if hd(polist) = finish result = nil if branch = nil stksys(in) stksys(condlist) stksys(lnumbers) stksys(branch) eval(polist, eachval) branch = unstksys lnumbers = unstksys condlist = unstksys in = unstksys if jumpflag = 1 then result = nil if goflag = 1 then exit ! JUMP INSTR val = unstack if fun # nil and curfun = nil then result = val finish branch = tl(branch) polist = tl(hd(branch)) repeat if goflag = 1 then start ! JUMP branch = findlinenums(lnumbers) ! FIND LINE WITH THIS LABEL if branch = 0 then result = nil ! LABEL NOT FOUND AT THIS LEVEL val = unstack -> evalnextline finish ! FINISH JUMP result = val end ! OF EVALSTARTFIN ! ! integer fn spec equal(integer l1, l2) integer fn findass(integer list, att) ! FINDS AN ASSOCIATION IN LIST WITH ATTRIBUTE ATT. USES W1 AND W2 ! FREE. IF ASSOC FOUND, W2 POINTS TO LIST STARTING WITH ASSOC AND ! W1 POINTS TO ONE BEFORE, UNLESS ASSOC IS FIRST IN LIST WHEN W1=W2 ! IN EITHER CASE W2 ALSO RETURNED VIA RESULT. ! IF NO ASSOC FOUND, NIL RETURNED. w1 = list w2 = list while w2 # nil cycle if equal(hd(hd(w2)), att) = false then start w1 = w2 w2 = tl(w2) finish else result = w2 repeat result = nil end ! END FINDASS ! routine checknum if arg1 & nm # nm or arg2 & nm # nm C then error("ARITHMETIC REQUIRES NUMBERS - ", cons(arg1, C cons(arg2, nil)), 1, in) return end ! END CHECKNUM ! integer fn checksize(integer i) if i > numtop then start prstring("ARITHMETIC RESULT OUT OF RANGE.") write(i, 0) space prstring("MAX SUBSTITUTED") nooline(1) result = numtop finish if i < numbot then start prstring("ARITHMETIC RESULT OUT OF RANGE. MIN SUBSTITUTED") nooline(1) result = numbot finish result = i end ! END CHECKSIZE ! routine checksum(integer arg1, arg2) !CHECKS THAT ARG1+ARG2 DOES NOT EXCEED IMP LIMIT if arg1 > 0 then start if arg2 > 0 and maxint - arg1 < arg2 then start error("INTEGER OVERFLOW IN SUM/DIFFERENCE", empty, 1, in) return finish finish else start if arg2 < 0 and maxint + arg2 < imod(arg1) then start error("INTEGER OVERFLOW IN SUM/DIFFERENCE", empty, 1, in) return finish finish end ! END CHECKSUM ! routine readynum arg1 = unstack arg2 = unstack checknum if jumpflag = 1 then return if arg1 < 0 then arg1 = arg1 >> 8 ! t8 else arg1 = arg1 >> 8 if arg2 < 0 then arg2 = arg2 >> 8 ! t8 else arg2 = arg2 >> 8 end ! END READYNUM ! routine word if arg1 & lm = lm or arg1 < 0 then start error("WORD MUST HAVE A WORD OR NON-NEGATIVE NUMBER AS ARGUMENT - ", arg1, 1, in) return finish if arg2 & lm = lm or arg2 < 0 then start error("WORD MUST HAVE A WORD OR NON-NEGATIVE NUMBER AS ARGUMENT - ", arg2, 1, in) return finish if arg1 & nm = nm then wstr1 = numtostr(arg1) C else wstr1 = wa(arg1 >> 8) if arg2 & nm = nm then wstr2 = numtostr(arg2) C else wstr2 = wa(arg2 >> 8) if length(wstr1) + length(wstr2) > 64 then start error("WORD LENGTH EXCEEDED - ", cons(arg1, cons(arg2, nil)), C 1, in) return finish stack(put(wstr1 . wstr2)) return end ! END WORD ! routine lastput if arg2 & lm # lm then start error("LASTPUT MUST HAVE A LIST AS SECOND ARGUMENT - ", arg2, C 1, in) return finish arg3 = nil while arg2 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg2) stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys arg2 = unstksys if jumpflag = 1 then return finish arg3 = cons(hd(arg2), arg3) arg2 = tl(arg2) repeat ! ARG3 NOW ARG2 REVERSED arg2 = cons(arg1, nil) while arg3 # nil cycle arg2 = cons(hd(arg3), arg2) arg3 = tl(arg3) repeat stack(arg2) return end ! END LASTPUT ! ! integer fn equal(integer list1, list2) if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(list1) stksys(list2) error("USER INTERRUPT", empty, 0, in) list2 = unstksys list1 = unstksys if jumpflag = 1 then result = unstack finish if list1 = list2 then result = true ! WORD if list1 & lm = 0 or list2 & lm = 0 or list1 = nil C or list2 = nil then result = false if equal(hd(list1), hd(list2)) = true then C result = equal(tl(list1), tl(list2)) result = false end ! END EQUAL ! ! ! FILING SYSTEM SUPPORT ROUTINES routine restfile ! RESTORES OWNER ETC. owner = wstr2 userfile = wstr1 mdp = w1 mdind = w2 unless cactfile = 2 then getmaster end ! END RESTFILE ! routine savefile ! SAVES OWNER, USERFILE, MDP, MDIND DURING LIBRARY AND BORROWFILE wstr2 = owner owner = wstr1 wstr1 = userfile w1 = mdp w2 = mdind end ! END SAVEFILE ! routine nofile cactfile = 0 userfile = "" owner = emasuser mdp = 0 mdind = 0 end ! END NOFILE ! routine frothdir ! FREES ANOTHERS FILE closesm(4) clear("4") disconnect(owner . "." . masfile) end ! END FROTHDIR ! routine sharefile(string (15) filename) ! CONNECTS A FILE FOR SHARED READ ! EXITS IF CURRENTLY CONNECTED WRITE ELSEWHERE integer stat stat = status(filename, 0) if stat < 0 or (stat # 0 and stat & 4 = 0) then start if sw = 86 then restfile if sw = 85 then nofile and getmaster finish else return if stat < 0 C then error("FINFO CALL FAILS - ", (-stat) << 8 ! nm, 1, in) C else error("LIBRARY IS BEING UPDATED - TRY AGAIN", empty, C 1, in) end ! END SHAREFILE ! integer fn findfile integer i mdp = 0 udp = 0 txtp = 0 ff1: mdmap(filstart + mdp * 4096) unless mdents = 0 then start i = 1 while i <= mdents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 if sw = 75 then nofile else frothdir if sw = 86 then restfile if sw = 85 then nofile and getmaster result = quit finish if holdflag = 1 then start holdflag = 0 if sw = 75 then nofile else frothdir if sw = 86 then restfile if sw = 85 then nofile and getmaster error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, C in) result = unstack finish if i = 63 then mdp = mdnext and -> ff1 if udnam(i) = userfile then result = i i = i + 1 repeat finish result = -1 end !END FINDFILE ! routine gothdir ! CONNECTS ANOTHERS MASTER FILE ! OWNER CONTAINS OWNERS NAME integer temp sharefile(owner . "." . masfile) if jumpflag = 1 then return define("4," . owner . "." . masfile) filstart = smaddr(4, flen) temp = findfile if jumpflag = 1 then stack(temp) and return if temp < 0 then start frothdir if sw = 86 then restfile if sw = 85 then nofile and getmaster error("CANNOT FIND LIBRARY FILE ", empty, 1, in) return finish mdind = temp end ! END GOTHDIR ! routine claimmaster ! CLAIMS MASTER FILE FOR WRITE integer stat stat = status(masfile, 0) if stat = 0 then permit(maswrite) else start if sw = 75 then nofile if sw = 104 or sw = 105 then device = tty unless cactfile = 2 then getmaster if stat < 0 C then error("FINFO CALL FAILS - ", (-stat) << 8 ! nm, 1, C in) C else error("YOUR FILE IS IN USE BY ANOTHER - TRY AGAIN", C empty, 1, in) return finish getmaster end ! END CLAIMMASTER ! routine filetidy string (10) size integer tlen, page, tmdp, ttxtp, tindex, i, j, k unless cactfile = 2 then cluserfl claimmaster if jumpflag = 1 then return mdmap(filstart) if mdents = 0 then start closesm(4) permit(masread) return finish tmdp = 0 page = 0 txtp = 0 size = numtostr(flen << 8) define("10,T#JUNK") newsmfile("T#JUNK," . size) tstart = smaddr(10, tlen) tmdmap(tstart) tendmap tendtxt = 0 tmdents = 0 ft1: i = 1 while i <= mdents cycle if i = 63 then mdmap(filstart + mdnext * 4096) and -> ft1 unless udnam(i) = "" then start tmdents = tmdents + 1 if tmdents = 63 then start page = page + 1 tmdnext = page tmdp = page tmdmap(tstart + page * 4096) tmdents = 1 finish tudnam(tmdents) = udnam(i) if cactfile = 1 then start if udnam(i) = userfile then mdp = tmdp C and mdind = tmdents finish page = page + 1 tudpage(tmdents) = page tudmap(tstart + page * 4096) tudents = 0 udmap(filstart + udpage(i) * 4096) ft2: j = 1 while j <= udents cycle if j = 61 then udmap(filstart + udnext * 4096) C and -> ft2 unless funnam(j) = "" then start tudents = tudents + 1 if tudents = 61 then start page = page + 1 tudnext = page tudmap(tstart + page * 4096) tudents = 1 finish tfunnam(tudents) = funnam(j) if tendtxt = 0 or shortint(tendind(1)) = 4093 then C start page = page + 1 ttxtp = page unless tendtxt = 0 then ttxtnext = page ttxtmap(tstart + page * 4096) tindex = 0 ttxtnext = 0 tendtxt = page tendind(1) = 0 tendind(2) = 1 finish if txtp # txtpage(j) then gettxtp(j) index = shortint(txtind(1, j)) ft3: if tindex = 4092 then start page = page + 1 ttxtnext = page ttxtp = page setshortint(ttxtents(1), 4092) ttxtmap(tstart + page * 4096) tindex = 0 ttxtnext = 0 finish tindex = tindex + 1 readinsym(k) tfntxt(tindex) = k if k = termin then start if index <= shortint(txtents(1)) or txtnext # 0 C then start if nextinsym # 'T' then -> ft3 finish finish else -> ft3 ttxtpage(tudents) = tendtxt ttxtind(1, tudents) = tendind(1) ttxtind(2, tudents) = tendind(2) tendtxt = ttxtp setshortint(tendind(1), tindex + 1) setshortint(ttxtents(1), tindex) finish j = j + 1 repeat finish i = i + 1 repeat closesm(4) clear("4") destroy(masfile) if page * 4096 + 4096 < tlen then start size = numtostr((page * 4096 + 4096) << 8) define("4," . masfile) newsmfile(masfile . "," . size) filstart = smaddr(4, flen) cycle i = 0, 4096, flen - 4096 j = filstart + i k = tstart + i move(4096, k, j) repeat closesm(10) destroy("T#JUNK") closesm(4) finish else start closesm(10) rename("T#JUNK," . masfile) finish clear("10") cherish(masfile) permit(masread) permit(masfile . ",,R") end ! END FILETIDY ! routine updir(integer name) integer i udp = udpage(mdind) up1: udmap(filstart + udp * 4096) i = 1 if udents = 0 then -> up2 while i <= udents cycle if i = 61 then udp = udnext and -> up1 if wa(name >> 8) = funnam(i) then start txtpage(i) = endtxt txtind(1, i) = endind(1) txtind(2, i) = endind(2) setshortint(endind(1), index) endtxt = txtp return finish i = i + 1 repeat if udents = 60 then getpage(2) up2: udents = udents + 1 funnam(udents) = wa(name >> 8) txtpage(udents) = endtxt txtind(1, udents) = endind(1) txtind(2, udents) = endind(2) setshortint(endind(1), index) endtxt = txtp end ! END UPDIR ! integer fn fnents integer no mdmap(filstart + mdp * 4096) endmap getudp txtp = 0 no = udents while udents = 61 cycle udp = udnext udmap(filstart + udp * 4096) no = no - 1 + udents repeat result = no end !END FNENTS ! ! routine chlib !CHECKS LIBRARY OWNER arg1 = unstack arg2 = unstack if arg1 & wm # wm then start error(" INVALID NAME FOR LIBRARY OWNER - ", arg1, 1, in) return finish wstr1 = wa(arg1 >> 8) ! GET CHARS if length(wstr1) # 6 then start error("INVALID NAME FOR LIBRARY OWNER - ", arg1, 1, in) return finish cycle w1 = 1, 1, 4 wstr2 = fromstring(wstr1, w1, w1) if wstr2 <= "9" then start ! NUMERIC CHAR error("INVALID NAME FOR LIBRARY OWNER - ", arg1, 1, in) return finish repeat cycle w1 = 5, 1, 6 wstr2 = fromstring(wstr1, w1, w1) if wstr2 > "9" then start ! NON NUMERIC CHAR error("INVALID NAME FOR LIBRARY OWNER - ", arg1, 1, in) return finish repeat if arg2 & wm # wm C then error("LIBRARY NAME MUST BE A WORD - ", arg2, 1, in) end !END CHLIB ! ! ! ! TURTLE DEVICE SERVICE ROUTINES ! routine spec tsend(integer motors, pulses) routine spec tsend1(integer arg) integer fn spec tscale(integer n) integer fn spec tangle(integer n) ! integer fn intrem(integer i, j) result = i - (i // j) * j end ! END INTREM ! integer fn mod360(integer i) i = intrem(i, 360) if i < 0 then result = i + 360 else result = i end ! END MOD360 ! routine coordok(integer coord) string (80) errm if coord < (-501) or coord > 501 then start errm = "THE TURTLE WILL GO OFF THE EDGE OF THE " if tdev = 3 or tdev = 8 then errm = errm . "SCREEN" C else errm = errm . "PAPER" error(errm, empty, 1, in) finish end ! END COORDOK ! integer fn tstate result = cons(intpt(xturtle) << 8 ! nm, C cons(intpt(yturtle) << 8 ! nm, cons(hdturtle << 8 ! nm, C cons(penturtle, nil)))) end ! END TSTATE ! integer fn impnum(integer i) if i < 0 then result = i >> 8 ! t8 else result = i >> 8 end ! END IMPNUM ! routine circletest(integer flag, rad, ang) switch sw(0:1) coordok(intpt(xturtle + dx)) if jumpflag = 1 then return coordok(intpt(yturtle + dy)) if jumpflag = 1 then return if rad < 0 then rad = -rad if ang < 0 then ang = -ang -> sw(flag) sw(0): !LEFT if ang >= mod360(360 - hdturtle) then start coordok((yc // 32) + intpt(yturtle) - rad) if jumpflag = 1 then return finish if ang >= mod360(270 - hdturtle) then start coordok((xc // 32) + intpt(xturtle) - rad) if jumpflag = 1 then return finish if ang >= mod360(180 - hdturtle) then start coordok((yc // 32) + intpt(yturtle) + rad) if jumpflag = 1 then return finish if ang >= mod360(90 - hdturtle) then start coordok((xc // 32) + intpt(xturtle) + rad) if jumpflag = 1 then return finish return ! sw(1): !RIGHT if ang >= hdturtle then start coordok((yc // 32) + intpt(yturtle) + rad) if jumpflag = 1 then return finish if ang >= mod360(hdturtle + 90) then start coordok((xc // 32) + intpt(xturtle) + rad) if jumpflag = 1 then return finish if ang >= mod360(hdturtle + 180) then start coordok((yc // 32) + intpt(yturtle) - rad) if jumpflag = 1 then return finish if ang >= mod360(hdturtle + 270) then start coordok((xc // 32) + intpt(xturtle) - rad) if jumpflag = 1 then return finish return end ! END CIRCLETEST ! integer fn chdevarg integer arg arg = unstack if arg & nm = 0 then start error(wa(fn >> 8) . " MUST HAVE A NUMBER AS INPUT - ", arg, C 1, in) result = unstack finish w1 = arg result = impnum(arg) end ! END CHDEVARG ! routine setup(integer n, a) integer h if n = 0 then return h = 0 if a > 180 then a = a - 360 if penturtle = down then start penturtle = up tsend1(32) h = 1 finish if a # 0 then start if a < 0 then tsend(ltbits, tangle(-a)) C else tsend(rtbits, tangle(a)) if jumpflag = 1 then return ! RIGHT (A) finish if n < 0 then tsend(bdbits, tscale(-n)) C else tsend(fdbits, tscale(n)) if jumpflag = 1 then return ! FORWARD(N) if a # 0 then start if a < 0 then tsend(rtbits, tangle(-a)) C else tsend(ltbits, tangle(a)) if jumpflag = 1 then return ! LEFT(A) finish if h = 1 then start penturtle = down tsend1(32) finish end ! END SETUP ! routine tsend1(integer arg) if arg = 0 then return if penturtle = up then binarg(1, arg + penbit) C else binarg(1, arg) ! JAM TRANSFER ONLY REQUIREDD FOR HOOTBIT sendbin(0, 1) end ! END TSEND1 ! routine tsend(integer motors, pulses) while pulses > 1500 cycle ! 500 MOVE UNITS OR 375 ROTATE UNITS if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 cleset ! THIS IS THE POINT OF IT. TO BREAK A CLOG IN H316 stack(quit) return finish if holdflag = 1 then start holdflag = 0 cleset error("USER INTERRUPT - TURTLE DEVICE RESET", empty, 1, in) return finish tsend1(motors + 1500) pulses = pulses - 1500 repeat tsend1(motors + pulses) end ! END TSEND ! routine pindsend(integer direction, angle) ! SENDS FOR PLOTTER INDICATOR binarg(1, 5) while angle > 360 cycle if quitflag = 1 then start ! AS FOR TSEND quitflag = 0 jumpout = 0 jumpflag = 1 cleset stack(quit) return finish if holdflag = 1 then start holdflag = 0 cleset error("USER INTERRUPT - TURTLE DEVICE RESET", empty, 1, in) return finish binarg(2, 360 + direction) sendbin(0, 2) angle = angle - 360 repeat binarg(2, angle + direction) sendbin(0, 2) end ! END PINDSEND ! integer fn tscale(integer m) ! FOR 75 MM WHEEEL, ONE PULSE GIVES 0.06814 CM TRAVEL ! WITH GEAR RATIO 5:36 AT 48 PULSES TO ONE REV result = m * 3 end ! END TSCALE ! integer fn tangle(integer a) ! TRACK 312.5 MM, WHEEL 75 MM DIA, RATIO 5:36, ! THUS 4 PULSES TO ONE DEGREE TURN result = 4 * a end ! END TANGLE ! routine gtarcleft(integer r, a) integer p, q, n, th, c, d, e real rv1, b, dx, dy ! routine arcaux(integer m, a) if a = 0 then return if m = 0 then start hdturtle = hdturtle - a finish else start hdturtle = hdturtle + a finish calcturtle end ! END ARCAUX ! c = -1 d = 0 th = 2 if a < 0 then start hdturtle = mod360(hdturtle - 180) calcturtle r = -r a = -a finish if r < 0 then start c = 0 d = -1 r = -r finish loop: rv1 = 2.0 * r * sin(th * 3.14159 / 1440.0) n = int(rv1) if a > (th + 1) and r > n and (n < 1 or (n - rv1) > 0.1 C or (n - rv1) < (-0.1)) then start th = th + 1 -> loop finish p = a // th q = intrem(a, th) e = intpt(th / 2.0) arcaux(c, e) while p # 0 or q # 0 cycle b = hdturtle * 3.14159 / 180.0 dx = n * cos(b) dy = n * sin(b) vector(dx, dy) xturtle = xturtle + dx yturtle = yturtle + dy arcaux(c, th) p = p - 1 if p = 0 and q # 0 then start n = int(2.0 * r * sin(q * 3.14159 / 1440.0)) th = q p = 1 q = 0 finish repeat arcaux(d, e) end ! END TARCLEFT ! routine tarcleft(integer r, a) integer p, q, n, th, c, d, e, tttxcor, tttycor, tthead real rv1, b ! routine arcaux(integer m, a) if a = 0 then return if m = 0 then start tsend(rtbits, a) if jumpflag = 1 then return tthead = tthead - a finish else start tsend(ltbits, a) if jumpflag = 1 then return tthead = tthead + a finish end ! END ARCAUX ! r = 3 * r tttxcor = 3 * intpt(xturtle) tttycor = 3 * intpt(yturtle) a = 4 * a c = -1 d = 0 th = 2 if a < 0 then start hdturtle = mod360(hdturtle - 180) tsend(rtbits, 720) ! RIGHT(180) if jumpflag = 1 then return r = -r a = -a finish tthead = 4 * hdturtle if r < 0 then start c = 0 d = -1 r = -r finish loop: rv1 = 2.0 * r * sin(th * 3.14159 / 1440.0) n = int(rv1) if a > (th + 1) and r > n and (n < 1 or (n - rv1) > 0.1 C or (n - rv1) < (-0.1)) then start th = th + 1 -> loop finish p = a // th q = intrem(a, th) e = intpt(th / 2.0) arcaux(c, e) if jumpflag = 1 then return while p # 0 or q # 0 cycle b = tthead * 3.14159 / 720.0 tttxcor = tttxcor + int(n * cos(b)) tttycor = tttycor + int(n * sin(b)) tsend(fdbits, n) if jumpflag = 1 then return arcaux(c, th) if jumpflag = 1 then return p = p - 1 if p = 0 and q # 0 then start n = int(2.0 * r * sin(q * 3.14159 / 1440.0)) th = q p = 1 q = 0 finish repeat arcaux(d, e) if jumpflag = 1 then return xturtle = tttxcor / 3.0 yturtle = tttycor / 3.0 hdturtle = mod360(int(tthead / 4.0)) end ! END TARCLEFT ! routine claimdevice(integer n) record (rf) r integer flag if tdev # 0 then start ! ALREADY GOR A DEVICE if tdev = n then error("YOU ALREADY HAVE IT", empty, 1, in) C else error("YOU CAN ONLY BE CONNECTED TO ONE DEVICE", C empty, 1, in) return finish ! SO NOT GOT A DEVICE connect(masnum . tdevnames(n), 2, 0, 0, r, flag) ! CONNECT WRITE, NO SHARING - SO WE GOT IT ALONE if flag # 0 C then error("DEVICE " . tdevnames(n) . " IS ALREADY CONNECTED ELSEWHERE", empty, 1, in) and return ! FLAG#0 INDICATES CONNECTING NOT POSSIBLE, I.E. DEVICE IN USE ! ! SO NOW GOT DEVICE tdev = n prstring(tdevnames(n) . " CONNECTED") nooline(1) end ! END CLAIMDEVOCE ! routine freedevice ! ONLY IF TDEV#0 cleset unless tdev = 8 ! CLEAR AND RESET HONEY AS APROPRIATE disconnect(masnum . tdevnames(tdev)) tdev = 0 end ! END FREEDEVICE ! routine gcompile(real x, y, integer mode) !COMPILES A VECTOR DEFINITION INTO GT42 CODE extrinsic integer array modetable(0 : 2) ! integer penv if penturtle = down then penv = pen else penv = 0 if mode # gmode then curpic = consg(modetable(mode), curpic) C and gmode = mode curpic = consg((conv(int(y))), consg(penv ! (conv(int(x))), C curpic)) end ! integer fn getnumb(integer name list, string (64) func) ! ! POPS A NUMBER FROM THE HEAD OF LIST, REPLACING LIST BY ! TAIL OF LIST. FUNC IS ONLY USED IF LIST IS EMPTY (=NIL) ! WHEN AN ERROR DIAGNOSTIC IS OUTPUT ! integer w1 if list = nil C then error(func . " NEEDS A LONGER LIST ", arg2, 1, in) and C result = -100000 ! CHECK THAT LIST NON-EMPTY w1 = hd(list) list = tl(list) if w1 & nm # nm then error(func . " NEEDS A NUMBER ", w1, 1, C in) C and result = -100000 !CHECK THAT YOU HAVE A NUMBER result = w1 >> 8 !AND RETURN ITS VALUE end integer fn checkxy(integer n) ! ! CHECKS THAT GIVEN COORDINATE IS WITHIN THE SCREEN ! BOUNDARY (-512 -> 512) ! while n > 512 cycle n = n - 1024 repeat while n < -512 cycle n = n + 1024 repeat result = n end ! ! routine vector(real x, y) integer t if defpicture = 1 then gcompile(x, y, vectorm) and return if penturtle = down and showturtle42 = 1 then start t = intpt(sqrt(x ** 2 + y ** 2) / 5) if t = 0 then t = 1 ! ZERO TIME WILL BUGGER EXEK set42(chpic) ! SET 42 TO PICTURE MODE mode42(vectorm) ch3(gradv) !AND SEND A GRADUAL VECTOR ch3(t) ! DURATION ch3(int(x)) ch3(int(y)) graphp = graphp + 4 return finish if penturtle = down C then vecorpoint(int(x), int(y), pen, vectorm) C else vecorpoint(int(x), int(y), 0, vectorm) end ! ! routine point(real atx, aty) ! SENDS A DARK POINT INSTRUCTION TO DISPLAY ! ! ONLY USED FROM SETX SETY SETTURTLE AND INITIALISATION ! ! integer savegp if defpicture = 1 then gcompile(atx, aty, pointm) savegp = graphp vecorpoint(int(atx), int(aty), 0, pointm) graphp = savegp end ! ! routine modifyexec ! !*** "HACK" DP1 EXEC FOR LOGO USE !*** TO GIVE IMPROVED STATIC/DYNAMIC PICTURE !*** CAPABILITIES ! const integer array newheader(1 : 15) = C X'E000', X'3FF0', X'F700', X'0000', C X'2028', X'2028', X'8F5C', X'404A', X'4F8A', X'6F8A', C X'404A', X'E000', X'2012', X'E000', X'201A' const integer array newtail(1 : 5) = X'9354', 512, C 512, X'E000', X'2028' const integer ref1 = X'1016' const integer ref2 = X'145E' const integer staddr = X'200E' integer i ! set42(chpic) graphp = initgraphp lbr ch3(setn) ch3(staddr) ch3(15) cycle i = 1, 1, 15 ch3(newheader(i)) repeat ch3(setn) ch3(corebottom) ch3(5) cycle i = 1, 1, 5 ch3(newtail(i)) repeat ch3(set) ch3(ref1) ch3(turtlestart) !**IMPORTANT** MOD TO "CLEAR" !INSTRINGT42EXEC ch3(set) ch3(ref2) ch3(turtlestart) rbr end ! ! routine calcturtle integer i ! ! THIS ROUTINE SENDS A VECTOR DESCRIPTION OF THE ! TURTLE TO THE GT42 - ASSUMING THAT THE TURTLE ! IS CURRENTLY BEING SHOWN ! integer fn vec(integer dx, dy) !CONVERTS DX,DY INTO A GT42 SHORT VECTOR ! if dx < 0 then dx = X'40' + ((0 - dx) & X'3F') C else dx = dx & X'3F' if dy < 0 then dy = X'40' + ((0 - dy) & X'3F') C else dy = dy & X'3F' result = X'4000' ! (dx << 7) ! dy end const integer array x(1 : 4) = 0, 31, -31, 0 const integer array y(1 : 4) = -10, 10, 10, -10 !*** FUNCTIONS TO CALCULATE NEW X AND Y DISPLACEMENTS *** !*** (DONE LIKE THIS FOR EASE OF MODIFICATION ) *** integer fn newx result = int(x(i) * cos(hdturtle / 57.3) - sin(hdturtle / 57.3) * y(i)) end integer fn newy result = int(y(i) * cos(hdturtle / 57.3) + x(i) * sin(hdturtle / 57.3)) end const integer turtlemode = X'8F5C' return if showturtle42 = 0 return if defpicture = 1 ! DON"T BOTHER WITH TURTLE IN DEF MODE set42(chpic) lbr ch3(setn) ch3(turtlestart) ch3(5) ch3(turtlemode) ! SEND DESCRIPTION cycle i = 1, 1, 4 ch3(vec(newx, newy)) repeat rbr return ! !OTHERWISE PART OF PICTURE DEFINITION ! SO IGNORE THE BLOODY THING ! end routine showturtle showturtle42 = 1 calcturtle end routine hideturtle ! ! *** SENDS CODE TO THE GT42 TO PREVENT TURTLE BEING DRAWN ! *** (ACTUALLY DUMPS A DJMP INST{UCTION ROUND THE TURTLE BLOCK) ! set42(chpic) ! SET GRAPHICS MODE lbr ch3(setn) ch3(turtlestart) ch3(2) ch3(djump) ! JUMP INSTRUCTION ch3(dlast) ! TO END OF DISPLAY FILE rbr showturtle42 = 0 end ! routine setcorepointer(integer toval) ! USED TO ASSIGN TO END OF CORE POINTER IN GT42 ! ! ALSO UPDATES EMAS LOCAL VARIABLE PICTURE POINTER ! const integer corepointer = X'2010' ! ADDRESS IN GT42 ! picturepointer = toval ! UPDATE EMAS POINTER set42(chpic) ch3(set) ! AND GT42 POINTER ch3(corepointer) ch3(picturepointer) ! NEW VALUE end routine inc(integer w1) ! *** ROUTINE TO SEND A PICTURE DEFINITION ! *** TO THE GT42 -- CALLED FROM "INCLUDE" AND "PUT" ! integer w2, w3 set42(chpic) ! SET GT42 MODE w2 = listlen(index42(w1)_ptr) ! LENGTH OF PICTURE index42(w1)_faddr = picturepointer picturepointer = picturepointer - w2 - w2 - 2 lbr ch3(setn) ch3(picturepointer) ch3(w2) !HEADER!! w3 = consg(djump, consg(index42(w1)_faddr, C tl(tl(index42(w1)_ptr)))) until w3 = nil cycle ch3(hd(w3) >> 8) w3 = tl(w3) repeat rbr ! DELIMITER index42(w1)_ptr42 = picturepointer ! START ADDR IN 42 setcorepointer(picturepointer) if picturepointer < graphp C then error("GT42 DISPLAY FILE CORRUPTED :-" . snl . C "TOO MUCH DISPLAY DATA", empty, 1, in) and return end ! ! ! ! INFERENCE SERVICE ROUTINES ! routine sayl(string (20) mess, integer rule, indent) ! PRINTS MESS INDENTED INDENT SPACES if getval(thinkaloud, envir) = true then start printstring("*") spaces(indent) charout = charout + 1 + indent prstring(mess) printel(rule) nooline(1) finish end ! END SAYL ! integer fn fitsq(integer fact, pat) ! MATCHES FACT AGAINST PAT. ! FACT AND PAT ARE ASSUMED TO BE SIMPLE PATTERNS. ! (FACT WILL HAVE HAD COLON VARIABLES ASSIGNED ALREADY.) integer val if fact = nil then start if pat = nil then result = true result = false finish if pat = nil then result = false ! (NEXT LINE INCORRECT IF FACT ALLOWED TO CONTAIN QUOTED VARIABLES.) if hd(pat) = quote then setval(hd(tl(pat)), hd(fact), envir) C else start if hd(pat) = dots then start val = getval(hd(tl(pat)), envir) if val = undef then start error("NO VALUE HAS BEEN GIVEN TO VARIABLE -", C hd(tl(pat)), 1, in) result = unstack finish if val # hd(fact) then result = false finish else start if hd(pat) # hd(fact) then result = false result = fitsq(tl(fact), tl(pat)) finish finish result = fitsq(tl(fact), tl(tl(pat))) end ! END FITSQ ! routine setvbls(integer vbls) ! VBLS IS A LIST OF QUOTED VARIABLES. EACH VARIABLE IS SET TO NIL, ! EITHER GLOBALLY OR LOCALLY. integer i, l vbls = hd(tl(vbls)) l = listlen(vbls) if envir = basenvir then start cycle i = 1, 1, l setval(hd(vbls), nil, envir) vbls = tl(vbls) repeat finish else start cycle i = 1, 1, l stack(nil) repeat envir = setbind(vbls, envir) finish end ! END SETVBLS ! routine tryimprule(integer rule, fact, keyed, indent) ! MATCHES IMPLIED RULE AGAINST FACT. ! KEYED IS TRUE IF RULE STARTS WITH AKEYWORD, FALSE IF IT STARTS WITH ! A QUOTED WORD. IF MATCH IS FOUND, ADDS IMPLIED FACT. integer vbls, pred vbls = hd(rule) rule = tl(rule) if vbls # nil then setvbls(vbls) if keyed = true then pred = fitsq(tl(fact), tl(hd(rule))) C else pred = fitsq(fact, hd(rule)) if jumpflag = 1 then stack(pred) and return if pred = true then start sayl("USING RULE ", cons(implies, rule), indent) addfact(hd(tl(rule)), indent + 3) finish end ! END TRYIMPRULE ! integer fn vblsin(integer terms) ! LOOKS FOR QUOTED VARIABLES IN IMPLY/TOINFER RULE, TERMS, AND PUTS ! THEM INTO A LIST CONSED ON TO "NEW". E.G. [NEW [X Y]] ! CHECKS THAT CONSEQUENT OF TOINFER RULE DOESN"T CONTAIN A DOTTED ! VARIABLE AND THAT AN IMPLY RULE ONLY HAS ONE CONSEQUENT. integer term, vbls, rule, first vbls = nil rule = hd(terms) terms = tl(terms) first = true while terms # nil cycle term = hd(terms) if term & lm # lm or term = nil then -> vblerr if hd(term) & lm = lm then -> vblerr while term # nil cycle if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(term) stksys(terms) stksys(vbls) error("USER INTERRUPT", empty, 0, in) vbls = unstksys terms = unstksys term = unstksys if jumpflag = 1 then result = unstack finish if hd(term) = quote then start term = tl(term) if term = nil or hd(term) & wm # wm then -> vblerr vbls = cons(hd(term), vbls) finish else start if hd(term) = dots then start if rule = toinfer and first = true then -> vblerr term = tl(term) if term = nil or hd(term) & wm # wm then -> vblerr finish finish term = tl(term) repeat terms = tl(terms) if first = false then start if terms # nil and rule = implies then -> vblerr finish else first = false repeat if vbls # nil then vbls = cons(new, cons(vbls, nil)) result = vbls vblerr: error("INVALID PATTERN FOR IMPLIES/TOINFER RULE -", terms, 1, in) result = unstack end ! END VBLSIN ! integer fn instance(integer item) ! ITEM IS A (SIMPLE?) PATTERN. ! IF IT IS SIMPLE,CHECKS THAT IT IS IN CORRECT FROM AND ASSIGNS ! CURRENT VALUES TO COLON VARIABLES. integer val if item = nil then result = nil if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(item) error("USER INTERRUPT", empty, 0, in) item = unstksys if jumpflag = 1 then result = unstack finish val = hd(item) if val = dots then start item = tl(item) if item = nil or hd(item) & wm # wm then -> insterr val = getval(hd(item), envir) if val = undef C then error("NO VALUE HAS BEEN GIVEN TO VARIABLE - ", C hd(item), 1, in) and result = unstack finish else start if val = quote then start if tl(item) = nil or hd(tl(item)) & wm # wm C then -> insterr finish finish result = cons(val, instance(tl(item))) insterr: error("INVALID PATTERN FOR FACT -", item, 1, in) result = unstack end ! END INSTANCE ! routine addlink(integer item, key, integer array name links) ! ADDS PATTERN, ITEM, TO ONE OF DATABASE,IMPRULES OR INFRULES ! ACCORDING TO VALUE OF LINKS. SETS UP WORD, KEY, AS AN ! ASSOCIATION SET, IF IT DOES NOT ALREADY EXIST, ADDING KEY TO ONE OF ! FACTKEYS, IMPKEYS, INFKEYS, AND ADDS ITEM TO THE ASSOCIATION SET. integer val, ind if key & wm # wm then start if links(2) # fact then item = cons(links(2), tl(item)) error("INVALID PATTERN FOR ASSERT - ", item, 1, in) return finish bvalue(links(1) >> 8) = cons(item, bvalue(links(1) >> 8)) ind = key >> 8 val = findass(assocwa(ind), links(2)) if val # nil then start val = tl(hd(val)) rephead(val, cons(item, hd(val))) finish else start bvalue(links(3) >> 8) = cons(key, bvalue(links(3) >> 8)) assocwa(ind) = cons(cons(links(2), cons(cons(item, nil), C nil)), assocwa(ind)) finish end ! END ADDLINK ! routine addrule(integer rule, indent, integer array name links) ! REPLACES HEAD OF RULE WITH A LIST OF THE QUOTED VARIABLES IN THE RULE ! OF THE FORM [NEW [X Y]]. ADDS THE RULE TO IMPRULES/INFRULES. integer vbls if tl(rule) = nil then start error("INVALID PATTERN FOR IMPLIES/TOINFER RULE -", tl(rule), C 1, in) return finish stksys(rule) vbls = vblsin(rule) rule = unstksys if jumpflag = 1 then stack(vbls) and return vbls = cons(vbls, tl(rule)) addlink(vbls, hd(hd(tl(rule))), links) if jumpflag = 1 then return sayl("ADDED RULE ", rule, indent) end ! END ADDRULE ! routine addfact(integer fact, indent) ! ADDS A FACT TO DATABASE.(NO CHECK MADE FOR FACT CONTAINING QUOTED ! VARIABLES.) CHECKS IF KEYWORD POINTS TO ANY IMPLIED RULES, I.E. IF ! THE ASSOCIATION SET, KEY, HAS ANY VALUES WITH ATTRIBUTE "IMPLIES", ! AND, IF THEY MATCH FACT, ADDS THE IMPLIED FACT. ! SIMILARLY, CHECKS IF FACT MATCHES ANY IMPLIED RULES WHOSE KEY WORD IS ! NOT FIRST, BY LOOKING AT THE ASSOCIATION SET FOR "QUOTE", AND ADDS ! ANY MATCHING IMPLIED FACT. integer key, val fact = instance(fact) if jumpflag = 1 then stack(fact) and return key = hd(fact) addlink(fact, key, dbase) if jumpflag = 1 then return sayl("ADDED FACT ", fact, indent) val = findass(assocwa(key >> 8), implies) if val # nil then start val = hd(tl(hd(val))) while val # nil cycle if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(val) stksys(fact) error("USER INTERRUPT", empty, 0, in) fact = unstksys val = unstksys if jumpflag = 1 then return finish stksys(val) stksys(fact) tryimprule(hd(val), fact, true, indent) fact = unstksys val = unstksys if jumpflag = 1 then return val = tl(val) repeat finish val = findass(assocwa(quote >> 8), implies) if val # nil then start val = hd(tl(hd(val))) while val # nil cycle if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(val) stksys(fact) error("USER INTERRUPT", empty, 0, in) fact = unstksys val = unstksys if jumpflag = 1 then return finish stksys(val) stksys(fact) tryimprule(hd(val), fact, false, indent) fact = unstksys val = unstksys if jumpflag = 1 then return val = tl(val) repeat finish end ! END ADDFACT ! integer fn trybest(integer array name links, integer C name epat, keyed, integer ipat) ! IPAT IS A PATTERN (SHOULD BE SIMPLE). ! IF ITS HEAD IS A QUOTED VARIABLE, RETURNS ONE OF DATABASE, IMPRULES ! OR INFRULES, DEPNEDING ON VALUE OF LINKS, AND SETS KEYED TO FALSE, ! EPAT TO IPAT. OTHERWISE, RETURNS THE ASSOCIATION SET FOR HD(IPAT) ! WITH ATTRIBUTE FACT, IMPLIES OR TOINFER AND SETS KEYED TO TRUE, ! EPAT TO TL(IPAT). integer it if hd(ipat) = quote then start epat = ipat keyed = false result = bvalue(links(1) >> 8) finish keyed = true if hd(ipat) = dots then start epat = tl(tl(ipat)) it = getval(hd(tl(ipat)), envir) if it = undef then start error("NO VALUE HAS BEEN GIVEN TO VARIABLE - ", C hd(tl(ipat)), 1, in) result = unstack finish finish else start epat = tl(ipat) it = hd(ipat) finish if it & wm # wm then start error("INVALID PATTERN - ", ipat, 1, in) result = unstack finish it = findass(assocwa(it >> 8), links(2)) if it # nil then result = hd(tl(hd(it))) result = nil end ! END TRYBEST ! integer fn infinstance(integer term) ! TERM IS AN ANTECEDENT OF A TOINFER RULE. ! RETURNS TERM WITH COLON VARIABLES REPLACED BY THEIR CURRENT ! VALUES (THIS MAY BE A QUOTED VARIABLE OR ANOTHER COLON VARIABLE) ! AND QUOTED VARIABLES ASSIGNED TO LOCAL COLON VARIABLES AND REPLACED ! BY LOCAL QUOTED VARIABLES. (SO THEY DO NOT CLASH WITH QUOTED ! VARIABLES OF ORIGINAL PATTERN WHICH WAS MATCHED AGAINST CONSEQUENT OF ! THIS TOINFER RULE.) integer vf, it string (10) str1, str2 if term = nil then result = nil if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(term) stksys(arg1) stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys arg1 = unstksys term = unstksys if jumpflag = 1 then result = unstack finish if hd(term) = dots then start vf = getval(hd(tl(term)), envir) if vf = undef then start error("NO VALUE HAS BEEN GIVEN TO VARIABLE - ", C hd(tl(term)), 1, in) result = unstack finish if vf & lm # lm or vf = nil then C result = cons(vf, infinstance(tl(tl(term)))) if hd(vf) = quote then start rephead(vf, dots) result = cons(quote, cons(hd(tl(vf)), C infinstance(tl(tl(term))))) finish if hd(vf) # dots then C result = cons(vf, infinstance(tl(tl(term)))) result = cons(dots, cons(hd(tl(vf)), C infinstance(tl(tl(term))))) finish if hd(term) # quote then C result = cons(hd(term), infinstance(tl(term))) genos = genos + 1 str1 = wa(vbl >> 8) str2 = numtostr(genos << 8) it = put(str1 . str2) setval(hd(tl(term)), cons(dots, cons(it, nil)), envir) result = cons(quote, cons(it, infinstance(tl(tl(term))))) end ! END INFINSTANCE ! integer fn inffitsq(integer pat, rpat) ! MATCHES PATTERN, PAT, AGAINST CONSEQUENT OF TOINFER RULE, RPAT. ! SETS QUOTED VARIABLES IN RPAT TO CORRESPONDING VALUE IN PAT ! (THIS MAY ALSO BE A QUOTED VARIABLE). SETS ANY OTHER QUOTED ! VARIABLES IN PAT TO CORRESPONDING VALUE IN RPAT. integer p1, rp1 inff1: if pat = nil then start if rpat = nil then result = true result = false finish if rpat = nil then result = false p1 = hd(pat) pat = tl(pat) rp1 = hd(rpat) rpat = tl(rpat) if p1 = dots then start p1 = getval(hd(pat), envir) if p1 = undef then start error("NO VALUE HAS BEEN GIVEN TO VARIABLE - ", hd(pat), C 1, in) result = unstack finish pat = tl(pat) finish else start if p1 = quote then start p1 = hd(pat) pat = tl(pat) if rp1 = quote then start setval(hd(rpat), cons(quote, cons(p1, nil)), envir) rpat = tl(rpat) finish else setval(p1, rp1, envir) -> inff1 finish finish if rp1 = quote then start setval(hd(rpat), p1, envir) rpat = tl(rpat) -> inff1 finish if p1 = rp1 then -> inff1 result = false end ! END INFFITSQ ! integer fn tryinfrule(integer rule, epat, pat, keyed, indent) ! MATCHES PATTERN, EPAT, AGAINST TOINFER RULE, RULE. ! IF EPAT MATCHES CONSEQUENT OF TOINFER RULE, SUBSTITUTES ! CURRENT VALUES FOR VARIABLES IN ANTECEDENT(S) AND TRIES ! TO MATCH ANTECEDENT(S) USING TRYINFQ. integer vbls, pred, list, savlist, temp vbls = hd(rule) rule = tl(rule) if vbls # nil then setvbls(vbls) if keyed = true then pred = inffitsq(epat, tl(hd(rule))) C else pred = inffitsq(epat, hd(rule)) if jumpflag = 1 then result = pred if pred = true then start sayl("USING RULE ", cons(toinfer, rule), indent) list = cons(nil, nil) savlist = list while tl(rule) # nil cycle stksys(rule) stksys(list) stksys(savlist) stksys(pat) temp = infinstance(hd(tl(rule))) pat = unstksys savlist = unstksys list = unstksys rule = unstksys if jumpflag = 1 then result = temp reptail(list, cons(temp, nil)) rule = tl(rule) list = tl(list) repeat reptail(list, tl(pat)) list = tl(savlist) result = tryinfq(list, indent + 3) finish result = false end !END TRYINFRULE ! integer fn bindings(integer vlist) ! VLIST IS THE LIST OF VARIABLES OF FINDANY/FINDALL. ! A LIST OF THE VALUES OF THESE VARIABLES IS RETURNED. integer val if vlist = nil then result = nil val = getval(hd(vlist), envir) if val = undef then start error("NO VALUE HAS BEEN GIVEN TO VARIABLE - ", hd(vlist), 1, C in) result = unstack finish result = cons(val, bindings(tl(vlist))) end ! END BINDINGS ! integer fn tryinfq(integer pat, indent) ! MATCHES PATTERN, PAT. ! IF PAT HAS A KEYWORD, MATCHES AGAINST ITS ASSOCIATION SET, ! FIRSTLY WITH ATTRIBUTE "FACT", THEN "TOINFER", ! EXITING IF A MATCH IS FOUND AND ONLY ONE MATCH REQUIRED (VALUE ! OF SW DETERMINES THIS). OTHERWISE, PAT IS MATCHED AGAINST ! DATABASE, THEN INFRULES, EXITING AS ABOVE. FINALLY, IF PAT HAS ! A KEYWORD, IT IS MATCHED AGAINST THE ASSOCIATION SET FOR "QUOTE" ! WITH ATTRIBUTE "TOINFER", EXITING AS ABOVE. ! BEFORE EXITING, IF CURRENT FUNCTION IS FINDALL, ASSIGNS CURRENT ! VALUES TO ITS VARIABLE LIST, AND CONS"S THIS LIST TO ARG3 AS RESULT. integer ipat, epat, keyed, it, fact, res, temp if pat = nil then start if sw = 156 then start fact = bindings(arg1) if jumpflag = 1 then result = fact it = arg3 while it # nil cycle stksys(it) stksys(fact) res = equal(hd(it), fact) fact = unstksys it = unstksys if jumpflag = 1 then result = res if res = true then result = true it = tl(it) repeat arg3 = cons(fact, arg3) finish result = true finish ipat = hd(pat) if ipat & lm # lm or ipat = nil then -> tryinferr it = ipat while it # nil cycle if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(it) stksys(ipat) stksys(pat) stksys(arg1) stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys arg1 = unstksys pat = unstksys ipat = unstksys it = unstksys if jumpflag = 1 then result = unstack finish if hd(it) = dots or hd(it) = quote then start it = tl(it) if it = nil then -> tryinferr finish it = tl(it) repeat sayl("LOOK FOR ", ipat, indent) if hd(ipat) = not then start if tl(ipat) = nil then -> tryinferr ipat = tl(ipat) stack(sw) sw = 154 stksys(pat) stksys(ipat) res = deduceq(ipat, indent + 3) sw = unstack ipat = unstksys pat = unstksys if jumpflag = 1 then result = res if res = true then result = false sayl("SUCCEED WITH - ", cons(not, ipat), indent) result = tryinfq(tl(pat), indent + 3) finish it = trybest(dbase, epat, keyed, ipat) if jumpflag = 1 then result = it while it # nil cycle if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(it) stksys(ipat) stksys(pat) stksys(epat) stksys(arg1) stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys arg1 = unstksys epat = unstksys pat = unstksys ipat = unstksys it = unstksys if jumpflag = 1 then result = unstack finish if keyed = true then fact = tl(hd(it)) else fact = hd(it) temp = fitsq(fact, epat) if jumpflag = 1 then result = temp if temp = true then start sayl("SUCCEED WITH ", hd(it), indent) stksys(it) stksys(pat) stksys(ipat) res = tryinfq(tl(pat), indent + 3) ipat = unstksys pat = unstksys it = unstksys if jumpflag = 1 then result = res if res = true and (sw = 154 or sw = 155) then C result = true finish it = tl(it) repeat it = trybest(inflinks, epat, keyed, ipat) if jumpflag = 1 then result = it while it # nil cycle if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(it) stksys(ipat) stksys(pat) stksys(epat) stksys(arg1) stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys arg1 = unstksys epat = unstksys pat = unstksys ipat = unstksys it = unstksys if jumpflag = 1 then result = unstack finish stksys(it) stksys(pat) stksys(epat) stksys(ipat) res = tryinfrule(hd(it), epat, pat, keyed, indent) ipat = unstksys epat = unstksys pat = unstksys it = unstksys if jumpflag = 1 then result = res if res = true and (sw = 154 or sw = 155) then result = true it = tl(it) repeat if keyed = true then start keyed = false epat = ipat it = findass(assocwa(quote >> 8), toinfer) if it # nil then it = hd(tl(hd(it))) while it # nil cycle if quitflag = 1 then start quitflag = 0 jumpflag = 1 jumpout = 0 result = quit finish if holdflag = 1 then start holdflag = 0 stksys(it) stksys(pat) stksys(epat) stksys(arg1) stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys arg1 = unstksys epat = unstksys pat = unstksys it = unstksys if jumpflag = 1 then result = unstack finish stksys(it) stksys(pat) stksys(epat) res = tryinfrule(hd(it), epat, pat, keyed, indent) epat = unstksys pat = unstksys it = unstksys if jumpflag = 1 then result = res if res = true and (sw = 154 or sw = 155) then C result = true it = tl(it) repeat finish sayl("FAILED", empty, indent) result = false tryinferr: error("INVALID PATTERN -", ipat, 1, in) result = unstack end ! END TRYINFQ ! integer fn deduceq(integer pattern, indent) if hd(pattern) & lm # lm then pattern = cons(pattern, nil) result = tryinfq(pattern, indent) end ! END DEDUCEQ ! ! ! -> sysfun(sw) ! ! INPUT OUTPUT sysfun(1): !PRINT if tdev = 8 then set42(chtxt) arg1 = unstack if arg1 = enel then nooline(1) else printel(arg1) nooline(1) stack(arg1) return ! ! sysfun(2): !TYPE if tdev = 8 then set42(chtxt) arg1 = unstack if arg1 = enel then nooline(1) else printel(arg1) stack(arg1) return ! END TYPE ! ! sysfun(3): !GETLIST if tdev = 8 then set42(chtxt) blevel = 2 readinline("REPLY:") stack(readlist) prompt(promp) return ! END GETLIST ! ! sysfun(4): !GETWORD if tdev = 8 then set42(chtxt) blevel = 2 readinline("REPLY:") arg1 = headin if arg1 = rbrak then stack(empty) else start if arg1 & lm = lm then start prstring("NOT A WORD") nooline(1) -> sysfun(4) finish stack(arg1) finish prompt(promp) return ! END GETWORD ! ! sysfun(5): !SAY arg1 = unstack if arg1 = enel then nooline(1) else start enuf = 0 sep = "" if arg1 & lm = lm then printlcon(arg1) else printwn(arg1) finish nooline(1) stack(arg1) return ! END SAY ! ! ! ARITHMETIC sysfun(10): !+ORSUM readynum if jumpflag = 1 then return checksum(arg1, arg2) if jumpflag = 1 then return stack(checksize(arg1 + arg2) << 8 ! nm) return ! END SUM ! ! ! sysfun(11): !-ORDIFFERENCE readynum if jumpflag = 1 then return checksum(arg1, -arg2) if jumpflag = 1 then return stack(checksize(arg1 - arg2) << 8 ! nm) return ! END DIFFERENCE ! ! sysfun(12): !*ORTIMES readynum if jumpflag = 1 then return if arg1 = 0 or arg2 = 0 then -> stk if maxint / imod(arg1) < imod(arg2) then start error("INTEGER OVERFLOW IN PRODUCT", empty, 1, in) return finish stk: stack(checksize(arg1 * arg2) << 8 ! nm) return ! END TIMES ! ! sysfun(13): !/ORQUOTIENT readynum if jumpflag = 1 then return if arg2 = 0 then start error("DIVISION BY ZERO IN ", fn, 1, in) return finish stack(checksize(arg1 // arg2) << 8 ! nm) return ! END QUOTIENT ! ! sysfun(14): !REMAINDER readynum if jumpflag = 1 then return if arg2 = 0 then start error("DIVISION BY ZERO IN ", fn, 1, in) return finish stack(checksize(arg1 - (arg1 // arg2) * arg2) << 8 ! nm) return ! END REMAINDER ! ! sysfun(15): !DIVISION readynum if jumpflag = 1 then return if arg2 = 0 then start error("DIVISION BY ZERO IN ", fn, 1, in) return finish arg3 = arg1 // arg2 ! ARG3 USED TEMP stack(cons(checksize(arg3) << 8 ! nm, C cons(checksize(arg1 - arg3 * arg2) << 8 ! nm, nil))) return ! END DIVISION ! ! sysfun(16): !MAXIMUM readynum if jumpflag = 1 then return if arg1 >= arg2 then stack(arg1 << 8 ! nm) C else stack(arg2 << 8 ! nm) return ! END MAXIMUM ! ! sysfun(17): !MINIMUM readynum if jumpflag = 1 then return if arg1 <= arg2 then stack(arg1 << 8 ! nm) C else stack(arg2 << 8 ! nm) return ! END MIMIMUM ! ! ! ! CHARACTER AND LIST MANIPULATION ! sysfun(20): !FIRST arg1 = unstack if arg1 & lm # lm then start error("FIRST MUST HAVE A LIST AS ARGUMENT - ", arg1, 1, in) return finish if arg1 = nil then start error("FIRST CANNOT HAVE THE EMPTY LIST AS ARGUMENT", empty, 1, in) return finish stack(hd(arg1)) return ! END FIRST ! ! sysfun(21): !LAST arg1 = unstack if arg1 & lm # lm then start error("LAST MUST HAVE A LIST AS ARGUMENT - ", arg1, 1, in) return finish if arg1 = nil then start error("LAST CANNOT HAVE THE EMPTY LIST AS ARGUMENT", empty, 1, in) return finish while tl(arg1) # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg1) error("USER INTERRUPT", empty, 0, in) arg1 = unstksys if jumpflag = 1 then return finish arg1 = tl(arg1) repeat stack(hd(arg1)) return ! END LAST ! ! sysfun(22): !BUTFIRST arg1 = unstack if arg1 & lm # lm then start error("BUTFIRST MUST HAVE A LIST AS ARGUMENT - ", arg1, 1, in) return finish if arg1 = nil then start error("BUTFIRST CANNOT HAVE THE EMPTY LIST AS ARGUMENT", empty, C 1, in) return finish stack(tl(arg1)) return ! END BUTFIRST ! ! sysfun(23): !BUTLAST arg1 = unstack if arg1 & lm # lm then start error("BUTLAST MUST HAVE A LIST AS ARGUMENT - ", arg1, 1, in) return finish if arg1 = nil then start error("BUTLAST CANNOT HAVE THE EMPTY LIST AS ARGUMENT", empty, C 1, in) return finish arg2 = nil ! ARG2 USED TEMP while tl(arg1) # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg1) stksys(arg2) error("USER INTERRUPT", empty, 0, in) arg2 = unstksys arg1 = unstksys if jumpflag = 1 then return finish arg2 = cons(hd(arg1), arg2) arg1 = tl(arg1) repeat ! ARG2 NOW HAS ARG1 LESS LAST ELEMENT REVERSED arg1 = nil while arg2 # nil cycle arg1 = cons(hd(arg2), arg1) arg2 = tl(arg2) repeat stack(arg1) return ! END BUTLAST ! ! sysfun(24): !WORD arg1 = unstack arg2 = unstack word return ! END WORD ! ! sysfun(25): !LIST arg1 = unstack arg2 = unstack stack(cons(arg1, cons(arg2, nil))) return ! ND LIST ! ! sysfun(26): !FIRSTPUT arg1 = unstack arg2 = unstack if arg2 & lm = lm then start ! ARG2 A LIST stack(cons(arg1, arg2)) return finish error("FIRSTPUT MUST HAVE A LIST AS SECOND ARGUMENT - ", arg2, 1, in) return ! END FIRSTPUT ! ! sysfun(27): !LASTPUT arg1 = unstack arg2 = unstack lastput return ! END LASTPUT ! ! sysfun(28): !JOIN arg1 = unstack arg2 = unstack if arg1 & lm # lm then start error("JOIN MUST HAVE A LIST AS FIRST ARGUMENT - ", arg1, 1, in) return finish if arg2 & lm # lm then start error("JOIN MUST HAVE A LIST AS SECOND ARGUMENT - ", arg2, 1, in) return finish arg3 = nil ! ARG3 USED TEMP while arg1 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg1) stksys(arg2) stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys arg2 = unstksys arg1 = unstksys if jumpflag = 1 then return finish arg3 = cons(hd(arg1), arg3) arg1 = tl(arg1) repeat ! ARG3 NOW ARG1 REVERSED while arg3 # nil cycle arg2 = cons(hd(arg3), arg2) arg3 = tl(arg3) repeat stack(arg2) ! LISTS APPENDED return ! END JOIN ! ! sysfun(29): !COUNT arg1 = unstack if arg1 & lm # lm then start error("COUNT MUST HAVE A LIST AS ARGUMENT - ", arg1, 1, in) return finish arg2 = 0 while arg1 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg1) error("USER INTERRUPT", empty, 0, in) arg1 = unstksys if jumpflag = 1 then return finish arg2 = arg2 + 1 arg1 = tl(arg1) repeat stack(arg2 << 8 ! nm) return ! END COUNT ! ! ! PREDICATES AND CONDITIONALS ! ! ! ! sysfun(30): !LESSTHAN readynum if jumpflag = 1 then return if arg1 < arg2 then stack(true) else stack(false) return ! END LESS THAN ! ! sysfun(31): !EQUALTOORLESSTHAN readynum if jumpflag = 1 then return if arg1 <= arg2 then stack(true) else stack(false) return ! END EQUAL TO OR LESS THAN ! ! sysfun(32): !GREATERTHAN readynum if jumpflag = 1 then return if arg1 > arg2 then stack(true) else stack(false) return ! END GREATER THAN ! ! sysfun(33): !GREATERTHANOREQUALTO readynum if jumpflag = 1 then return if arg1 >= arg2 then stack(true) else stack(false) return ! END GREATER THAN OR EQUAL TO ! ! sysfun(34): !EQUALTO arg1 = unstack arg2 = unstack arg3 = equal(arg1, arg2) stack(arg3) return ! END EQUAL TO ! ! sysfun(35): !ZEROQ arg1 = unstack if arg1 & nm = nm and arg1 >> 8 = 0 then stack(true) C else stack(false) return ! END ZEROQ ! ! sysfun(36): !NUMBERQ arg1 = unstack if arg1 & nm = nm then stack(true) else stack(false) return ! END NUMBERQ ! ! sysfun(37): !WORDQ arg1 = unstack if arg1 & wm = wm then stack(true) else stack(false) return ! END WORDQ ! ! sysfun(38): !LISTQ arg1 = unstack if arg1 & lm = lm then stack(true) else stack(false) return ! END LISTQ ! ! sysfun(39): !EMPTYQ arg1 = unstack if arg1 = nil or arg1 = empty then stack(true) else stack(false) return !END EMPTYQ ! ! sysfun(40): !BOTH arg1 = unstack arg2 = unstack if arg1 = true and arg2 = true then stack(true) else stack(false) return ! END BOTH ! ! sysfun(41): !EITHER arg1 = unstack arg2 = unstack if arg1 = true or arg2 = true then stack(true) else stack(false) return ! END EITHER ! ! sysfun(42): !NOT arg1 = unstack if arg1 = true then stack(false) else stack(true) return ! END NOT ! ! ! sysfun(50): !TEST arg1 = unstack if arg1 = true then tstflg = 1 else start if arg1 = false then tstflg = 0 else start error("TEST MUST HAVE TRUE OR FALSE AS ARGUMENT - ", arg1, 1, C in) return finish finish stack(arg1) return ! END TEST ! ! sysfun(51): !IFTRUE if tstflg = 1 then start if in = nil then start error("NULL INSTRUCTION", empty, 1, in) return finish stksys(in) eval(in, eachval) in = unstksys finish else stack(false) return ! END IFTRUE ! ! sysfun(52): !IFFALSE if tstflg = 0 then start if in = nil then start error("NULL INSTRUCTION", empty, 1, in) return finish stksys(in) eval(in, eachval) in = unstksys finish else stack(true) return ! END IFFALSE ! ! sysfun(53): !IF condlist = hd(in) if condlist = nil then start error("NULL CONDITION", empty, 1, in) return finish stksys(in) eval(condlist, eachval) ! EVAL CONDITION in = unstksys if jumpflag = 1 then return cond = unstack ! RESULT OF CONDITION tbranch = hd(tl(in)) fbranch = tl(tl(in)) if cond = true then start !THEN if tbranch = nil then start error("NULL THEN CLAUSE", empty, 1, in) return finish else start ! EVAL TBRANCH if hd(tbranch) = start then start ! EVAL START...FINISH res = evalstartfin(tbranch) if jumpflag = 1 then return if goflag = 1 then return ! JUMP INSTR finish else start ! NOT START...FINISH stksys(in) eval(tbranch, eachval) dumlab: in = unstksys if jumpflag = 1 then return res = unstack finish finish ! FINISH EVAL TBRANCH finish else start !FINISH THEN if cond = false then start ! ELSE if fbranch = nil then res = nil else start if hd(fbranch) = start then start ! EVAL START...FINISH res = evalstartfin(fbranch) if jumpflag = 1 then return if goflag = 1 then return ! JUMP INSTR finish else start stksys(in) eval(fbranch, eachval) in = unstksys if jumpflag = 1 then return res = unstack finish finish finish else start error("BAD CONDITION", empty, 1, in) return finish finish stack(res) return ! END IF ! ! sysfun(54): !WHILE condlist = hd(in) tbranch = hd(tl(in)) if condlist = nil then start error("NULL CONDITION", empty, 1, in) return finish if tbranch = nil then start error("NULL THEN CLAUSE", empty, 1, in) return finish res = nil ! RESULT IF COND FALSE FIRST TIME ROUND cycle stksys(condlist) stksys(tbranch) stksys(in) eval(condlist, eachval) ! EVAL CONDITION in = unstksys tbranch = unstksys condlist = unstksys if jumpflag = 1 then return cond = unstack exit if cond = false unless cond = true then start error("BAD CONDITION", empty, 1, in) return finish if hd(tbranch) = start then start ! START...FINISH res = evalstartfin(tbranch) if jumpflag = 1 then return if goflag = 1 then return finish else start stksys(condlist) stksys(tbranch) stksys(in) eval(tbranch, eachval) in = unstksys tbranch = unstksys condlist = unstksys if jumpflag = 1 then return res = unstack finish if fun # nil and curfun = nil then exit ! SPECIAL TEST FOR RESULT repeat stack(res) return ! END WHILE ! ! sysfun(61): !EDIT arg1 = unstack if arg1 & wm # wm then start error("EDIT MUST HAVE A WORD AS ARGUMENT - ", arg1, 1, in) return finish arg2 = fnval(arg1 >> 8) ! GET SPEC if arg2 = 0 then start error("PROCEDURE FOR EDIT UNDEFINED - ", arg1, 1, in) return finish if arg2 & userpre # userpre then start error("SYSTEM PROCEDURE CANNOT BE EDITED - ", arg1, 1, in) return finish if sourceptr + 2 * fnlen(arg1 >> 8) + 64 > maxsource C then baderror("SOURCE FILE SPACE OVERFLOW", empty) oldfn(arg1 >> 8) = fnlen(arg1 >> 8) << 16 ! fntext(arg1 >> 8) newfn = fromlist(arg1, newfn) unless newfn = nil edit(arg1) unless fnparse(arg1 >> 8) = 255 then newfn = cons(arg1, newfn) device = tty nooline(1) printel(arg1) prstring(" EDITED") nooline(1) stack(arg1) return ! END EDIT ! ! sysfun(62): !MAKE arg1 = unstack arg2 = unstack if arg1 & wm # wm then start error("MAKE MUST HAVE A WORD AS FIRST ARGUMENT - ", arg1, 1, in) return finish setval(arg1, arg2, envir) stack(arg2) return ! END MAKE ! ! sysfun(63): !NEW arg1 = unstack if arg1 & wm = wm then arg1 = cons(arg1, nil) else chklist(arg1) if jumpflag = 1 then return arg2 = listlen(arg1) if arg2 = 0 then stack(nil) and return if envir = basenvir then start ! CREATE GLOBALS cycle arg3 = 1, 1, arg2 setval(hd(arg1), nil, envir) arg1 = tl(arg1) repeat finish else start ! CREATE LOCALS cycle arg3 = 1, 1, arg2 stack(nil) ! VALUES ONTO STACK repeat envir = setbind(arg1, envir) finish stack(nil) return ! END NEW ! ! sysfun(64): !GO arg1 = unstack if arg1 & nm # nm then start error("GO NEEDS A NUMBER - ", arg1, 1, in) return finish stack(arg1) goflag = 1 return ! END GO ! ! ! sysfun(65): !STOP curfun = nil !CURFUN=CONS(NIL,NIL); ! APPLYUSR STOPS WHEN A SINGLE LINE LEFT stack(true) return ! END STOP ! ! sysfun(66): !RESULT(OUTPUT) curfun = nil !CURFUN=CONS(NIL,NIL) ! STACK(UNSTACK) return ! END RESULT ! ! sysfun(70): !SHOW arg1 = unstack if arg1 & wm = wm then arg1 = cons(arg1, nil) if arg1 & lm # lm then start nooline(1) error1("NON-WORD FOR SHOW - ", arg1) -> sh2 finish while arg1 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg1) error("USER INTERRUPT", empty, 0, in) arg1 = unstksys if jumpflag = 1 then return finish arg2 = hd(arg1) arg1 = tl(arg1) nooline(1) if arg2 & wm # wm then start error1("NON WORD FOR SHOW - ", arg2) -> sh1 finish arg3 = fnval(arg2 >> 8) ! GET SPEC if arg3 = 0 then start error1("UNDEFINED PROCEDURE FOR SHOW - ", arg2) -> sh1 finish if arg3 & userpre # userpre then start error1("SYSTEM PROCEDURE FOR SHOW - ", arg2) -> sh1 finish arg3 = fntext(arg2 >> 8) until source(arg4) = 'E' and source(arg4 + 1) = 'N' C and source(arg4 + 2) = 'D' cycle arg4 = arg3 printfnline(arg3) repeat sh1: repeat sh2: stack(true) return ! END SHOW ! ! sysfun(71): !SHOWTITLES arg2 = -1 nooline(1) cycle arg1 = 0, 1, 1022 if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 error("USER INTERRUPT", empty, 0, in) if jumpflag = 1 then return finish if fnval(arg1) & userpre = userpre then start arg2 = fntext(arg1) printfnline(arg2) finish !PRINTLINE(HD(FNVAL(ARG1)&M16!LM)) %AND ARG2=1 repeat if arg2 < 0 then prstring("NO USER PROCEDURES DEFINED YET") C and nooline(1) stack(true) return ! END SHOWTITLES ! ! sysfun(72): !SHOWALL arg2 = -1 cycle arg1 = 0, 1, 1022 if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 error("USER INTERRUPT", empty, 0, in) if jumpflag = 1 then return finish if fnval(arg1) & userpre = userpre then start nooline(1) arg2 = fntext(arg1) until source(arg3) = 'E' and source(arg3 + 1) = 'N' C and source(arg3 + 2) = 'D' cycle arg3 = arg2 printfnline(arg2) repeat finish repeat if arg2 < 0 then start nooline(1) prstring("NO USER PROCEDURES DEFINED YET") nooline(1) finish stack(true) return ! END SHOWALL ! ! sysfun(73): !SHOWNEW nooline(1) if newfn = nil then start prstring("NO NEW PROCEDURES") nooline(1) stack(true) return finish arg2 = newfn while arg2 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg2) error("USER INTERRUP", empty, 0, in) arg2 = unstksys if jumpflag = 1 then return finish arg1 = hd(arg2) arg3 = fntext(arg1 >> 8) printfnline(arg3) arg2 = tl(arg2) repeat stack(true) return ! END SHOWNEW ! ! sysfun(74): !OLDDEF arg1 = unstack if arg1 & wm # wm then start error("OLDDEF MUST HAVE A WORD FOR ARGUMENT - ", arg1, 1, in) return finish if oldfn(arg1 >> 8) = 0 then start error(" NO STANDBY DEF FOR PROCEDURE - ", arg1, 1, in) return finish newfn = fromlist(arg1, newfn) unless newfn = nil arg2 = fnlen(arg1 >> 8) << 16 ! fntext(arg1 >> 8) fntext(arg1 >> 8) = oldfn(arg1 >> 8) & X'FFFF' fnlen(arg1 >> 8) = oldfn(arg1 >> 8) >> 16 w1 = checkfnhead(arg1) if w1 = fault then fnparse(arg1 >> 8) = 255 oldfn(arg1 >> 8) = arg2 newfn = cons(arg1, newfn) unless w1 = fault prstring("STANDBY DEFINITION OF ") prstring(wa(arg1 >> 8) . " RESTORED") nooline(1) stack(arg1) return ! END OLDDEF ! ! sysfun(75): !GETFILE arg1 = unstack if arg1 & wm # wm then start error("GETFILE MUST HAVE A WORD AS ARGUMENT - ", arg1, 1, in) return finish userfile = wa(arg1 >> 8) if cactfile = 2 then getmaster mdind = findfile if jumpflag = 1 then stack(mdind) and return cactfile = 1 if mdind < 0 then start ! FILE NOT FOUND IN MASTER DIRECTORY cluserfl claimmaster ! OPEN MASTERFILE FOR WRITE,UNSHARED ACCESS if jumpflag = 1 then return if mdents = 62 then getpage(3) else getpage(2) mdents = mdents + 1 mdind = mdents udnam(mdents) = userfile udpage(mdents) = udp nooline(1) printel(arg1) prstring(" CREATED") freemaster ! FREE MASTERFILE FOR SHARED ACCESS finish nooline(1) printel(arg1) prstring(" ACTIVE") nooline(1) stack(true) return ! END GETFILE ! ! sysfun(76): !LOADDOT arg1 = unstack if cactfile = 0 then start error("NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish nooline(1) if arg1 & wm = wm then arg1 = cons(arg1, nil) if arg1 & lm # lm C then error1("LOAD CANNOT HAVE A NUMBER AS ARGUMENT - ", arg1) C and -> ld5 if cactfile = 2 then start gothdir if jumpflag = 1 then return finish libload = 1 mdmap(filstart + mdp * 4096) udp = 0 while arg1 # nil cycle w1 = hd(arg1) arg1 = tl(arg1) if w1 & wm # wm then start error1("NON-WORD FOR LOAD - ", w1) -> ld3 finish if udp = udpage(mdind) then -> ld2 else getudp if udents = 0 then start prstring("NO USER PROCEDURES SAVED") nooline(1) -> ld4 finish -> ld2 ld1: udmap(filstart + udp * 4096) ld2: arg2 = 1 while arg2 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) -> ld4 finish if holdflag = 1 then start holdflag = 0 libload = 0 device = tty if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg2 = 61 then udp = udnext and -> ld1 if funnam(arg2) = wa(w1 >> 8) then start txtmap(filstart + txtpage(arg2) * 4096) index = shortint(txtind(1, arg2)) device = disc starttext = sourceptr until headin = end cycle readinline(promp) copyline repeat newfn = fromlist(w1, newfn) unless newfn = nil if fntext(w1 >> 8) # 0 C then oldfn(w1 >> 8) = fnlen(w1 >> 8) << 16 ! fntext(w1 >> 8) fnlen(w1 >> 8) = sourceptr - starttext fntext(w1 >> 8) = starttext arg3 = checkfnhead(w1) if arg3 = fault then fnparse(w1 >> 8) = 255 C else newfn = cons(w1, newfn) prstring(wa(w1 >> 8)) prstring(" LOADED") nooline(1) -> ld3 finish arg2 = arg2 + 1 repeat prstring(wa(w1 >> 8)) prstring(" NOT SAVED") nooline(1) ld3: repeat ld4: device = tty if cactfile = 2 then frothdir libload = 0 ld5: unless jumpflag = 1 then stack(true) return ! END LOAD ! ! sysfun(77): !SAVE arg3 = unstack if cactfile = 0 then start error(" NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start error("CANNOT SAVE TO A LIBRARY FILE", empty, 1, in) return finish nooline(1) if arg3 & wm = wm then arg3 = cons(arg3, nil) if arg3 & lm # lm then error1("NON-WORD FOR SAVE - ", arg3) C and -> save2 cluserfl claimmaster if jumpflag = 1 then return mdmap(filstart + mdp * 4096) endmap device = disc while arg3 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 device = tty freemaster stack(quit) return finish if holdflag = 1 then start holdflag = 0 device = tty freemaster error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish arg1 = hd(arg3) arg3 = tl(arg3) if arg1 & wm # wm then start error1(" NON-WORD FOR SAVE - ", arg1) -> saverep finish arg2 = fnparse(arg1 >> 8) if arg2 = 255 then start error1("PROCEDURE HAS FAULTY FIRST LINE", arg1) -> saverep finish arg2 = fnval(arg1 >> 8) if arg2 = 0 then start error1(" UNDEFINED PROCEDURE FOR SAVE - ", arg1) -> saverep finish if arg2 & userpre # userpre then start error1("YOU CANNOT SAVE A SYSTEM PROCEDURE - ", arg1) -> saverep finish mapend w1 = fntext(arg1 >> 8) ! START OF TEXT w2 = w1 + fnlen(arg1 >> 8) ! END OF TEXT until w1 >= w2 cycle w3 = w1 ! SAVE PTR TO START OF LINE printfnline(w1) repeat ! ! UPDATE DIRECTORY updir(arg1) ! newfn = fromlist(arg1, newfn) unless newfn = nil prstring(wa(arg1 >> 8)) prstring(" SAVED") nooline(1) saverep: repeat device = tty freemaster save2: stack(true) return ! END SAVE ! ! sysfun(78): !SAVENEW if cactfile = 0 then start error("NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start error("CANNOT SAVE TO A LIBRARY FILE", empty, 1, in) return finish nooline(1) if newfn = nil then start prstring("NO USER PROCEDURES DEFINED OR EDITED YET") nooline(1) stack(true) return finish cluserfl claimmaster if jumpflag = 1 then return mdmap(filstart + mdp * 4096) endmap device = disc while newfn # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 device = tty freemaster stack(quit) return finish if holdflag = 1 then start holdflag = 0 device = tty freemaster error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish mapend arg1 = hd(newfn) w1 = fntext(arg1 >> 8) ! START OF TEXT w2 = w1 + fnlen(arg1 >> 8) ! END OF TEXT until w1 >= w2 cycle w3 = w1 ! SAVE PTR TO START OF LINE printfnline(w1) repeat ! UPDATE DIR updir(arg1) prstring(wa(arg1 >> 8)) prstring(" SAVED") nooline(1) newfn = tl(newfn) repeat device = tty freemaster stack(true) return ! END SAVENEW ! ! sysfun(79): !FORGET arg3 = unstack if cactfile = 0 then start error(" NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start error("CANNOT FORGET LIBRARY PROCEDURES", empty, 1, in) return finish nooline(1) if arg3 & wm = wm then arg3 = cons(arg3, nil) if arg3 & lm # lm then start error1("FORGET CANNOT HAVE A NUMBER AS ARGUMENT - ", arg3) stack(true) return finish cluserfl claimmaster if jumpflag = 1 then return udp = 0 mdmap(filstart + mdp * 4096) while arg3 # nil cycle arg1 = hd(arg3) arg3 = tl(arg3) if arg1 & wm # wm then start error1(" NON-WORD FOR FORGET - ", arg1) -> fg3 finish if udp = udpage(mdind) then -> fg2 else getudp if udents = 0 then start prstring("NO USER PROCEDURES SAVED") nooline(1) -> fg4 finish fg1: udmap(filstart + udp * 4096) fg2: arg2 = 1 while arg2 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 freemaster stack(quit) return finish if holdflag = 1 then start holdflag = 0 freemaster error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg2 = 61 then udp = udnext and -> fg1 if funnam(arg2) = wa(arg1 >> 8) then start funnam(arg2) = "" txtpage(arg2) = 0 prstring(wa(arg1 >> 8) . " FORGOTTEN") nooline(1) -> fg3 finish ! SPACES IN USER DIR ONLY AT MOMENT arg2 = arg2 + 1 repeat prstring(wa(arg1 >> 8)) prstring(" NOT SAVED") nooline(1) fg3: repeat fg4: freemaster stack(true) return ! END FORGET ! ! sysfun(80): !SHOWSAVEDTITLES if cactfile = 0 then start error("NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start gothdir if jumpflag = 1 then return finish mdmap(filstart + mdp * 4096) udp = udpage(mdind) txtp = 0 nooline(1) ss5: udmap(filstart + udp * 4096) arg2 = 1 if udents = 0 then start prstring("NO USER PROCEDURES SAVED YET") nooline(1) -> ss6 finish while arg2 <= udents cycle if arg2 = 61 then udp = udnext and -> ss5 if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 if cactfile = 2 then frothdir stack(quit) return finish if holdflag = 1 then start holdflag = 0 if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if txtpage(arg2) = 0 then start prstring("FORGOTTEN PROCEDURE") nooline(1) finish else start unless txtp = txtpage(arg2) then gettxtp(arg2) index = shortint(txtind(1, arg2)) device = disc arg3 = readline device = tty printline(arg3) finish arg2 = arg2 + 1 repeat ss6: if cactfile = 2 then frothdir stack(true) return ! END SHOWSAVEDTITLES ! ! sysfun(81): !SHOWSAVED arg1 = unstack if cactfile = 0 then start error(" NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if arg1 & wm = wm then arg1 = cons(arg1, nil) if arg1 & lm # lm then start nooline(1) error1("SHOWSAVED CANNOT HAVE A NUMBER AS ARGUMENT - ", arg1) -> ss10 finish if cactfile = 2 then start gothdir if jumpflag = 1 then return finish mdmap(filstart + mdp * 4096) udp = 0 while arg1 # nil cycle w1 = hd(arg1) arg1 = tl(arg1) nooline(1) if w1 & wm # wm then start error1(" NON-WORD FOR SHOWSAVED - ", w1) -> ss3 finish if udp = udpage(mdind) then -> ss2 else getudp if udents = 0 then start prstring("NO USER PROCEDURES SAVED") nooline(1) -> ss4 finish -> ss2 ss1: udmap(filstart + udp * 4096) ss2: arg3 = 1 while arg3 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 if cactfile = 2 then frothdir stack(quit) return finish if arg3 = 61 then udp = udnext and -> ss1 if holdflag = 1 then start holdflag = 0 if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if funnam(arg3) = wa(w1 >> 8) then start txtmap(filstart + txtpage(arg3) * 4096) index = shortint(txtind(1, arg3)) rl: device = disc arg2 = readline device = tty printline(arg2) if hd(arg2) = end then -> ss3 -> rl finish arg3 = arg3 + 1 repeat prstring(wa(w1 >> 8)) prstring(" NOT SAVED") nooline(1) ss3: repeat ss4: if cactfile = 2 then frothdir ss10: stack(true) return ! END SHOWSAVED ! ! sysfun(82): !SHOWSAVEDALL if cactfile = 0 then start error("NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start gothdir if jumpflag = 1 then return finish mdmap(filstart + mdp * 4096) udp = udpage(mdind) txtp = 0 ssall1: udmap(filstart + udp * 4096) if udents = 0 then start nooline(1) prstring("NO USER PROCEDURES SAVED YET") nooline(1) -> ssall2 finish arg2 = 1 while arg2 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 if cactfile = 2 then frothdir stack(quit) return finish if holdflag = 1 then start holdflag = 0 if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg2 = 61 then udp = udnext and -> ssall1 if txtpage(arg2) = 0 then start prstring("FORGOTTEN PROCEDURE") nooline(1) finish else start unless txtp = txtpage(arg2) then gettxtp(arg2) nooline(1) index = shortint(txtind(1, arg2)) cycle device = disc arg3 = readline device = tty printline(arg3) if hd(arg3) = end then exit repeat finish arg2 = arg2 + 1 repeat ssall2: if cactfile = 2 then frothdir stack(true) return ! END SHOWSAVEDALL ! ! sysfun(83): !LOADSAVED if cactfile = 0 then start error(" NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start gothdir if jumpflag = 1 then return finish mdmap(filstart + mdp * 4096) udmap(filstart + udpage(mdind) * 4096) nooline(1) if udents = 0 then start prstring(" NO USER PROCEDURES SAVED YET") nooline(1) if cactfile = 2 then frothdir stack(true) return finish txtp = 0 libload = 1 ls1: arg1 = 1 while arg1 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) -> ls3 finish if holdflag = 1 then start holdflag = 0 device = tty libload = 0 if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg1 = 61 then udmap(filstart + udnext * 4096) and -> ls1 if txtpage(arg1) = 0 then -> ls2 unless txtp = txtpage(arg1) then gettxtp(arg1) index = shortint(txtind(1, arg1)) device = disc starttext = sourceptr until headin = end cycle readinline(promp) copyline repeat arg2 = hash(funnam(arg1)) newfn = fromlist(arg2, newfn) unless newfn = nil if fntext(arg2 >> 8) # 0 C then oldfn(arg2 >> 8) = fnlen(arg2 >> 8) << 16 ! fntext(arg2 >> 8) fnlen(arg2 >> 8) = sourceptr - starttext fntext(arg2 >> 8) = starttext arg3 = checkfnhead(arg2) if arg3 = fault then fnparse(arg2 >> 8) = 255 C else newfn = cons(arg2, newfn) ls2: arg1 = arg1 + 1 repeat stack(true) ls3: device = tty if cactfile = 2 then frothdir libload = 0 return ! END LOADSAVED ! ! sysfun(84): !DESTROY arg1 = unstack nooline(1) if arg1 & wm = wm then arg1 = cons(arg1, nil) if arg1 & lm # lm then start error1("DESTROY MUST HAVE A WORD AS ARGUMENT -", arg1) stack(true) return finish unless cactfile = 2 then cluserfl claimmaster if jumpflag = 1 then return mdmap(filstart) if mdents = 0 then start prstring("NO FILES CREATED YET") nooline(1) -> d4 finish while arg1 # nil cycle arg2 = hd(arg1) arg1 = tl(arg1) if arg2 & wm # wm then start error1("NON-WORD FOR DESTROY - ", arg2) -> d3 finish mdmap(filstart) d2: arg3 = 1 while arg3 <= mdents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 freemaster stack(quit) return finish if holdflag = 1 then start holdflag = 0 freemaster error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg3 = 63 then mdmap(filstart + mdnext * 4096) and -> d2 if udnam(arg3) = wa(arg2 >> 8) then start udnam(arg3) = "" udpage(arg3) = 0 prstring(wa(arg2 >> 8) . " DESTROYED") nooline(1) if userfile = wa(arg2 >> 8) and owner = emasuser C then nofile -> d3 finish arg3 = arg3 + 1 repeat prstring(wa(arg2 >> 8) . " DOES NOT EXIST") nooline(1) d3: repeat d4: freemaster stack(true) return ! END DESTROY ! ! sysfun(85): !BORROWFILE chlib if jumpflag = 1 then return unless cactfile = 2 then cluserfl owner = wstr1 userfile = wa(arg2 >> 8) gothdir if jumpflag = 1 then return frothdir cactfile = 2 nooline(1) printel(arg1) prstring(" ") printel(arg2) prstring(" EXISTS") nooline(1) stack(true) return ! END BORROWFILE ! ! sysfun(86): !LIBRARY chlib if jumpflag = 1 then return savefile unless cactfile = 2 then closesm(4) and clear("4") ! MAP ONTO LIB OWNER"S DIRECTORY userfile = wa(arg2 >> 8) gothdir if jumpflag = 1 then return ! GET LIBRARY DIR cactfile = cactfile + 1 libload = 1 udp = udpage(mdind) lib1: udmap(filstart + udp * 4096) arg1 = 1 while arg1 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) exit finish if holdflag = 1 then start holdflag = 0 device = tty cactfile = cactfile - 1 frothdir restfile libload = 0 error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg1 = 61 then udp = udnext and -> lib1 unless txtpage(arg1) = 0 then start unless txtp = txtpage(arg1) then gettxtp(arg1) index = shortint(txtind(1, arg1)) device = disc starttext = sourceptr until headin = end cycle readinline(promp) copyline repeat arg2 = hash(funnam(arg1)) newfn = fromlist(arg2, newfn) unless newfn = nil if fntext(arg2 >> 8) # 0 C then oldfn(arg2 >> 8) = fnlen(arg2 >> 8) << 16 ! fntext(arg2 >> 8) fnlen(arg2 >> 8) = sourceptr - starttext fntext(arg2 >> 8) = starttext arg3 = checkfnhead(arg2) if arg3 = fault then fnparse(arg2 >> 8) = 255 C else newfn = cons(arg2, newfn) finish arg1 = arg1 + 1 repeat device = tty cactfile = cactfile - 1 frothdir restfile libload = 0 if jumpflag # 1 then stack(true) return ! END LIBRARY ! ! sysfun(87): !FILEINFO if cactfile = 0 then start error("NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start gothdir if jumpflag = 1 then return finish arg1 = fnents nooline(1) prstring("NO OF ENTRIES IN FILE DIRECTORY= ") write(arg1, 6) nooline(1) prstring("NXT FREE PAGE IN USER TEXT AREA =") write(endtxt + 1, 6) nooline(1) prstring("NXT FREE INDEX =") write(shortint(endind(1)), 6) nooline(1) if udp # udpage(mdind) then getudp if udents = 0 then -> fi2 fi1: arg1 = 1 while arg1 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 if cactfile = 2 then frothdir stack(quit) return finish if holdflag = 1 then start holdflag = 0 if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg1 = 61 then start udp = udnext udmap(filstart + udp * 4096) -> fi1 finish nooline(1) if funnam(arg1) = "" then start prstring(" FORGOTTEN PROCEDURE") nooline(1) finish else start prstring(" ENTRY NO = ") write(arg1, 6) nooline(1) prstring(" STARTING PAGE =") write(txtpage(arg1) + 1, 6) nooline(1) prstring(" STARTING INDEX =") write(shortint(txtind(1, arg1)), 6) nooline(1) prstring(" TEXT =") nooline(2) unless txtp = txtpage(arg1) then gettxtp(arg1) index = shortint(txtind(1, arg1)) cycle device = disc arg2 = readline device = tty printline(arg2) if hd(arg2) = end then exit repeat finish arg1 = arg1 + 1 repeat fi2: stack(true) if cactfile = 2 then frothdir return ! END FILEINFO ! ! sysfun(88): !LISTFILE if cactfile = 0 then start error(" NO FILE CURRENTLY ACTIVE", empty, 1, in) return finish if cactfile = 2 then start gothdir if jumpflag = 1 then return finish arg1 = fnents if udents = 0 then start printstring("FILE EMPTY") newline -> lf3 finish define("10,.LP") ! USUALLY .LP selectoutput(10) newline printstring("****** PROCEDURE DIRECTORY FOR ") if owner = "" then printstring("USER ") C else printstring("LIBRARY ") printstring("FILE " . userfile . " ******") newlines(2) printstring(" NO OF PROCEDURES SAVED/FORGOTTEN = ") write(arg1, 8) newline printstring(" ENTRY NO START PAGE START INDEX PROCEDURE NAME") if udp # udpage(mdind) then getudp lf1: arg1 = 1 while arg1 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) -> lf4 finish if holdflag = 1 then start holdflag = 0 selectoutput(0) closestream(10) clear("10") if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg1 = 61 then start udp = udnext udmap(filstart + udp * 4096) -> lf1 finish newline write(arg1, 6) if funnam(arg1) = "" then start spaces(7) printstring(" FORGOTTEN PROCEDURE ") -> rep136 finish spaces(10) write(txtpage(arg1) + 1, 6) spaces(8) write(shortint(txtind(1, arg1)), 6) spaces(8) printstring(funnam(arg1)) rep136: arg1 = arg1 + 1 repeat newlines(2) printstring("****** TEXT AREA ******") if udp # udpage(mdind) then getudp txtp = 0 lf2: arg1 = 1 while arg1 <= udents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) -> lf4 finish if holdflag = 1 then start holdflag = 0 selectoutput(0) closestream(10) clear("10") if cactfile = 2 then frothdir error("USER INTERRUPT - PROCESS ABANDONNED", empty, 11, in) return finish if arg1 = 61 then start udp = udnext udmap(filstart + udp * 4096) -> lf2 finish unless funnam(arg1) = "" then start unless txtp = txtpage(arg1) then gettxtp(arg1) arg2 = shortint(txtind(1, arg1)) newline lff: printsymbol(fntxt(arg2)) if fntxt(arg2) = termin then start arg2 = arg2 + 1 if arg2 > shortint(txtents(1)) then -> lf5 chkind(arg2) if fntxt(arg2) = 'T' then -> lf5 finish else arg2 = arg2 + 1 and chkind(arg2) -> lff finish lf5: arg1 = arg1 + 1 repeat lf4: selectoutput(0) closestream(10) clear("10") lf3: if cactfile = 2 then frothdir unless jumpflag = 1 then stack(true) return ! END LISTFILE ! ! sysfun(89): !SHOWFILES if cactfile = 2 then getmaster mdmap(filstart) nooline(1) if mdents = 0 then prstring("NO FILES CREATED YET") and -> sf2 prstring(" LOGO MASTER DIRECTORY ") nooline(2) prstring(" ENTRY NO FILENAME ") sf1: arg1 = 1 while arg1 <= mdents cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 if cactfile = 2 then cluserfl stack(quit) return finish if holdflag = 1 then start holdflag = 0 if cactfile = 2 then cluserfl error("USER INTERRUPT - PROCESS ABANDONNED", empty, 1, in) return finish if arg1 = 63 then mdmap(filstart + mdnext * 4096) and -> sf1 nooline(1) write(arg1, 9) spaces(9) if udnam(arg1) = "" then prstring("FORGOTTEN FILE") else start prstring(udnam(arg1)) finish arg1 = arg1 + 1 repeat sf2: nooline(1) stack(true) if cactfile = 2 then cluserfl return ! END SHOWFILES ! ! sysfun(90): !SUPERQUIT jumpflag = 1 jumpout = 100 superjmp = 1 stack(fn) return ! END SUPERQUIT ! ! sysfun(91): !ABORT arg1 = unstack if arg1 & nm # nm or arg1 < 0 then start error("ABORT MUST HAVE A POSITIVE NUMBER AS ARGUMENT - ", arg1, C 1, in) return finish jumpflag = 1 jumpout = arg1 >> 8 stack(fn) return ! END ABORT ! ! sysfun(92): !QUIT jumpflag = 1 jumpout = 100 stack(fn) return ! END QUIT ! ! sysfun(93): !CONTINUE if severity = 1 then start error("CANNOT CONTINUE FROM LAST ERROR", empty, 1, in) return finish jumpflag = 1 jumpout = -1 stack(fn) return ! END CONTINUE ! ! sysfun(94): !SENDBACK arg1 = unstack ! VALUE TO BE SENT arg2 = unstack ! FN TO BE SENT TO OR NUMBER OF FNS TO BE EXITED if arg2 & nm = nm then start if arg2 < 0 then start error("NEGATIVE SECOND ARG FOR SENDBACK - ", empty, 1, in) return finish sendflag = arg2 >> 8 ! NO OF RETURNS jumpflag = 1 stack(arg1) return finish if arg2 & wm # wm then start error("SENDBACK TO WHERE? ", arg2, 1, in) return finish w1 = envir ! CURRENT ENVIR TOP arg3 = 0 while w1 > basenvir cycle while bname(w1) # 0 cycle w1 = w1 - 1 repeat w2 = bvalue(w1) ! FN ENTERED w1 = w1 - 1 ! NEXT ENVIR TOP if w2 = arg2 then start ! FOUND IT sendflag = arg3 + 1 ! NO OF RETURNS TO BE MADE TO GET THERE jumpflag = 1 stack(arg1) return finish else start ! NOT THE RIGHT FN if w2 # logoname then arg3 = arg3 + 1 ! SO INC NO OF RETURNS, UNLESS LOGO finish repeat ! GETS HERE IF FN NOT FOUND AT CURRENT LEVEL error("FN FOR SENDBACK NOT OUTSTANDING - ", arg2, 1, in) return ! END SENDBACK ! ! sysfun(95): !BREAK arg1 = in nooline(1) if arg1 = nil then printel(break) while arg1 # nil cycle printel(hd(arg1)) space arg1 = tl(arg1) repeat error("", empty, 0, in) if jumpflag = 1 then return ! ABORT OR QUIT stack(break) ! RESULT FOR CONTINUE return ! FROM CONTINUE. END BREAK ! ! sysfun(96): !CALLUSER arg1 = envir nooline(1) prstring("CALLUSER CALLED FROM:-") if arg1 = basenvir then start printel(logoname) nooline(1) finish else start arg2 = arg1 while bname(arg2) # 0 cycle arg2 = arg2 - 1 repeat printel(bvalue(arg2)) ! FN NAME nooline(1) if arg2 = arg1 then start prstring("NO LOCALS") nooline(1) finish else start arg2 = arg2 + 1 while arg2 <= arg1 cycle spaces(2) printel(bname(arg2)) prstring(":-") printel(bvalue(arg2)) nooline(1) arg2 = arg2 + 1 repeat finish finish rl107: arg3 = stkpnt ! SAVV STACK readinline("RESULT:") plevel = 0 arg1 = parseline(0) if arg1 = fault then stkpnt = arg3 and -> rl107 stksys(in) eval(arg1, eachval) in = unstksys if jumpflag = 1 then start ! SPECIAL FOR RETRY if superjmp = 1 then return jumpflag = 0 jumpout = 0 sendflag = 0 stkpnt = arg3 -> rl107 finish prompt(promp) ! STACK(UNSTACK) return ! END CALLUSER ! ! sysfun(97): !FNCALLS arg1 = envir nooline(1) while arg1 > 1022 cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 error("USER INTERRUPT", empty, 0, in) if jumpflag = 1 then return finish if bname(arg1) = 0 then start printel(bvalue(arg1)) nooline(1) finish arg1 = arg1 - 1 repeat printel(logoname) nooline(1) stack(logoname) return ! END FNCALLS ! ! sysfun(98): !FNVALS arg1 = envir nooline(1) while arg1 > 1022 cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 error("USER INTERRUPT", empty, 0, in) if jumpflag = 1 then return finish arg2 = arg1 while bname(arg2) # 0 cycle arg2 = arg2 - 1 repeat ! ARG2 POINTS TO CURRENT BOTTOM printel(bvalue(arg2)) ! FUNCTION NAME prstring(":-") nooline(1) arg3 = arg2 + 1 while arg3 <= arg1 cycle spaces(4) printel(bname(arg3)) space printel(bvalue(arg3)) nooline(1) arg3 = arg3 + 1 repeat nooline(1) arg1 = arg2 - 1 repeat printel(logoname) nooline(1) stack(logoname) return ! END FNVALS ! ! sysfun(99): !ABBREV redef = 0 arg1 = unstack arg2 = unstack if arg1 & wm # wm then start error("ABBREV MUST HAVE A WORD AS FIRST ARGUMENT - ", arg1, 1, in) return finish if arg2 & wm # wm then start error("ABBREV MUST HAVE A WORD AS SECOND ARGUMENT - ", arg2, 1, in) return finish if fnval(arg1 >> 8) = 0 then start error("UNDEFINED PROCEDURE FOR ABBREV - ", arg1, 1, in) return finish ! SO ARG1 OK arg3 = fnval(arg2 >> 8) ! GET SPEC FOR ABBREVIATION if arg3 = 0 then -> transpec ! UNDEFINED SO OK if arg3 & userpre = userpre then start redef = 1 newfn = fromlist(arg2, newfn) unless newfn = nil -> transpec finish ! ALREADY DEFINED BY USER error("YOU CANNOT USE ONE OF LOGOS OWN PROCEDURE NAMES" . " AS AN ABBREVIATION - ", arg2, 1, in) return transpec: w1 = arg1 >> 8 w2 = arg2 >> 8 fnval(w2) = fnval(w1) fnparse(w2) = fnparse(w1) fnlen(w2) = fnlen(w1) fntext(w2) = fntext(w1) printel(arg2) prstring(" IS") if redef = 1 then prstring(" REDEFINED") else prstring(" DEFINED") prstring(" AS AN ABBREVIATION FOR ") printel(arg1) nooline(1) stack(arg1) return ! END ABBREV ! ! sysfun(100): !MFIRST arg1 = unstack arg2 = unstack if arg1 & lm # lm or arg1 = nil then start error("MFIRST MUST HAVE A NON-NULL LIST AS FIRST ARGUMENT -", C arg1, 1, in) return finish if (arg1 >> 8) >= lafnb then start ! LIST EMBEDDED IN FN DEFN error("LIST EMBEDDED IN PROCEDURE DEFN CANNOT BE UPDATED - ", C arg1, 1, in) return finish rephead(arg1, arg2) stack(arg2) return ! END MFIRST ! ! sysfun(101): !MBUTFIRST arg1 = unstack arg2 = unstack if arg1 & lm # lm or arg1 = nil then start error("MBUTFIRST MUST HAVE A NON EMPTY LIST AS FIRST ARGUMENT - ", arg1, 1, in) return finish if (arg1 >> 8) >= lafnb then start error("LIST EMBEDDED IN PROCEDURE DEFN CANNOT BE UPDATED - ", C arg1, 1, in) return finish if arg2 & lm # lm then start error("MBUTFIRST MUST HAVE A LIST AS SECOND ARGUMENT - ", arg2, C 1, in) return finish reptail(arg1, arg2) stack(arg2) return ! END MBUTFIRST ! ! sysfun(102): !PACK arg1 = unstack if arg1 & lm # lm then start error("PACK MUST HAVE A LIST AS ARGUMENT - ", arg1, 1, in) return finish wstr1 = "" while arg1 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg1) error("USER INTERRUPT", empty, 0, in) arg1 = unstksys if jumpflag = 1 then return finish arg2 = hd(arg1) if arg2 & nm = nm then start arg3 = arg2 >> 8 if arg3 >= 0 and arg3 <= 9 then start wstr2 = numtostr(arg2) -> packok finish finish else start if arg2 & wm = wm then start wstr2 = wa(arg2 >> 8) if length(wstr2) = 1 then -> packok finish finish error("CAN ONLY PACK SINGLE LETTERS OR DIGITS - ", arg2, 1, in) return packok: if length(wstr1) = 64 then start error("WORD LENGTH EXCEEDED - ", arg1, 1, in) return finish wstr1 = wstr1 . wstr2 arg1 = tl(arg1) repeat stack(put(wstr1)) return !END PACK ! ! sysfun(103): !UNPACK arg1 = unstack if arg1 & lm = lm then start error("UNPACK MUST HAVE A WORD OR NUMBER AS ARGUMENT - ", arg1, C 1, in) return finish if arg1 & nm = nm then wstr1 = numtostr(arg1) C else wstr1 = wa(arg1 >> 8) arg1 = nil arg2 = length(wstr1) while arg2 # 0 cycle w1 = put(fromstring(wstr1, arg2, arg2)) arg1 = cons(w1, arg1) arg2 = arg2 - 1 repeat stack(arg1) return !END UNPACK ! ! sysfun(104): !COMPRESS device = disc filetidy ! ASSUME USER IDENTIFIED if jumpflag = 1 then return device = tty unless cactfile = 2 then getmaster stack(true) return ! END COMPRESS ! ! sysfun(105): !GOODBYE device = disc filetidy if jumpflag = 1 then return device = tty prstring("FILE TIDIED") nooline(1) closestream(1) clear("1") closesm(6) clear("6") destroy("T#LOGOSTK") stop ! END GOODBYE ! ! sysfun(106): !EXIT closestream(1) clear("1") closesm(6) clear("6") destroy("T#LOGOSTK") stop ! END EXIT ! ! sysfun(107): !AND arg2 = unstack arg1 = unstack stack(arg2) ! DISCARD FIRST ARG return ! END AND ! ! sysfun(108): !QUOTE stack(quote) return ! END QUOTE ! ! sysfun(109): !DOTS stack(dots) return ! END DOTS ! ! sysfun(110): !IT stack(val) return ! END IT ! ! sysfun(111): !VALUE arg1 = unstack if arg1 & wm # wm then start error("VALUE OF WHAT? ", arg1, 1, in) return finish val1: arg2 = getval(arg1, envir) if arg2 = undef then start stksys(arg1) error("NO VALUE HAS BEEN GIVEN TO VARIABLE - ", arg1, 0, in) arg1 = unstksys if jumpflag = 1 then return -> val1 finish stack(arg2) return ! END VALUE ! ! sysfun(112): !REPEAT arg1 = unstack if arg1 & nm # nm or arg1 < 0 then start error("REPEAT NEEDS A NON-NEGATIVE NUMBER - ", arg1, 1, in) return finish if arg1 >> 8 = 0 then start stack(arg1) return finish cycle arg2 = 1, 1, arg1 >> 8 arg3 = in stksys(in) eval(arg3, eachval) in = unstksys if jumpflag = 1 then return w1 = unstack ! LAST VALUE repeat stack(w1) return ! END REPEAT ! ! sysfun(113): !RESET logotime = time100 stack(logotime << 8 ! nm) return ! END RESET ! ! sysfun(114): !TIME stack((time100 - logotime) << 8 ! nm) return ! END TIME ! ! ! SYSFUN(115):; ! DOLOGO !ARG1=UNSTACK !%IF ARG1&LM#LM %THENSTART ! ERROR("DOLOGO MUST HAVE A LIST AS ARGUMENT - ",ARG1,1,IN) ! %RETURN ! %FINISH !STKSYS(IN) ! ! IN=UNSTKSYS ! STACK(UNSTACK) ! %RETURN; ! END DOLOGO ! ! sysfun(116): !RANDOM arg1 = unstack if arg1 & nm # nm then start error("RANDOM MUST HAVE A NUMBER AS ARGUMENT - ", arg1, 1, in) return finish if arg1 < 0 then start arg2 = -1 arg1 = -(arg1 >> 8 ! t8) + 1 ! POSITIVE BINARY +1 finish else start arg2 = 1 arg1 = arg1 >> 8 + 1 finish stack((intpt(random(ranseed, 1) * arg1) * arg2) << 8 ! nm) return ! END RANDOM ! ! sysfun(117): !APPLY arg1 = unstack if arg1 & wm # wm then start error("APPLY MUST HAVE A WORD AS FIRST ARG - ", arg1, 1, in) return finish if arg1 = ift or arg1 = iff then start in = cons(arg1 ! fnm, in) finish else start if arg1 = repeat then start if in = nil then start error("NOT ENOUGH ARGS FOR ", arg1, 1, in) return finish arg2 = reverse(in) arg3 = hd(arg2) in = reverse(tl(arg2)) in = cons(arg3, cons(arg1 ! fnm, in)) finish else start arg1 = cons(arg1 ! fnm, nil) if in # nil then start if (in >> 8) >= lafnb then in = copy(in) ! COPY FROM FN SPACE arg2 = in while tl(arg2) # nil cycle arg2 = tl(arg2) repeat reptail(arg2, arg1) finish else in = arg1 finish finish !IN=CONS(UNSTACK,IN) stksys(in) eval(in, eachval) in = unstksys ! STACK(UNSTACK) return ! END APPLY ! ! sysfun(118): !ALERT list(masnum . "LOGALERT") stack(true) return ! END ALERT ! ! ! sysfun(119): !EXERCISE cycle arg1 = 1, 1, 8 if status(masnum . tdevnames(arg1), 1) < 0 then start prstring("SYSTEM FILE " . tdevnames(arg1) . " NEEDS RESTORING.") nooline(1) prstring("SET PERMIT W,ALL AFTER RESTORE.") nooline(1) finish else disconnect(masnum . tdevnames(arg1)) repeat cycle arg1 = 1, 1, 2 if status(masnum . sysfiles(arg1), 1) < 0 then start prstring("SYSTEM FILE " . sysfiles(arg1) . " NEEDS RESTORING.") nooline(1) prstring("SET PERMIT RS,ALL AFTER RESTORE.") nooline(1) finish else disconnect(masnum . sysfiles(arg1)) repeat stack(true) return ! END EXERCISE ! ! sysfun(120): !DUMP dump("USER REQUEST") stack(nil) return ! END DUMP ! ! ! sysfun(122): !GETTY selectinput(0) closestream(3) clear("3") destroy("T#TEMP") prstring("TEMPORARY FILE DESTROYED") nooline(1) prstring("LOADED AND READY") nooline(3) stack(nil) return ! END GETTY ! ! sysfun(123): !TRUE stack(true) return ! END TRUE ! ! sysfun(124): !FALSE stack(false) return ! END FALSE ! ! sysfun(125): !SPACE stack(space1) return ! END SPACE ! ! sysfun(126): !TAB stack(tab) return ! END TAB ! ! sysfun(127): !NL stack(enel) return ! END NL ! ! sysfun(128): !EMPTY stack(empty) return ! END EMPTY ! ! ! ! sysfun(131): !SETELIM arg1 = unstack if arg1 & nm # nm or arg1 < 0 then start error("SETELIM NEEDS A POSITIVE NUMBER - ", arg1, 1, in) return finish evalimit = arg1 >> 8 stack(arg1) return ! END SETELIM ! ! sysfun(132): !SETCFLG clectflg = 1 stack(nil) return ! END SETCFLG ! ! sysfun(133): !HASHINFO arg1 = hash1023 // hash1024 prstring(" AVERAGE NO OF ACCESSES OF WA= ") write(arg1, 6) nooline(1) prstring(" WHERE NO OF WORDS HASHED= ") write(hash1024, 8) nooline(1) prstring(" AND TOTAL NO OF ACCESSES OF WA= ") write(hash1023, 8) nooline(1) prstring(" DUMPING INFO TO FILE HASHINFO") nooline(1) selectoutput(1) cycle arg1 = 0, 1, 1022 unless wa(arg1) = "?" then start nooline(1) prstring(" ORIG HASH VALUE=") write(hashinfo(arg1), 5) prstring(" ACHIEVED ENTRY KEY=") write(arg1, 5) prstring(" WORD= ") prstring(wa(arg1)) finish repeat selectoutput(0) prstring(" FILE HASH INFO WRITTEN") nooline(1) stack(true) return ! END HASHINFO ! ! sysfun(134): !MAKEASSOC arg1 = unstack ! OBJECT arg2 = unstack ! ATTRIBUTE arg3 = unstack ! VALUE if arg1 & wm # wm then start error("MAKEASSOC MUST HAVE A WORD AS FIRST ARGUMENT - ", arg1, C 1, in) return finish arg1 = arg1 >> 8 ! WA INDEX stack(arg3) arg3 = cons(arg2, cons(arg3, nil)) ! [ATT VAL] if findass(assocwa(arg1), arg2) = nil then start ! NO EXISTING ASSOC assocwa(arg1) = cons(arg3, assocwa(arg1)) ! INSERT [ATT VAL] AS FIRST ELEMENT IN ASSLIST FOR THIS OBJECT finish else start ! ASSOC ALREADY EXISTS. W2 POINTS TO LIST ! WHOSE HEAD IS ASSOC rephead(w2, arg3) finish return ! END MAKEASSOC ! ! sysfun(135): !GETASSOC arg1 = unstack ! OB arg2 = unstack ! ATT if arg1 & wm # wm then start error("GETASSOC MUST HAVE A WORD AS FIRST ARGUMENT - ", arg1, 1, C in) return finish arg3 = findass(assocwa(arg1 >> 8), arg2) if arg3 # nil then arg3 = hd(tl(hd(arg3))) ! VALUE stack(arg3) return ! END GETASSOC ! ! sysfun(136): !REMASSOC arg1 = unstack arg2 = unstack if arg1 & wm # wm then start error("REMASSOC MUST HAVE A WORD AS FIRST ARGUMENT - ", arg1, 1, C in) return finish arg1 = arg1 >> 8 arg3 = findass(assocwa(arg1), arg2) if arg3 # nil then start ! ASSOC EXISTS if w1 = w2 then assocwa(arg1) = tl(w2) else reptail(w1, tl(w2)) finish stack(nil) return ! END REMASSOC ! ! sysfun(137): !CLEARASSOC arg1 = unstack if arg1 & wm # wm then start error("CLEARASSOC MUST HAVE A WORD AS ARGUMENT - ", arg1, 1, in) return finish assocwa(arg1 >> 8) = nil stack(nil) return ! END CLEARASSOC ! ! sysfun(138): !CLEARALLASSOC cycle arg1 = 0, 1, 1022 assocwa(arg1) = nil repeat stack(nil) return ! END CLEARALLASSOC ! ! ! ! ! sysfun(144): !TRACE arg3 = unstack if arg3 & wm = wm then arg3 = cons(arg3, nil) if arg3 & lm # lm then start error1("TRACE WHAT? ", arg3) -> tr2 finish while arg3 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys if jumpflag = 1 then return finish arg1 = hd(arg3) arg3 = tl(arg3) if arg1 & wm # wm then start error1("TRACE WHAT? ", arg1) -> tr1 finish arg2 = fnval(arg1 >> 8) if arg2 = 0 then start error1("UNDEFINED PROCEDURE FOR TRACE - ", arg1) -> tr1 finish if arg2 & interp = interp then start error1("CANNOT TRACE AN INTERP PROCEDURE - ", arg1) -> tr1 finish fnval(arg1 >> 8) = (arg2 & unmask) ! trace1 ! INSERT TRACE FLAG tr1: repeat tr2: stack(true) return ! END TRACE ! ! sysfun(145): !FULLTRACE arg3 = unstack if arg3 & wm = wm then arg3 = cons(arg3, nil) if arg3 & lm # lm then start error1("FULLTRACE WHAT? ", arg3) -> ft2 finish while arg3 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys if jumpflag = 1 then return finish arg1 = hd(arg3) arg3 = tl(arg3) if arg1 & wm # wm then start error1("FULLTRACE WHAT? ", arg1) -> ft1 finish arg2 = fnval(arg1 >> 8) if arg2 = 0 then start error1("UNDEFINED PROCEDURE FOR TRACE - ", arg1) -> ft1 finish if arg2 & interp = interp then start error1("CANNOT TRACE AN INTERP PROCEDURE - ", arg1) -> ft1 finish fnval(arg1 >> 8) = (arg2 & unmask) ! trace2 !INSERT TRACE FLAG ft1: repeat ft2: stack(true) return ! END FULLTRACE ! ! ! sysfun(147): !UNTRACE arg3 = unstack nooline(1) if arg3 & wm = wm then arg3 = cons(arg3, nil) if arg3 & lm # lm then start error1("UNTRACE WHAT? ", arg3) -> untr2 finish while arg3 # nil cycle if quitflag = 1 then start quitflag = 0 jumpout = 0 jumpflag = 1 stack(quit) return finish if holdflag = 1 then start holdflag = 0 stksys(arg3) error("USER INTERRUPT", empty, 0, in) arg3 = unstksys if jumpflag = 1 then return finish arg1 = hd(arg3) arg3 = tl(arg3) if arg1 & wm # wm then start error1("UNTRACE WHAT? ", arg1) -> untr1 finish arg2 = fnval(arg1 >> 8) if arg2 = 0 then start error1("UNDEFINED PROCEDURE FOR UNTRACE - ", arg1) -> untr1 finish fnval(arg1 >> 8) = arg2 & unmask ! REMOVE TRACE FLAG. IF SYSFUN NO EFFECT untr1: repeat untr2: stack(false) return ! END UNTRACE ! ! sysfun(148): !MAPLIST arg1 = unstack if arg1 & lm # lm then start error("MAPLIST MUST HAVE A LIST AS FIRST ARGUMENT - ", arg1, 1, in) return finish arg3 = nil arg2 = in if hd(arg2) & nm = nm then start error("INVALID SECOND ARG FOR MAPLIST-", arg2, 1, in) return finish if hd(arg2) & wm = wm then start stksys(in) stksys(arg1) eval(arg2, eachval) arg1 = unstksys in = unstksys if jumpflag = 1 then return arg2 = unstack finish if arg2 & wm = wm then start while arg1 # nil cycle w1 = hd(arg1) ! qu w1 = cons(w1, cons(arg2 ! fnm, nil)) arg1 = tl(arg1) stksys(in) stksys(arg1) stksys(arg3) eval(w1, eachval) arg3 = unstksys arg1 = unstksys in = unstksys if jumpflag = 1 then return arg3 = cons(unstack, arg3) repeat finish else start if arg2 & lm # lm then start error("INVALID 2ND ARG FOR MAPLIST - ", arg2, 1, in) return finish if hd(arg2) & lp # lp then start savedev = device device = srce sindex = sourceptr printlist(arg2 & X'FFFFFF0F') readinline(promp) device = savedev arg2 = parseline(0) finish while arg1 # nil cycle w1 = hd(arg1) arg1 = tl(arg1) stksys(in) stksys(arg1) stksys(arg2) stksys(arg3) eval(arg2, w1) arg3 = unstksys arg2 = unstksys arg1 = unstksys in = unstksys if jumpflag = 1 then return arg3 = cons(unstack, arg3) repeat finish while arg3 # nil cycle ! REVERSE LIST arg1 = cons(hd(arg3), arg1) arg3 = tl(arg3) repeat stack(arg1) return ! END MAPLIST ! ! sysfun(149): !APPLIST arg1 = unstack if arg1 & lm # lm then start error("APPLIST MUST HAVE A LIST AS FIRST ARGUMENT - ", arg1, 1, in) return finish arg3 = nil arg2 = in if hd(arg2) & nm = nm then start error("INVALID SECOND ARG FOR APPLIST-", arg2, 1, in) return finish if hd(arg2) & wm = wm then start stksys(in) stksys(arg1) eval(arg2, eachval) arg1 = unstksys in = unstksys if jumpflag = 1 then return arg2 = unstack finish if arg2 & wm = wm then start while arg1 # nil cycle w1 = hd(arg1) ! qu arg3 = cons(w1, cons(arg2 ! fnm, nil)) arg1 = tl(arg1) stksys(in) stksys(arg1) eval(arg3, eachval) arg1 = unstksys in = unstksys if jumpflag = 1 then return arg3 = unstack repeat finish else start if arg2 & lm # lm then start error("INVALID 2ND ARG FOR APPLIST - ", arg2, 1, in) return finish if hd(arg2) & lp # lp then start savedev = device device = srce sindex = sourceptr printlist(arg2 & X'FFFFFF0F') readinline(promp) device = savedev arg2 = parseline(0) finish while arg1 # nil cycle w1 = hd(arg1) arg1 = tl(arg1) stksys(in) stksys(arg1) stksys(arg2) eval(arg2, w1) arg2 = unstksys arg1 = unstksys in = unstksys if jumpflag = 1 then return arg3 = unstack repeat finish stack(arg3) return ! END APPLIST ! ! sysfun(150): !EACH if eachval = undef C then error("EACH USED OUT OF CONTEXT", empty, 1, in) C else stack(eachval) return ! END EACH ! ! sysfun(151): !CLEARDATABASE arg3 = bvalue(factkeys >> 8) while arg3 # nil cycle arg1 = hd(arg3) >> 8 arg3 = tl(arg3) arg2 = findass(assocwa(arg1), fact) if arg2 # nil then start if w1 = w2 then assocwa(arg1) = tl(w2) C else reptail(w1, tl(w2)) finish repeat arg3 = bvalue(impkeys >> 8) while arg3 # nil cycle arg1 = hd(arg3) >> 8 arg3 = tl(arg3) arg2 = findass(assocwa(arg1), implies) if arg2 # nil then start if w1 = w2 then assocwa(arg1) = tl(w2) C else reptail(w1, tl(w2)) finish repeat arg3 = bvalue(infkeys >> 8) while arg3 # nil cycle arg1 = hd(arg3) >> 8 arg3 = tl(arg3) arg2 = findass(assocwa(arg1), toinfer) if arg2 # nil then start if w1 = w2 then assocwa(arg1) = tl(w2) C else reptail(w1, tl(w2)) finish repeat setupinf stack(nil) return ! END CLEARDATABASE ! ! sysfun(152): !ASSERT arg1 = unstack if arg1 & lm # lm or arg1 = nil then start error("INVALID ARG FOR ASSERT -", arg1, 1, in) return finish if hd(arg1) = implies then addrule(arg1, 0, implinks) else start if hd(arg1) = toinfer then addrule(arg1, 0, inflinks) C else addfact(arg1, 0) finish if jumpflag = 1 then return stack(nil) return ! END ASSERT ! ! sysfun(153): !AMONGQ arg1 = unstack arg2 = unstack if arg2 & lm # lm then start error("INVALID 2ND ARG FOR AMONGQ -", arg2, 1, in) return finish while arg2 # nil cycle arg3 = equal(hd(arg2), arg1) if jumpflag = 1 then stack(arg3) and return if arg3 = true then stack(true) and return arg2 = tl(arg2) repeat stack(false) return ! END AMONGQ ! ! sysfun(154): !ISQ arg1 = unstack if arg1 & lm # lm or arg1 = nil then start error("INVALID ARG FOR ISQ -", arg1, 1, in) return finish arg3 = undef stack(deduceq(arg1, 0)) return ! END ISQ ! ! sysfun(155): !FINDANY arg1 = unstack arg2 = unstack if arg1 & lm # lm or arg1 = nil then start error("INVALID 1ST ARG FOR FINDANY -", arg1, 1, in) return finish if arg2 & lm # lm or arg2 = nil then start error("INVALID 2ND ARG FOR FINDANY -", arg2, 1, in) return finish arg3 = undef arg3 = deduceq(arg2, 0) if jumpflag = 1 then stack(arg2) and return if arg3 = true then stack(bindings(arg1)) else stack(nil) return ! END FINDANY ! ! sysfun(156): !FINDALL arg1 = unstack arg2 = unstack if arg1 & lm # lm or arg1 = nil then start error("INVALID 1ST ARG FOR FINDALL -", arg1, 1, in) return finish if arg2 & lm # lm or arg2 = nil then start error("INVALID 2ND ARG FOR FINDALL -", arg2, 1, in) return finish arg3 = nil arg2 = deduceq(arg2, 0) if jumpflag = 1 then stack(arg2) else stack(arg3) return !END FINDALL ! ! ! sysfun(160): !FORWARD arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return -> fdsw(tdev) ! fdsw(1): fdsw(2): ! PLOTTERS dy = arg1 * sin(hdturtle / 57.3) dx = arg1 * cos(hdturtle / 57.3) coordok(intpt(xturtle + dx)) if jumpflag = 1 then return coordok(intpt(yturtle + dy)) if jumpflag = 1 then return if penturtle = down then start binarg(1, 0) binarg(2, 4) sendbin(0, 2) ! PENDOWN finish binarg(1, 2) binarg(2, intpt(dx + fracpt(xturtle)) << 5) binarg(3, intpt(dy + fracpt(yturtle)) << 5) sendbin(0, 3) ! OUTLINV(DX,DY) if penturtle = down then start binarg(1, 0) binarg(2, 0) sendbin(0, 2) ! PENUP finish xturtle = xturtle + dx yturtle = yturtle + dy stack(w1) ! NO SPECIAL RESULT return ! fdsw(3): !DISPLAY dy = arg1 * sin(hdturtle / 57.3) dx = arg1 * cos(hdturtle / 57.3) coordok(intpt(xturtle + dx)) if jumpflag = 1 then return coordok(intpt(yturtle + dy)) if jumpflag = 1 then return binarg(2, intpt(dx + fracpt(xturtle)) << 5) binarg(3, intpt(dy + fracpt(yturtle)) << 5) if penturtle = down then binarg(1, 9) else binarg(1, 5) sendbin(0, 3) ! DLINEV(DX,DY) OR DSETV(DX,DY) xturtle = xturtle + dx yturtle = yturtle + dy stack(w1) return ! fdsw(4): !TURTLE if arg1 = 0 then stack(w1) and return dy = arg1 * sin(hdturtle / 57.3) dx = arg1 * cos(hdturtle / 57.3) if arg1 < 0 then tsend(bdbits, tscale(-arg1)) C else tsend(fdbits, tscale(arg1)) if jumpflag = 1 then return xturtle = xturtle + dx yturtle = yturtle + dy stack(w1) return ! fdsw(5): fdsw(6): fdsw(7): !PUNCH,MUSIC,MECCANO ! error("DEVICE CANNOT DO", fn, 1, in) return fdsw(8): !GT42DISPLAY dx = arg1 * cos(hdturtle / 57.3) dy = arg1 * sin(hdturtle / 57.3) coordok(intpt(xturtle + dx)) if jumpflag = 1 then return coordok(intpt(yturtle + dy)) if jumpflag = 1 then return ! *** CHECK FOR COMPILING A PICTURE (LATER VERSION) vector(dx, dy) xturtle = xturtle + dx yturtle = yturtle + dy stack(w1) return ! END FORWARD ! ! sysfun(161): !BACKWARD arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return -> bdsw(tdev) ! bdsw(1): bdsw(2): !PLOTTERS arg1 = -arg1 -> fdsw(1) ! bdsw(3): !DISPLAY arg1 = -arg1 -> fdsw(3) ! bdsw(4): !TURTLE arg1 = -arg1 -> fdsw(4) ! bdsw(5): bdsw(6): bdsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) ! return bdsw(8): !GT42DISPLAA arg1 = -arg1 -> fdsw(8) ! END BACKWARD ! sysfun(162): !LEFT arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return -> leftsw(tdev) ! leftsw(1): leftsw(2): !PLOTTERS if arg1 = 0 then stack(w1) and return hdturtle = mod360(hdturtle + arg1) if arg1 < 0 then pindsend(0, -arg1) else pindsend(pindlbit, arg1) if jumpflag = 1 then return if w1 = true then w1 = tstate stack(w1) return ! leftsw(3): !DISPLAY hdturtle = mod360(hdturtle + arg1) if w1 = true then w1 = tstate stack(w1) return ! leftsw(4): !TURTLE if arg1 = 0 then stack(w1) and return hdturtle = mod360(hdturtle + arg1) if arg1 < 0 then tsend(rtbits, tangle(-arg1)) C else tsend(ltbits, tangle(arg1)) if jumpflag = 1 then return if w1 = true then w1 = tstate stack(w1) return ! leftsw(5): leftsw(6): leftsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) return ! leftsw(8): !GT42DISPLAY hdturtle = mod360(hdturtle + arg1) calcturtle stack(w1) return ! END LEFT ! ! sysfun(163): !RIGHT arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return -> rightsw(tdev) ! rightsw(1): rightsw(2): !PLOTTERS arg1 = -arg1 -> leftsw(1) ! rightsw(3): !DISPLAY arg1 = -arg1 -> leftsw(3) ! rightsw(4): !TURTLE arg1 = -arg1 -> leftsw(4) ! rightsw(5): rightsw(6): rightsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! rightsw(8): !GT42DISPLAA arg1 = -arg1 -> leftsw(8) ! END RIGHT ! ! sysfun(164): !LIFTPEN -> liftsw(tdev) ! liftsw(1): liftsw(2): liftsw(3): liftsw(8): !PLOTTERSANDDISPLAYS penturtle = up stack(false) return ! liftsw(4): !TURTLE penturtle = up tsend1(32) stack(false) return ! liftsw(5): liftsw(6): liftsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) return ! END LIFT ! ! sysfun(165): !DROPPEN -> dropsw(tdev) ! dropsw(1): dropsw(2): dropsw(3): dropsw(8): !PLOTTERSANDDISPLAYS penturtle = down stack(true) return ! dropsw(4): !TURTLE penturtle = down tsend1(32) stack(true) return ! dropsw(5): dropsw(6): dropsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) return ! END DROP ! ! sysfun(166): !HOOT -> hootsw(tdev) ! hootsw(1): hootsw(2): hootsw(3): hootsw(5): hootsw(6): hootsw(7): !ALLBUTTURTLE error("DEVICE CANNOT DO ", fn, 1, in) return ! hootsw(4): !TURTLE tsend1(hootbit) stack(true) return ! hootsw(8): !GT42DISPLAY set42(chpic) ch3(bleep) stack(true) return ! END HOOT ! ! sysfun(167): !CENTRE -> censw(tdev) ! censw(1): censw(2): !PLOTTERS xturtle = 0 yturtle = 0 hdturtle = 0 penturtle = down binarg(1, 1) binarg(2, 0) binarg(3, 0) sendbin(0, 3) ! OUTLIN(0,0) pindsend(pindrbit + pindlbit, 360) ! RESET IND ANTICLOCK if jumpflag = 1 then return stack(true) return ! censw(3): !DISPLAY xturtle = 0 yturtle = 0 hdturtle = 0 penturtle = down binarg(1, 6) binarg(2, 0) binarg(3, 0) sendbin(0, 3) ! DPOINT(0,0) stack(true) return ! censw(4): !TURTLE arg2 = 0 arg3 = 0 w2 = 0 arg1 = down w1 = true -> posw(4) ! SETTURTLE ! censw(5): censw(6): censw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) return ! censw(8): !GT42DISPLAY xturtle = 0 yturtle = 0 hdturtle = 0 penturtle = down point(512, 512) calcturtle stack(true) return ! END CENTRE ! ! sysfun(168): !CLEAR -> clsw(tdev) ! clsw(1): clsw(2): clsw(4): !PLOTTERS,TURTLE stack(true) return ! clsw(5): clsw(6): clsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) return ! clsw(3): !DISPLAY binarg(1, 0) sendbin(0, 1) ! CLEARDIS -> whsw(3) ! clsw(8): !GT42DISPLAY set42(chpic) clear42 xturtle = 0 yturtle = 0 hdturtle = 0 penturtle = down point(512, 512) -> whsw(8) ! END CLEAR ! ! sysfun(169): !WHERE -> whsw(tdev) ! whsw(1): whsw(2): !PLOTTERS arg1 = hdturtle + 90 binarg(1, 0) binarg(2, 4) sendbin(0, 2) ! PENDOWN cycle w1 = 1, 1, 2 arg1 = mod360(arg1 + 60) arg2 = int(10.0 * sin(arg1 / 57.3)) arg3 = int(10.0 * cos(arg1 / 57.3)) binarg(1, 2) binarg(2, arg3 << 5) binarg(3, arg2 << 5) sendbin(0, 3) ! OUTLINV(DX,DY) binarg(2, -(arg3 << 5)) binarg(3, -(arg2 << 5)) sendbin(0, 3) ! OUTLINV(-DX,-DY) repeat binarg(1, 0) binarg(2, 0) sendbin(0, 2) ! PENUP stack(true) return ! whsw(3): !DISPLAY rw1 = sin(hdturtle / 57.3) rw2 = cos(hdturtle / 57.3) binarg(1, 12) binarg(2, int(-1300.0 * (0.9659 * rw2 + 0.2588 * rw1))) binarg(3, int(-1300.0 * (0.9659 * rw1 - 0.2588 * rw2))) binarg(4, int(0.5176 * 1300.0 * rw1)) binarg(5, int(-0.5176 * 1300.0 * rw2)) sendbin(0, 5) ! DRAWTURT stack(true) return ! whsw(4): whsw(5): whsw(6): whsw(7): !TURTLE,PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) return ! whsw(8): !GT42DISPLAY showturtle42 = 1 calcturtle stack(true) return ! END WHERE ! ! sysfun(170): !HERE -> heresw(tdev) ! heresw(1): heresw(2): heresw(3): heresw(4): heresw(8): !PLOTTERS,DISPLAY,TURTLE stack(tstate) return ! heresw(5): heresw(6): heresw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO", fn, 1, in) return ! END HERE ! ! sysfun(171): !XCOR -> xcorsw(tdev) ! xcorsw(1): xcorsw(2): xcorsw(3): xcorsw(4): xcorsw(8): !PLOTTERS,DISPLAY,TURTLE stack(intpt(xturtle) << 8 ! nm) return ! xcorsw(5): xcorsw(6): xcorsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! END XCOR ! ! sysfun(172): !YCOR -> ycorsw(tdev) ! ycorsw(1): ycorsw(2): ycorsw(3): ycorsw(4): ycorsw(8): !PLOTTERS,DISPLAY,TURTLE stack(intpt(yturtle) << 8 ! nm) return ! ycorsw(5): ycorsw(6): ycorsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! END YCOE ! ! sysfun(173): !HEADING -> hdsw(tdev) ! hdsw(1): hdsw(2): hdsw(3): hdsw(4): hdsw(8): !PLOTTERS,DISPLAY,TURTLE stack(hdturtle << 8 ! nm) return ! hdsw(5): hdsw(6): hdsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! END HEADING ! ! sysfun(174): !PEN -> pensw(tdev) ! pensw(1): pensw(2): pensw(3): pensw(4): pensw(8): !PLOTTERS,DISPLAY,TURTLE stack(penturtle) return ! pensw(5): pensw(6): pensw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! END PEN ! ! sysfun(175): !SETX arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return -> setxsw(tdev) ! setxsw(1): setxsw(2): !PLOTTERS coordok(arg1) if jumpflag = 1 then return xturtle = arg1 binarg(1, 1) binarg(2, arg1 << 5) binarg(3, intpt(yturtle) << 5) sendbin(0, 3) ! OUTLIN(X,Y) stack(w1) return ! setxsw(3): !DISPLAY coordok(arg1) if jumpflag = 1 then return xturtle = arg1 if penturtle = down then binarg(1, 6) else binarg(1, 4) ! EITHER DPOINT(X,Y) OR DSET(X,Y) binarg(2, arg1 << 5) binarg(3, intpt(yturtle) << 5) sendbin(0, 3) stack(w1) return ! setxsw(4): !TURTLE setup(arg1 - intpt(xturtle), hdturtle) if jumpflag = 1 then return xturtle = arg1 stack(w1) return ! setxsw(5): setxsw(6): setxsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! setxsw(8): !GT42DISPLAY coordok(arg1) if jumpflag = 1 then return xturtle = arg1 point(xturtle + 512, yturtle + 512) stack(w1) return ! END SETX ! ! sysfun(176): !SETY arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return -> setysw(tdev) ! setysw(1): setysw(2): !PLOTTERS coordok(arg1) if jumpflag = 1 then return yturtle = arg1 binarg(1, 1) binarg(2, intpt(xturtle) << 5) binarg(3, arg1 << 5) sendbin(0, 3) ! OUTLIN,X,Y) stack(w1) return ! setysw(3): !DISPLAY coordok(arg1) if jumpflag = 1 then return yturtle = arg1 if penturtle = down then binarg(1, 6) else binarg(1, 4) binarg(2, intpt(xturtle) << 5) binarg(3, arg1 << 5) sendbin(0, 3) stack(w1) return ! setysw(4): !TURTLE setup(arg1 - intpt(yturtle), hdturtle - 90) if jumpflag = 1 then return yturtle = arg1 stack(w1) return ! setysw(5): setysw(6): setysw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! setysw(8): !GT42DISPLAY coordok(arg1) if jumpflag = 1 then return yturtle = arg1 point(xturtle + 512, yturtle + 512) stack(w1) return ! END SETY ! ! sysfun(177): !SETHEADING arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return -> sethsw(tdev) ! sethsw(1): sethsw(2): !PLOTTERS arg1 = mod360(arg1 - hdturtle) if arg1 > 180 then arg1 = arg1 - 360 -> leftsw(1) ! sethsw(3): !DISPLAY hdturtle = mod360(arg1) stack(w1) return ! sethsw(4): !TURTLE arg1 = mod360(arg1 - hdturtle) if arg1 > 180 then arg1 = arg1 - 360 -> leftsw(4) ! sethsw(5): sethsw(6): sethsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! sethsw(8): !GT42DISPLAY hdturtle = mod360(arg1) calcturtle stack(w1) return ! END SETHEADING ! ! sysfun(178): !POSITION arg1 = unstack if arg1 & lm = 0 then start error("LIST INPUT REQUIRED FOR ", fn, 1, in) return finish w1 = arg1 if listlen(arg1) # 4 then -> pos1 arg2 = hd(arg1) arg1 = tl(arg1) ! X arg3 = hd(arg1) arg1 = tl(arg1) ! Y w2 = hd(arg1) ! HEADING arg1 = hd(tl(arg1)) ! PEN if arg2 & nm = 0 or arg3 & nm = 0 or w2 & nm = 0 or (arg1 # up C and arg1 # down) then -> pos1 arg2 = impnum(arg2) arg3 = impnum(arg3) w2 = impnum(w2) -> posw(tdev) ! posw(1): posw(2): !PLOTTERS coordok(arg2) if jumpflag = 1 then return coordok(arg3) if jumpflag = 1 then return xturtle = arg2 yturtle = arg3 penturtle = arg1 binarg(1, 1) binarg(2, arg2 << 5) binarg(3, arg3 << 5) sendbin(0, 3) ! OUTLIN(X,Y) arg1 = w2 -> sethsw(1) pos1: error("WRONGLY FORMATTED LIST FOR ", fn, 1, in) return ! posw(3): !DISPLAY coordok(arg2) if jumpflag = 1 then return coordok(arg3) if jumpflag = 1 then return xturtle = arg2 yturtle = arg3 hdturtle = mod360(w2) penturtle = arg1 if penturtle = down then binarg(1, 6) else binarg(1, 4) binarg(2, arg2 << 5) binarg(3, arg3 << 5) sendbin(0, 3) stack(w1) return ! posw(4): !TURTLE penturtle = up tsend1(32) ! PENUP setup(arg2 - intpt(xturtle), hdturtle) if jumpflag = 1 then return setup(arg3 - intpt(yturtle), hdturtle - 90) if jumpflag = 1 then return xturtle = arg2 yturtle = arg3 arg2 = mod360(w2 - hdturtle) hdturtle = mod360(w2) if arg2 > 180 then arg2 = arg2 - 360 if arg2 # 0 then start if arg2 < 0 then tsend(rtbits, tangle(-arg2)) C else tsend(ltbits, tangle(arg2)) if jumpflag = 1 then return finish penturtle = arg1 tsend1(32) stack(w1) return ! posw(5): posw(6): posw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! posw(8): !GT42DISPLAY coordok(arg2) if jumpflag = 1 then return coordok(arg3) if jumpflag = 1 then return xturtle = arg2 yturtle = arg3 hdturtle = mod360(w1) penturtle = w2 point(xturtle + 512, yturtle + 512) calcturtle stack(w1) return ! END POSITION ! ! sysfun(179): !ARCLEFT arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return arg2 = chdevarg if jumpflag = 1 then stack(arg2) and return arg3 = 0 ! TO INDICATE LEFT ! ARG1=ANG,ARG2=RAD w1 = true -> arclsw(tdev) ! arclsw(1): arclsw(2): !PLOTTERS if arg1 = 0 then -> arcl1 if arg2 = 0 then -> leftsw(1) ! ZERO RAD. DO LEFT(ANG) xc = int(-arg2 * sin(hdturtle / 57.3) * 32) yc = int(arg2 * cos(hdturtle / 57.3) * 32) rw1 = 2.0 * arg2 * sin(arg1 / 114.6) dx = rw1 * cos((hdturtle + arg1 / 2.0) / 57.3) dy = rw1 * sin((hdturtle + arg1 / 2.0) / 57.3) circletest(arg3, arg2, arg1) if jumpflag = 1 then return w1 = int(0.5 * mod(arg2) * arg1 / 360.0 * 32) if penturtle = down then start binarg(1, 0) binarg(2, 4) sendbin(0, 2) ! PENDOWN finish if w1 # 0 then start binarg(1, 4) binarg(2, xc) binarg(3, yc) binarg(4, w1) sendbin(0, 4) ! OUTCRCLV(XC,YC,W1) finish xturtle = xturtle + dx yturtle = yturtle + dy binarg(1, 1) binarg(2, intpt(xturtle) << 5) binarg(3, intpt(yturtle) << 5) ! OUTLIN(X,Y) TO FINISH sendbin(0, 3) if penturtle = down then start binarg(1, 0) binarg(2, 0) sendbin(0, 2) finish w1 = true -> leftsw(1) ! TO DO HDTURTLE AND INDICATOR arcl1: stack(tstate) return ! arclsw(3): !DISPLAY if arg1 = 0 then -> arcl2 if arg2 = 0 then -> leftsw(3) xc = int(-arg2 * sin(hdturtle / 57.3) * 32) yc = int(arg2 * cos(hdturtle / 57.3) * 32) rw1 = 2.0 * arg2 * sin(arg1 / 114.6) dx = rw1 * cos((hdturtle + arg1 / 2.0) / 57.3) dy = rw1 * sin((hdturtle + arg1 / 2.0) / 57.3) circletest(arg3, arg2, arg1) if jumpflag = 1 then return w1 = int(0.5 * mod(arg2) * arg1 / 360.0 * 32) if penturtle = down and w1 # 0 then start binarg(1, 11) binarg(2, xc) binarg(3, yc) binarg(4, w1) sendbin(0, 4) ! DCIRCLV(XC,YX,W1) finish else start binarg(1, 5) binarg(2, intpt(dx + fracpt(xturtle)) << 5) binarg(3, intpt(dy + fracpt(yturtle)) << 5) sendbin(0, 3) ! DSETV(DX,DY) finish xturtle = xturtle + dx yturtle = yturtle + dy hdturtle = mod360(hdturtle + arg1) arcl2: if penturtle = down then binarg(1, 6) else binarg(1, 4) binarg(2, intpt(xturtle) << 5) binarg(3, intpt(yturtle) << 5) sendbin(0, 3) ! DPOINT OR DSET TO FINISH stack(tstate) return ! arclsw(4): !TURTLE if arg1 = 0 then stack(tstate) and return if arg2 = 0 then -> leftsw(4) tarcleft(arg2, arg1) if jumpflag = 1 then return stack(tstate) return ! arclsw(5): arclsw(6): arclsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! arclsw(8): !GT42 if arg1 = 0 then stack(tstate) and return if arg2 = 0 then -> leftsw(8) gtarcleft(arg2, arg1) if jumpflag = 1 then return stack(tstate) return ! END ARCLEFT ! ! sysfun(180): !ARCRIGHT arg1 = chdevarg if jumpflag = 1 then stack(arg1) and return arg2 = chdevarg if jumpflag = 1 then stack(arg2) and return arg3 = 1 ! TO INDICATE RIGHT ! ARG1=ANG,ARG2=RAD w1 = true -> arcrsw(tdev) ! arcrsw(1): arcrsw(2): !PLOTTERS arg2 = -arg2 arg1 = -arg1 -> arclsw(1) ! arcrsw(3): !DISPLAY arg2 = -arg2 arg1 = -arg1 -> arclsw(3) ! arcrsw(4): !TURTLE arg2 = -arg2 -> arclsw(4) ! arcrsw(5): arcrsw(6): arcrsw(7): !PUNCH,MUSIC,MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! arcrsw(8): !GT42 arg2 = -arg2 -> arclsw(8) ! END ARCRIGHT ! ! sysfun(181): !PUNCH -> pnsw(tdev) ! pnsw(1): pnsw(2): pnsw(3): pnsw(4): pnsw(6): pnsw(7): pnsw(8): ! ALL BUT PUNCH error("DEVICE CANNOT DO ", fn, 1, in) return ! pnsw(5): !PUNCH arg1 = chdevarg if arg1 = err then return if arg1 > 255 then start error("NUMBER TOO BIG TO BE PUNCHED", empty, 1, in) return finish if arg1 < 0 then start error("NEGATIVE NUMBERS CANNOT BE PUNCHED", empty, 1, in) return finish binarg(1, 0) binarg(2, arg1) sendbin(0, 2) ! PUNCH(ARG1) stack(true) return ! END PUNCH ! ! sysfun(182): !RUNOUT -> rnsw(tdev) ! rnsw(1): rnsw(2): rnsw(3): rnsw(4): rnsw(6): rnsw(7): rnsw(8): ! ALL BUT PUNCH error("DEVICE CANNOT DO ", fn, 1, in) return ! rnsw(5): !PUNCH binarg(1, 1) sendbin(0, 1) ! RUNOUT stack(true) return ! END RUNOUT ! ! ! fdsw(0): bdsw(0): leftsw(0): rightsw(0): liftsw(0): dropsw(0): hootsw(0): censw(0): clsw(0): whsw(0): heresw(0): xcorsw(0): ycorsw(0): hdsw(0): pensw(0): setxsw(0): setysw(0): sethsw(0): posw(0): arclsw(0): arcrsw(0): pnsw(0): rnsw(0): notesw(0): playsw(0): motasw(0): motbsw(0): rotsw(0): pairsw(0): error("NO TURTLE DEVICE ASSIGNED TO DO ", fn, 1, in) return ! ! ! sysfun(183): !PLOTTERA claimdevice(1) if jumpflag = 1 then return -> censw(1) ! END PLOTTERA ! ! sysfun(184): !PLOTTERB claimdevice(2) if jumpflag = 1 then return -> censw(2) ! END PLOTTERB ! ! sysfun(185): !DISPLAY claimdevice(3) if jumpflag = 1 then return binarg(1, 0) sendbin(0, 1) ! CLEARDIS -> censw(3) ! END DISPLAY ! ! sysfun(186): !TURTLE claimdevice(4) if jumpflag = 1 then return xturtle = 0 yturtle = 0 hdturtle = 0 penturtle = down tsend1(32) ! PUT PEN DOWN stack(true) return ! END TURTLE ! ! sysfun(187): !TAPE claimdevice(5) if jumpflag = 1 then return -> rnsw(5) ! END TAPE ! ! sysfun(188): !FREE if tdev = 0 then start error("YOU ARE NOT CONNECTED TO ANY DEVICE", empty, 1, in) return finish wstr1 = tdevnames(tdev) if tdev = 8 then disconnect(masnum . "EXEC26") freedevice prstring(wstr1 . " DISCONNECTED") nooline(1) stack(true) return ! END FREE ! ! sysfun(189): !CLESET if tdev = 0 then start error("DEVICE CANNOT DO ", fn, 1, in) return finish cleset stack(true) return ! END CLESET ! ! ! ! sysfun(191): !MUSIC claimdevice(6) if jumpflag = 1 then return stack(true) return ! END MUSIC ! ! sysfun(192): !MECCANO claimdevice(7) if jumpflag = 1 then return xturtle = 0 yturtle = 0 hdturtle = 0 penturtle = down stack(true) return ! END MECCANO ! ! ! ! ! sysfun(200): !GT42 claimdevice(8) if jumpflag = 1 then return load42(gt42exec) modifyexec clear42 point(512, 512) graphp = initgraphp picturepointer = corebottom set42(chtxt) hdturtle = 0 xturtle = 0 yturtle = 0 penturtle = down stack(true) return ! END GT42 ! ! sysfun(201): !HIDE(HIDETURTLEFORGT42???) if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return hideturtle stack(true) return ! END HIDE ! ! ! ! ! sysfun(210): !PICTURE/PIC if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & wm # wm C then error("PICTURE NEEDS A WORD FOR FIRST ARG-", arg1, 1, in) C and return w1 = arg1 >> 8 ! GET INDEX FROM ARG tstor(1) = xturtle tstor(2) = yturtle tstori(3) = hdturtle tstori(4) = penturtle curpic = consg(int(yturtle) + 512, consg(int(xturtle) + 512, C consg(curmode, nil))) gmode = 0 defpicture = 1 ! SET COMPILE FLAG stksys(in) eval(in, eachval) ! AND EXECUTE DRAWING FN in = unstksys if jumpflag = 1 then defpicture = 0 and return index42(w1)_ptr = reverse(curpic) ! AND DEF PICTUREE PICTURE DEFINITION index42(w1)_ptr42 = 0 ! SET PICTURE FLAG xturtle = tstor(1) yturtle = tstor(2) hdturtle = tstori(3) penturtle = tstori(4) defpicture = 0 ! RESET MARKER stack(tstate) !RETURN PIC NAME AS RESULT return ! ! ! ! ! return sysfun(211): !INCLUDE/INC if tdev # 8 C then error("YOU NEED THE GT42 TO RUN MOVIES ", empty, 1, C in) and C return if frameflag = 0 C then error("YOU ARE NOT INSIDE A FRAME ", empty, 1, in) and C return arg1 = unstack ! GET NAME if arg1 & wm # wm C then error("INCLUDE NEEDS A WORD ARGUMENT-", arg1, 1, in) and C return w1 = arg1 >> 8 if index42(w1)_ptr = 0 C then error("PICTURE DOES NOT EXIST-", arg1, 1, in) and return if index42(w1)_ptr42 = 0 then inc(w1) !PICTURENOTALREADYIN !DUMP CODE TO INCLUDE PICTURE AT CURRENT CRANE COORDS !*** WHEN MOVIE IS RUN index42(w1)_mode = curmode curframe = consg(ycrane, consg(xcrane, consg(curmode, consg(3, C consg(index42(w1)_ptr42, consg(setn, curframe)))))) index42(w1)_x = xcrane ! RECORD CURRENT COORDS index42(w1)_y = ycrane stack(true) return ! END-- INCLUDE ! sysfun(212): !ACTION if tdev # 8 C then error("YOU NEED THE GT42 TO RUN MOVIES", empty, 1, in) and C return if frameflag # 0 C then error("ACTION INSIDE FRAME INVALID", empty, 1, in) and C return frameflag = 1 ! SET FRAME FLAG curframe = nil ! AND INITIALISE FRAMELIST savepromp = promp promp = "A:" prompt(promp) if grablist = nil start ! CRANE ONLY INITIALISED !TOCENTREWHENNOTHING !ISCURRENTLYGRABBED xcrane = 512 ycrane = 512 finish hdcrane = 0 !**CRANE HEADING 0 ON ENTRY cycle w1 = 1, 1, 1022 ! CLEAR MOVE CTRS index42(w1)_moved = 0 index42(w1)_lastmovetime = frametime repeat stack(true) return ! sysfun(213): !CUT if tdev # 8 C then error("YOU NEED THE GT42 TO RUN MOVIES", empty, 1, in) and C return if frameflag = 0 C then error("CUT OUTSIDE FRAME INVALID", empty, 1, in) and return frameflag = 0 ! END OF FRAME if curframe = nil then start ! SPECIAL CASE -- !NULLFRAMEDECLAREDSOPAD !FOR"FRAMETIME"TIMEUNITS w2 = consg(wait, consg(frametime, nil)) curmovie = cons(w2, curmovie) promp = savepromp prompt(promp) stack(true) return finish cycle w1 = 1, 1, frametime ! RESET MOVIE RECORD !"MOVIE RECORD"ISA !ATABLEOFLISTS movierecord(w1) = nil repeat ! currentmovietime = 1 w1 = curframe while w1 # nil cycle arg1 = hd(w1) // 256 if arg1 > 0 and arg1 & cranemask = cranemark start !MOVEGROUPFOUND,EG ![MARKDYDXPTRTOINDEX---] w1 = tl(w1) ! "POP" MARK w2 = hd(tl(tl(w1))) >> 8 !ANDGETPTRTOINDEX if hd(w1) >> 8 = cranemark C then w4 = int(hd(tl(w1)) / index42(w2)_moved * frametime) C else start ! COULD BE A "HOLD" MARK rw1 = sqrt((hd(w1) / 256.0) ** 2 + (hd(tl(w1)) / 256.0) ** 2) w4 = int(rw1 / index42(w2)_moved * frametime) !CALCULATETIMETHISMOVE !WILLTAKE.(=FRACTIONOF !OFTOTALDISTANCEMOVED* !TIMETAKENFORFRAME) finish w4 = 1 if w4 <= 0 w4 = frametime if w4 > frametime wptr1 == index42(w2)_lastmovetime wptr1 = wptr1 - w4 wptr1 = 1 if wptr1 <= 0 wptr1 = frametime if wptr1 > frametime !WPTR1NOWPOINTSTOTHE !THEAPPROPRIATEMOVIE !RECORD if hd(w1) >> 8 # cranemark C then movierecord(wptr1) = cons(hd(w1), cons(hd(tl(w1)), C consg(w4, consg(index42(w2)_ptr42 + 2, consg(pmov, C movierecord(wptr1)))))) !ADDCELLTOLIST! currentmovietime = wptr1 ! UPDATE CURRENT MOVIE !CLOCKSOTHATANYINCLUSIONS !OROMMISIONS !CANBEADDEDTO !THEAPPROPRIATEMOVIE !RECORD w1 = tl(tl(tl(w1))) ! POP CELL FROM LIST finish else start arg1 = hd(w1) arg2 = movierecord(currentmovietime) lastput movierecord(currentmovietime) = unstack w1 = tl(w1) finish repeat ! !*** FRAME NOW DISSSEMBLED INTO TIME SLICES ON MOVIE !*** RECORD ARRAY. ! !*** NOW REASSEMBLE INTO CURFRAME (BACKWARDS, OF COURSE) !*** AND DUMP APPROPRIATE "WAIT" INSTRUCTIONS ! curframe = nil w1 = frametime + 1 cycle w2 = 0 ! NO OF OUTSTANDING TIME !INNCREMENTS w1 = w1 - 1 and w2 = w2 + 1 until w1 = 0 C or movierecord(w1) # nil ! FIND LENGTH OF NEXT WAIT if w1 = 0 then start ! END OF FRAME curmovie = cons(reverse(curframe), curmovie) !ADDTOMOVIELIST stack(true) promp = savepromp prompt(promp) return finish arg2 = consg(w2, consg(wait, movierecord(w1))) !CURRENTTIMESLICEOF !FRAME arg1 = curframe ! ARGS LIKE THIS FOR LPUT curframe = appendl(arg1, arg2) ! FUNCTION ! ! *** LOTS OF LIST SPACE BEING CLAIMED/FREED, SO CHECK FOR ! *** POSSIBLE GARBAGE COLLECTS ! if clectflg = 1 then start ! GARBAGE COLLECT NEEDED cycle w4 = 1, 1, w1 ! PUT REMAINING MOVIE RECORD !INTOCOLLECTABLESPACE stack(movierecord(w4)) repeat stksys(in) stksys(val) ! SYSTEM SPACE collect(envir) val = unstksys in = unstksys ! RESTORE cycle w4 = w1, -1, 1 movierecord(w4) = unstack repeat finish repeat ! ! ! ! sysfun(214): !ROLLMOVIE/ROLL if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return if frameflag # 0 C then error("CANNOT ROLL MOVIE INSIDE A FRAME", empty, 1, C in) and C return set42(chpic) ! *** TUURTLE IS SWITCHED OFF FOR DURATION OF MOVIE ! w4 = showturtle42 ! SAVE CURRENT SHOWN STATE if w4 = 1 then hideturtle lbr ! NEST COMMAND GROUP cycle w1 = 0, 1, 1022 ! OMIT ANY CURRENTLY if index42(w1)_ptr42 # 0 start !INCLUDED PICTURES ch3(setn) ch3(index42(w1)_ptr42) ch3(2) ch3(djump) ch3(index42(w1)_faddr) ! OMIT GROUP finish repeat rbr ! AND CLOSE GROUP w1 = reverse(curmovie) stack(true) cycle if w1 = nil start ! END OF MOVIE showturtle if w4 = 1 ! RESTORE ORIGINAL TURTLE STATE return finish w3 = hd(w1) ! NEXT FRAME w1 = tl(w1) lbr ! DEFER EXECUTION OF FRAMES while w3 # nil cycle ch3(hd(w3) // 256) w3 = tl(w3) repeat rbr repeat return ! sysfun(215): !CRANEFORWARD(VERSION2 if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & nm # nm C then error("CRANEFORWARD NEEDS A NUMBER-", arg1, 1, in) and C return if frameflag = 0 C then error("CRANE MOVEMENT OUTSIDE FRAME INVALID", empty, 1, in) C and return w1 = arg1 // 256 ! CONVERT TO ORDINARY NUM cfd: w2 = intpt(w1 * cos(hdcrane / 57.3)) !NEW COORDS w3 = intpt(w1 * sin(hdcrane / 57.3)) ! W2=DX : W3=DY xcrane = xcrane + w2 ycrane = ycrane + w3 arg2 = grablist ! NOW MOVE ANY PICTURES while arg2 # nil cycle ! CURRENTLY "GRABBED" w4 = hd(arg2) >> 8 index42(w4)_moved = index42(w4)_moved + imod(w1) curframe = consg(cranemark, consg(w3, consg(w2, consg(w4, C curframe)))) ! ADD CELL TO FRAMELIST index42(w4)_x = index42(w4)_x + w2 index42(w4)_y = index42(w4)_y + w3 arg2 = tl(arg2) repeat stack(true) return ! sysfun(216): !CRANEBACKWARD if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & nm # nm C then error("CRANEBACKWARD NEEDS A NUMBER-", arg1, 1, in) and C return if frameflag = 0 C then error("CRANE MOVEMENT OUTSIDE FRAME INVALID", empty, 1, in) C and return w1 = -(arg1 // 256) -> cfd ! sysfun(217): !CRANELEFT/CLEFT if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & nm # nm C then error("CRANELEFT NEEDS A NUMBER-", arg1, 1, in) and return if frameflag = 0 C then error("CRANE MOVEMENT OUTSIDE FRAME INVALID", empty, 1, in) C and return hdcrane = mod360(arg1 >> 8 + hdcrane) stack(true) return ! sysfun(218): !CRANERIGHT/CRIGHT if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & nm # nm C then error("CRANERIGHT NEEDS A NUMBER", arg1, 1, in) and return if frameflag = 0 C then error("CRANE MOVEMENT OUTSIDE FRAME INVALID", empty, 1, in) C and return hdcrane = mod360(hdcrane - arg1 >> 8) stack(true) return ! sysfun(219): !NEWMOVIE if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return curmovie = nil ! INITIALISES CURRENT MOVIE LIST promp = savepromp unless frameflag = 0 frameflag = 0 !MAKE SURE NOT IN FRAME prompt(promp) !AND RESTORE PROMPT grablist = nil stack(true) return ! sysfun(220): !GRAB(VERSION2) if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & wm # wm then error("I CAN""", arg1, 1, in) and return if frameflag = 0 C then error("GRAB NOT VALID OUTSIDE FRAME", empty, 1, in) and C return w1 = arg1 >> 8 if index42(w1)_ptr42 = 0 C then error("GRAB FAILS - PICTURE NOT IN GT42 -", arg1, 1, C in) and C return if amongq(arg1, grablist) = 1 C then error("I HAVE ALREADY GRABBED ", arg1, 1, in) and return grablist = cons(arg1, grablist) xcrane = index42(w1)_x ! MOVE CRANE TO PICTURE ycrane = index42(w1)_y ! COORDINATES stack(true) return ! sysfun(221): !RELEASE(VERSION2) if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & wm # wm then error("I CAN""", arg1, 1, in) and return if frameflag = 0 C then error("RELEASE NOT VALID OUTSIDE FRAME", empty, 1, in) and C return if amongq(arg1, grablist) = 0 C then error("I HAVE NOT GRABBED ", arg1, 1, in) and return grablist = without(arg1, grablist) stack(true) return ! sysfun(222): !SETCRANE/SETC if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if frameflag = 0 C then error("CRANE MOVEMENT OUTSDIE FRAME INVALID", empty, 1, in) C and return if arg1 & lm # lm then error("SETCRANE NEEDS A LIST-", arg1, 1, C in) C and return arg2 = arg1 ! SAVE ARGUMENT w1 = getnumb(arg1, "SETCRANE") ! CHECK ALL CRANE if w1 = -100000 then return w2 = getnumb(arg1, "SETCRANE") !COORDS BEFORE return if w2 = -100000 w3 = getnumb(arg1, "SETCRANE") !ALTERING POSITION return if w3 = -100000 xcrane = checkxy(w1) + 512 ycrane = checkxy(w2) + 512 hdcrane = mod360(w3) stack(true) return ! sysfun(223): !OMIT if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack ! GET PICTURE NAME if arg1 & wm # wm then error("OMIT NEEDS A WORD-", arg1, 1, in) C and return if frameflag = 0 C then error("OMIT OUTSIDE FRAME INVALID", empty, 1, in) and return w1 = arg1 >> 8 if index42(w1)_ptr42 = 0 C then error("OMIT FAILS - PICTURE NOT IN GT42 -", arg1, 1, C in) and C return grablist = without(arg1, grablist) curframe = consg(index42(w1)_faddr, consg(djump, consg(2, C consg(index42(w1)_ptr42, consg(setn, curframe))))) stack(true) return ! return ! sysfun(224): !GRABLIST if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return stack(grablist) return return ! END GRABLIST ! sysfun(228): !CRANEHERE if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return if frameflag = 0 C then error("CRANE COMMAND OUTSIDE FRAME NOT VALID", empty, 1, C in) C and return w2 = xcrane - 512 w3 = ycrane - 512 w1 = consg(xcrane, consg(ycrane, consg(hdcrane, nil))) stack(w1) return ! return ! sysfun(225): !CAPTION if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return capflag = 1 arg1 = unstack printel(arg1) capflag = 0 stack(arg1) return ! return ! sysfun(226): !FRAMESPEEDN if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return arg1 = unstack if arg1 & nm # nm C then error("FRAME SPEED NEEDS A NUMBER", arg1, 1, in) and return if frameflag = 1 C then error("CANNOT ADJUST FRAMESPEED WITHIN A FRAME", empty, 1, C in) and return if arg1 < 0 C then error("FRAMESPEED NEEDS A +VE NUMBER", arg1, 1, in) and C return frametime = arg1 >> 8 stack(true) return ! sysfun(227): !KILLFRAME if tdev # 8 then error("DEVICE CANNOT DO ", fn, 1, in) and return if frameflag = 0 C then error("KILLFRAME FAILS - NO FRAME CURRENT", empty, 1, in) C and return frameflag = 0 prompt(savepromp) prstring("*** FRAME KILLED " . time . " ***") nooline(1) stack(true) return ! sysfun(229): !WIPE(CLEARSDYNAMICDISPLAYSPACE) ! setcorepointer(corebottom) cycle w1 = 0, 1, 1022 index42(w1)_ptr42 = 0 repeat curmovie = nil ! RESET MOVIE LIST stack(true) return ! END WIPE ! ! sysfun(230): !NOTE(FORMUSICBOX) -> notesw(tdev) ! notesw(1): notesw(2): notesw(3): notesw(4): notesw(5): notesw(7): notesw(8): ! ALL BUT MUSIC error("DEVICE CANNOT DO ", fn, 1, in) return ! notesw(6): !MUSIC readynum if jumpflag = 1 then return unless 0 <= arg1 <= 48 then start error("THE FIRST INPUT FOR NOTE MUST LIE BETWEEN 0 AND 48. IT WAS GIVEN ", arg1 << 8 ! nm, 1, in) return finish unless 1 <= arg2 <= 256 then start error("THE SECOND INPUT FOR NOTE MUST LIE BETWEEN 1 AND 256. IT WAS GIVEN ", arg2 << 8 ! nm, 1, in) return finish binarg(1, 1) binarg(2, (arg1 << 8) ! (arg2 - 1)) sendbin(0, 2) stack(true) return ! END NOTE ! ! sysfun(231): !PLAY -> playsw(tdev) ! playsw(1): playsw(2): playsw(3): playsw(4): playsw(5): playsw(7): playsw(8): ! ALL BUT MUSIC error("DEVICE CANNOT DO ", fn, 1, in) return ! playsw(6): !MUSIC binarg(1, 0) sendbin(0, 1) stack(true) return ! END PLAY ! ! sysfun(232): !REST sysfun(233): !A0 sysfun(234): !AS0 sysfun(235): !B0 sysfun(236): !C0 sysfun(237): !CS0 sysfun(238): !D0 sysfun(239): !DS0 sysfun(240): !E0 sysfun(241): !F0 sysfun(242): !FS0 sysfun(243): !G0 sysfun(244): !GS0 sysfun(245): !A1 sysfun(246): !AS1 sysfun(247): !B1 sysfun(248): !C1 sysfun(249): !CS1 sysfun(250): !D1 sysfun(251): !DS1 sysfun(252): !E1 sysfun(253): !F1 sysfun(254): !FS1 sysfun(255): !G1 sysfun(256): !GS1 sysfun(257): !A2 sysfun(258): !AS2 sysfun(259): !B2 sysfun(260): !C2 sysfun(261): !CS2 sysfun(262): !D2 sysfun(263): !DS2 sysfun(264): !E2 sysfun(265): !F2 sysfun(266): !FS2 sysfun(267): !G2 sysfun(268): !GS2 sysfun(269): !A3 sysfun(270): !AS3 sysfun(271): !B3 sysfun(272): !C3 sysfun(273): !CS3 sysfun(274): !D3 sysfun(275): !DS3 sysfun(276): !E3 sysfun(277): !F3 sysfun(278): !FS3 sysfun(279): !G3 sysfun(280): !GS3 ! ! stack((sw - 232) << 8 ! nm) return ! ! sysfun(281): !MOTORA -> motasw(tdev) ! motasw(1): motasw(2): motasw(3): motasw(4): motasw(5): motasw(6): motasw(8): ! ALL BUT MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! motasw(7): !MECCANO -> dropsw(4) ! TURTLE DROP FOR NOW ! ! sysfun(282): !MOTORB -> motbsw(tdev) ! motbsw(1): motbsw(2): motbsw(3): motbsw(4): motbsw(5): motbsw(6): motbsw(8): ! ALL BUT MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! motbsw(7): !MECCANO -> liftsw(4) ! TURTLE LIFT FOR NOW ! ! sysfun(283): !ROTATE arg1 = chdevarg if arg1 = err then return -> rotsw(tdev) ! rotsw(1): rotsw(2): rotsw(3): rotsw(4): rotsw(5): rotsw(6): rotsw(8): ! ALL BUT MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! rotsw(7): !MECCANO -> fdsw(4) ! TURTLE FORWARD FOR NOW ! ! sysfun(284): !PAIR arg1 = chdevarg if arg1 = err then return -> pairsw(tdev) ! pairsw(1): pairsw(2): pairsw(3): pairsw(4): pairsw(5): pairsw(6): pairsw(8): ! ALL BUT MECCANO error("DEVICE CANNOT DO ", fn, 1, in) return ! pairsw(7): !MECCANO -> leftsw(4) ! TURTLE LEFT FOR NOW ! ! ! ! ! ! ! end ! END APPLYSYS ! ! ! ! ! routine eval(integer in, integer name eachval) integer fn, funspec, type, argno, parmlist, funlist, userenv integer work1, work2, trace, count, sw, savedev switch systr(0:2), usrtr(0 : 2), outr(0 : 2) switch evalsw(0:15) const integer markermask = X'FFFFFF0F' if quitflag = 1 then start ! USER INT Q quitflag = 0 jumpout = 0 jumpflag = 1 if tdev # 0 then cleset ! CLEAR AND RESET TURTLE DEVICE stack(quit) return finish if holdflag = 1 and libload = 0 then start holdflag = 0 if in = nil then stack(val) and return if tdev # 0 then start cleset error("USER INTERRUPT - TURTLE DEVICE RESET", empty, 1, in) return finish error("USER INTERRUPT", empty, 0, in) if jumpflag = 1 then return finish ! IF USER INTERRUPT HAS HAPPENED SERVICE IT if clectflg = 1 then start ! GARBAGE COLLECT NEEDED stksys(in) stksys(val) collect(envir) val = unstksys in = unstksys finish evalcnt = evalcnt + 1 if evalcnt >= evalimit then start error("EVALIMIT EXCEEDED", empty, 1, in) return finish if in & markermask = nil then start stack(val) return finish lp: return if in = nil fn = hd(in) in = tl(in) & markermask top: sw = (fn >> 4) & X'F' ! SWITCH ON MARKER fn = fn & markermask ! REMOVE MARKER -> evalsw(sw) evalsw(1): !QUOTES stack(fn) -> lp evalsw(2): !DOTS top1: work1 = getval(fn, envir) if work1 = undef then start error("NO VALUE HAS BEEN GIVEN TO VARIABLE - ", fn, 0, in) if jumpflag = 1 then return -> top1 finish else stack(work1) -> lp evalsw(4): !FUNCTIONNAME ! SPECIAL TREATMENT IS REQUIRED FOR UNARY MINUS AND ANGLE BRACKETS if fn = unminus then stack(negate(unstack)) and -> lp if fn = langbrks then start work2 = nil work1 = hd(in) in = tl(in) while work1 & markermask # rangbrks cycle stksys(work2) stksys(in) eval(work1, eachval) in = unstksys work2 = unstksys if jumpflag = 1 then return work2 = cons(unstack, work2) work1 = hd(in) in = tl(in) repeat stack(reverse(work2)) -> lp finish ! FINISH ANGLE BRACKETS funspec = fnval(fn >> 8) ! GET FUNCTION SPEC type = funspec & b4 ! GET FUNCTION TYPE if fnparse(fn >> 8) = 255 then start error("FAULTY FIRST LINE OF PROCEDURE-", fn, 0, in) if jumpflag = 1 then return -> evalsw(4) finish if fnparse(fn >> 8) = 0 and type = userpre then start ! FN NOT PARSED sindex = fntext(fn >> 8) savedev = device device = srce readinline(promp) ! INPUT FROM SOURCE TEXT plevel = 1 work1 = parseline(0) device = savedev if work1 = fault then start error("ERROR WHILE PARSING", fn, 0, in) if jumpflag = 1 then return -> evalsw(4) finish funspec = fnval(fn >> 8) type = funspec & b4 finish if funspec = 0 then start ! UNDEFINED error("UNDEFINED PROCEDURE - ", fn, 0, in) if jumpflag = 1 then return -> evalsw(4) finish if type = syspre or type = userpre or type = infix then start if type = infix then argno = 2 else start if type = syspre then argno = (funspec & b3b) >> 16 C else argno = funspec & X'FF' ! GET NUMBER OF ARGS finish trace = (funspec & traceflg) >> 30 if type = syspre or type = infix then start if stkpnt - argno < 0 then start error("NOT ENOUGH ARGS FOR ", fn, 1, in) return finish -> systr(trace) systr(2): strtrace(fn) if argno # 0 then start ! ARGS EXIST spaces(indent) cycle work1 = 1, 1, argno ! PRINT VALUES OF ARGS printstring("ARG" . tostring(work1 + 48) . " = ") printel(stk(stkpnt + 1 - work1)) printstring(", ") repeat nooline(1) finish -> systr(0) systr(1): strtrace(fn) systr(0): applysys(funspec & b2, fn, in, eachval) finish else start ! FINISH SYSPRE,INFIX : START USERPRE funlist = funspec & m16 ! lm ! FUN NOW HAS USER DEF AS LIST parmlist = tl(tl(hd(funlist))) ! PARAMETRS if jumpflag = 1 then stack(parmlist) and return userenv = makebind(parmlist, envir, fn) if userenv = fault then start error("NOT ENOUGH ARGS FOR ", fn, 1, in) return finish -> usrtr(trace) usrtr(2): strtrace(fn) if argno # 0 then start spaces(indent) work1 = parmlist cycle count = 1, 1, argno printel(hd(work1)) printstring(" = ") printel(bvalue(userenv - argno + count)) printstring(", ") work1 = tl(work1) repeat nooline(1) finish -> usrtr(0) usrtr(1): strtrace(fn) usrtr(0): stksys(in) stksys(val) applyusr(userenv, funlist, tstflg, val, severity) val = unstksys in = unstksys finish ! FINISH USERPRE -> outr(trace) outr(2): spaces(indent) printstring("RESULT = ") printel(stk(stkpnt)) nooline(1) outr(1): endtrace(fn) outr(0): if jumpflag = 1 then return finish else start ! FINISH SYSPRE/USERPRE/INFIX if type = interp then start ! START INTERP applysys(funspec & b2, fn, in, eachval) if jumpflag = 1 then return finish else start error("ERROR IN FN TYPE FOR EVAL", empty, 1, in) return finish finish ! FINISH INTERP ! return ! evalsw(0): !POINTER evalsw(8): stksys(in) eval(fn, eachval) in = unstksys if jumpflag = 1 then return -> lp ! ! end ! END EVAL eval(in, undef) end ! OF EVALAPPL ! ! integer fn parseline(integer prec) integer fn spec checkhd(integer hd) routine spec topolish(integer name arglist, operator) integer fn spec readfndefn integer fn spec parseto integer fn spec parseifc integer fn spec parseif routine spec tobottom(integer op, list) integer fn spec preced(integer op) integer fn spec parseappmap integer undefin integer fn parse(integer prec) integer fn, funspec, type, argno, nextprec integer polist, arg1list, operator, arg1, item, in integer work1, work2 switch interpsw(59:150) in = nil polist = nil arg1list = nil plevel = plevel + 1 lp: fn = headin unusedhd = 0 if fn = rbrak then result = polist ! END OF LINE if fn = rpar then result = polist ! ')' if fn = comment then result = polist ! IGNORE REST OF LINE if fn = comma then tailin and -> lp ! SEPARATOR top: if fn & nm = nm then start ! NUMBER fn = fn ! qu ! QU IS A VALUE MARKER polist = cons(fn, polist) finish else start ! START 0 if fn = lbrak then start ! '[' tailin fn = readlist ! qu ! READLIST polist = cons(fn, polist) finish else start ! START 1 if fn = quote then start ! DATA WORD FOLLOWS quoteon = 1 tailin fn = headin polist = cons(fn ! qu, polist) quoteon = 0 finish else start ! START 2 if fn = dots then start ! DATA NAME FOLLOWS tailin fn = headin if fn = rbrak then start ! ']' parseerr(-1, empty) result = fault finish fn = fn ! dts ! DTS IS A NAME MARKER if fn & wm = wm then start polist = cons(fn, polist) finish else start parseerr(-2, fn) result = fault finish finish else start ! START 3 if fn = lpar then start ! '(' tailin work1 = parse(4) ! CALL PARSE RECURSIVELY WITH HIGHER PRECEDENCE ! RETURNS ON MATCHING ')' OR END OF LINE if work1 < 0 then result = fault polist = cons((work1 ! lp), polist) tailin while headin # rpar and headin # rbrak finish else start ! START 4 if fn = minus then start ! UNARY MINUS. EVAL WITH TOP PREC polist = cons(unminus ! fnm, polist) tailin work1 = parse(100) if work1 < 0 then result = fault polist = cons(work1 ! lp, polist) finish else start ! START 5 if fn = langbrks then start ! << polist = cons(langbrks ! fnm, polist) tailin item = headin while headin # rbrak and headin # rangbrks C cycle ! UNTIL NEXT ITEM ! IS MATCHING ">>" OR END OF LINE work1 = parse(0) if work1 < 0 then result = fault polist = cons(work1 ! lp, polist) repeat if headin = rbrak then start parseerr(-3, empty) result = fault finish unusedhd = 0 polist = cons(rangbrks ! fnm, polist) polist = reverse(polist) finish else start ! START 6 if fn = rpar or fn = rangbrks then start ! SPURIOUS ')' OR ">>" parseerr(-4, fn) result = fault finish polist = cons(fn ! fnm, polist) ! FNM IS A FN MARKER funspec = fnval(fn >> 8) ! GET FUNCTION SPEC if funspec = 0 then start ! UNDEFINED undefin = 1 ! IF NOT PARSING A FN DEFINITION OR A CONDITION THEN... if fndefn = 0 and condflag = 0 then start parseerr(-11, fn) result = fault finish type = userpre finish else type = funspec & b4 if fn = if or fn = while then start work1 = parseif condflag = condflag - 1 unless condflag = 0 result = work1 finish if fn = ift or fn = iff then start work1 = parseifc condflag = condflag - 1 unless condflag = 0 result = work1 finish if type = syspre or type = userpre then start ! PREFIX FUN ! GET NUMBER OF ARGS if undefin = 1 then argno = -1 else start if type = syspre C then argno = (funspec & b3b) >> 16 C else argno = funspec & X'FF' finish tailin if argno # 0 then start work1 = argno if work1 < 0 then start ! UNKNOWN NUMBER OF ARGS cycle exit if checkhd(headin) = 1 ! CHECK FOR SPECIAL VALUES work2 = parse(10) ! PARSE ARGS if work2 < 0 then result = fault polist = cons(work2 ! lp, polist) repeat finish else start while work1 > 0 cycle ! GATHER ARGS INTO POLIST if checkhd(headin) = 1 then start exit if undefin = 1 parseerr(-12, fn) result = fault finish work2 = parse(10) if work2 < 0 then result = fault polist = cons(work2 ! lp, polist) work1 = work1 - 1 repeat finish finish if headin = then or headin = else then C result = polist if fn = break then start work1 = readlist reptail(polist, work1) result = polist finish if fn = apply then start work1 = nil cycle exit if checkhd(headin) = 1 work2 = parse(10) if work2 < 0 then result = fault work1 = cons(work2, work1) repeat reptail(tl(polist), work1) result = polist finish if fn = repeat then start work1 = parse(0) if work1 < 0 then result = fault work2 = tl(polist) reptail(work2, work1) result = polist finish if fn = do then start work1 = hd(polist) work2 = hd(tl(polist)) polist = tl(tl(polist)) polist = cons(work2, cons(work1, polist)) finish unusedhd = 1 polist = cons(polist ! lp, nil) finish else start ! START 7 if type = interp then start -> interpsw(funspec & b2) interpsw(59): !DEFINE if plevel > 1 then parseerr(-19, fn) C and result = fault polist = parseto prompt(promp) fndefn = 0 result = polist ! interpsw(60): !FNDEFINITION--NOTPARSEDUNTILFIRSTCALL if plevel = 1 then polist = readfndefn C else polist = parseto prompt(promp) fndefn = 0 result = polist interpsw(148): !MAPLIST interpsw(149): !APPLIST result = parseappmap finish else start ! START 8 if type = infix then start ! MISPLACED INFIX parseerr(-5, fn) result = fault finish else start parseerr(-10, empty) result = fault finish finish ! FINISH 8 finish ! FINISH 7 finish ! FINISH 6 finish ! FINISH 5 finish ! FINISH 4 finish ! FINISH 3 finish ! FINISH 2 finish ! FINISH 1 finish ! FINISH 0 ! ! ! INFIX LOOP infix: if headin = rpar then start if fn # lpar then -> return unusedhd = 0 finish tailin unless unusedhd = 1 nextinf: fn = headin if fn = rbrak or fn = rpar or fn & wm # wm then -> return funspec = fnval((fn >> 8) & X'FFFF') !GET FN DEFN if funspec = 0 then -> return !NOT DEFINED AS A FN type = funspec & b4 ! GET TYPE if type # infix then -> return ! NOT INFIX nextprec = (funspec & b3b) >> 16 ! GET PREC if nextprec <= prec then -> return ! NEXT PREC LOWER THAN CURRENT arg1 = hd(polist) polist = tl(polist) arg1list = cons(arg1, nil) !PUT FIRST ARG ONTO TEMP POLISH LIST operator = fn topolish(arg1list, operator) ! OPERATOR IS THE FN JUST FOUND !ARG1LIST IS UPDATED BEFORE RETURN FROM TOPOLISH if arg1list = fault then result = fault polist = cons(arg1list ! lp, polist) -> nextinf return: unusedhd = 1 result = polist end ! END PARSE ! ! integer fn checkhd(integer hd) integer funspec, type if hd = rbrak or hd = rpar or hd = rangbrks or hd = and C or hd = then or hd = else then result = 1 if hd & fnm = fnm then start funspec = fnval(hd >> 8) type = funspec & b4 if type = infix then result = 1 finish result = 0 end ! ! routine topolish(integer name arg1list, op) integer polist, op1, work1 polist = nil op1 = op tailin work1 = parse(preced(op)) if work1 < 0 then arg1list = fault and return polist = work1 ! SPECIAL CASE FOR AND if op = and then arg1list = cons(arg1list ! lp, polist) C else arg1list = cons(polist ! lp, arg1list) tobottom(op1 ! fnm, arg1list) return end ! ! routine tobottom(integer item, list) ! INSERT ITEM AT END OF LIST integer l, newtail la(lpoint) = item la(lpoint + 1) = nil newtail = lpoint << 8 ! lm lpoint = lpoint + 2 l = list while tl(l) # nil cycle l = tl(l) repeat reptail(l, newtail) end ! ! ! integer fn preced(integer op) ! RETURNS PRECEDENCE OF OP. integer funspec funspec = fnval(op >> 8) result = (funspec & b3b) >> 16 end ! integer fn parseifc integer thenc, fn, ins fn = headin tailin condflag = condflag + 1 thenc = parse(0) if thenc < 0 then result = fault if fndefn = 1 then start thenc = move1(thenc) ins = cons1(fn ! fnm, thenc) finish else ins = cons(fn ! fnm, thenc) result = ins end ! END OF PARSEIFC ! const string (6) strt = "START:" integer fn spec makecondbranch !%ROUTINESPEC PROCESS LINENUMS(%INTEGER LIST) integer fn parseif integer tbranch, fbranch, cond, thenc, elsec, item, fn, work1 tbranch = nil fbranch = nil fn = headin cond = nil tailin if headin = then or headin = else then start parseerr(-21, empty) result = fault finish work1 = parse(0) ! PARSE CONDITION if work1 < 0 then result = fault if headin = then then -> thencl if headin = else then parseerr(-6, headin) parseerr(-7, headin) result = fault ! thencl: !THENCLAUSE condflag = condflag + 1 ! DOWN A LEVEL OF CONDITION tailin item = headin if item = else then start parseerr(-22, empty) result = fault finish if item = start then start ! START...FINISH prompt(strt) tbranch = makecondbranch prompt(promp) if tbranch = fault then result = fault finish else start thenc = parse(0) if thenc < 0 then result = fault ! IF PARSING A FN DEFINITION MOVE LIST INTO FN DEFN SPACE if fndefn = 1 then tbranch = move1(thenc) else tbranch = thenc finish if headin = else then -> elsecl -> buildcond elsecl: !ELSECLAUSE if fn = while then fbranch = nil else start tailin item = headin if item = start then start ! START...FINISH prompt(strt) fbranch = makecondbranch prompt(promp) if fbranch = fault then result = fault finish else start elsec = parse(0) if elsec < 0 then result = fault if fndefn = 1 then fbranch = move1(elsec) C else fbranch = elsec finish finish buildcond: if fndefn = 1 then start ! PARSING A FN DEFN work1 = move1(work1) cond = cons1(fn ! fnm, cons1(work1 ! lp, cons1(tbranch, fbranch))) finish else start cond = cons(fn ! fnm, cons(work1 ! lp, cons(tbranch, fbranch))) finish result = cond end ! END OF PARSEIF integer fn makecondbranch integer condlist, work1, linenum, item, linenumlist, ftcondlist, C txtptr condlist = nil linenumlist = nil until item = finish cycle ! PARSE LINES UP TO "FINISH" if fndefn = 1 then start if device = tty then start copyline ! USING "DEFINE" - COPY LINE TO SOURCE txtptr = sourceptr ! PTR TO NEXT SOURCE LINE finish else txtptr = sindex finish readinline(strt) item = headin if fndefn = 1 then start if item = end then parseerr(-8, item) and result = fault if item & nm # nm then start parseerr(-9, item) -> rep finish linenum = item tailin item = headin finish if item = finish then work1 = cons(finish, nil) else start work1 = parse(0) if work1 < 0 then result = fault finish if fndefn = 1 then start work1 = move1(work1) ! lp ! MOVE LIST INTO FN DEFN SPACE ! INSERT LINENUMBER AND PTR TO FN TEXT FOR DIAGNOSTICS work1 = cons1(cons1(((txtptr << 16) ! ((linenum >> 8) << 2)), C work1), nil) finish else work1 = cons(cons(sourceptr << 16, work1), nil) ! ADD THIS LINE TO END OF FN LIST if condlist = nil then start condlist = work1 ftcondlist = condlist finish else start reptail(ftcondlist, work1) ftcondlist = tl(ftcondlist) finish ! IF A FN DEFN THEN ADD THIS LINE TO LINE NUMBER LIST if fndefn = 1 C then linenumlist = cons1(cons1(linenum, ftcondlist), C linenumlist) rep: repeat tailin ! INSERT LINE NUMBER INTO START...FINISH LIST if fndefn = 1 then C result = cons1(start, cons1(linenumlist, condlist)) else C result = cons(start, cons(linenumlist, condlist)) end integer fn readfndefn ! READ TEXT OF A FN INTO SOURCE TEXT FILE integer starttext, arg1, arg2, index starttext = sourceptr tailin arg1 = headin index = arg1 >> 8 if arg1 & wm # wm or arg1 = rbrak then start parseerr(-14, arg1) result = fault finish arg2 = fnval(index) if arg2 # 0 then start unless arg2 & userpre = userpre then start parseerr(-15, arg1) result = fault finish oldfn(index) = fnlen(index) << 16 ! fntext(index) finish copyline if sourceptr + 2 * (sourceptr - starttext) + 64 > maxsource C then baderror("SOURCE FILE SPACE OVWRFLOW", empty) newfn = fromlist(arg1, newfn) unless newfn = nil fntext(index) = starttext fnlen(index) = sourceptr - starttext edit(arg1) unless fnparse(arg1 >> 8) = 255 then newfn = cons(arg1, newfn) result = nil end ! ! ! integer fn spec makearglist(integer name len) integer fn parseto ! FIRST LINE OF FN ALREADY READ ! PARSE A FN DEFN -- TEXT IS IN SOURCE TEXT FILE IF HEADIN=TO ! OR READ FROM INPUT FILE IF HEADIN=DEFINE ! integer len, arg1, arg2, arg3, args, fnline, linenum, fn, item, C redef, fnlist integer endfnlist, starttext, lentext, index, txtptr, i, rest const string (8) fndef = "FN DEFN:" fndefn = 1 redef = 0 fnlist = nil endfnlist = nil linenumlist = nil fn = headin ! TO tailin arg1 = headin ! PROC NAME index = arg1 >> 8 tailin if fn = def then start starttext = sourceptr prompt(fndef) if arg1 & wm # wm or arg1 = rbrak then start parseerr(-14, arg1) result = fault finish arg2 = fnval(index) if arg2 = 0 then -> makespec if arg2 & userpre = userpre then start redef = 1 -> makespec finish else parseerr(-15, arg1) result = fault makespec: newfn = fromlist(arg1, newfn) unless newfn = nil i = 1 i = i + 1 while inbuff(i) = ' ' !SKIP LEADING SPACES i = i + 1 while inbuff(i) # ' ' ! SKIP FIRST WORD rest = inbuff(0) - i + 1 if sourceptr + 2 + rest > maxsource C then baderror("SOURCE FILE SPACE OVERFLOW", empty) source(sourceptr) = 'T' source(sourceptr + 1) = 'O' move(rest, addr(inbuff(i)), addr(source(sourceptr + 2))) sourceptr = sourceptr + 2 + rest finish args = makearglist(len) ! MAKE A LIST OF ARGUMENTS if args = fault then result = fault if fn = def then start if len > 127 then start parseerr(-13, arg1) result = fault finish if redef = 1 C then oldfn(index) = fnlen(index) << 8 ! fntext(index) finish arg3 = cons1(to, cons1(arg1, args)) fnval(index) = userpre + len ! TEMP SPEC TO ALLOW RECURSIVE CALLS ! FN=DEF IMPLIES DEVICE=TTY if device = tty then txtptr = sourceptr else txtptr = sindex ! POINTER TO BEGINNING OF NEXT LINE OF TEXT readinline(fndef) ! READ FIRST LINE item = headin tailin while item # end cycle fnline = nil if item & nm # nm then start parseerr(-9, arg1) ! NO NUMBER ON FN LINE -> readline finish linenum = item ! STORE LINE NUMBER undefin = 0 fnline = parse(0) ! PARSE LINE if fnline = fault then parseerr(-20, arg1) and -> readline fnline = move1(fnline) ! lp ! MOVE INTO FN DEFN SPACE ! INSERT LINENUMBER AND TEXT POINTER IN FN LIST fnline = cons1(cons1(((txtptr << 16) ! ((linenum >> 8) << 2)), C fnline), nil) ! ADD LINE TO END OF LIST if fnlist = nil then start fnlist = fnline endfnlist = fnlist finish else start reptail(endfnlist, fnline) endfnlist = tl(endfnlist) finish ! UPDATE LINE NUMBER LIST linenumlist = cons1(cons1(linenum, endfnlist), linenumlist) if fn = def then copyline readline: !READNEXTLINE if device = tty then txtptr = sourceptr else txtptr = sindex readinline(fndef) item = headin tailin repeat if fn = def then copyline ! INSERT END INTO SOURCE ! INSERT END INTO FN LIST ! %IF ENDFNLIST=NIL %THEN FNLIST=CONS1(CONS1(END,NIL)!LP,NIL) if endfnlist = nil then fnlist = cons1(end, nil) C else reptail(endfnlist, cons1(end, nil)) ! INSERT LINE NUMBER LIST INTO FN LIST fnlist = cons1(arg3 ! lp, cons1(linenumlist ! lp, fnlist)) fnval(index) = userpre + fnlist & m16 + len !BUILD SPEC if fn = def then start newfn = cons(arg1, newfn) printel(arg1) if redef = 1 then prstring(" REDEFINED") C else prstring(" DEFINED") nooline(1) lentext = sourceptr - starttext fntext(index) = starttext fnlen(index) = lentext finish fnparse(index) = 1 result = nil end ! END OF PARSETO ! integer fn makearglist(integer name len) ! MAKE A LIST OF ARGS. integer list, word list = nil len = 0 result = nil if headin = rbrak until word = rbrak cycle -> errlab unless headin = quote tailin word = headin -> errlab if word = rbrak or word & wm # wm list = cons(word, list) len = len + 1 tailin word = headin repeat tailin result = reverse1(list) errlab: parseerr(-16, empty) result = fault end ! END OF MAKEARGLIST ! ! integer fn parseappmap ! SPECIAL SYSTEM FNS APPLIST AND MAPLIST integer fn, work1, work2 fn = headin tailin work1 = parse(0) if work1 < 0 then result = fault if work1 = nil then start parseerr(-12, fn) result = fault finish ! ! PARSE LIST WHICH WILL BE APPLIED TO EACH ARG OF ARG1 ! if headin = lbrak then start tailin work2 = parse(0) tailin finish else work2 = parse(0) if work2 = fault then result = fault if work2 = nil then start parseerr(-12, fn) result = fault finish result = cons(work1, cons(fn ! fnm, work2)) end ! ! ! ! undefin = 0 result = parse(prec) ! end ! OF PARSELINE ! ! routine applyusr(integer envir, fun, tstflg, val, integer name severity) integer in, nextfun, savestk, linenumlist, curfun, num savestk = stkpnt linenumlist = hd(tl(fun)) nextfun = tl(tl(fun)) while hd(nextfun) # end cycle if nextfun = nil then return curfun = hd(nextfun) in = tl(curfun) nextfun = tl(nextfun) evalappl(envir, fun, curfun, in, tstflg, val, severity) return if curfun = nil if goflag = 1 then start nextfun = findlinenums(linenumlist) if nextfun = 0 then start num = unstack newline printstring("CANNOT JUMP TO LINE") write(num >> 8, 2) newline jumpflag = 1 goflag = 0 stack(num) finish finish if jumpflag = 1 then start ! RETURN FROM USERINT OR ERROR if sendflag > 1 then start sendflag = sendflag - 1 return finish else start if sendflag = 1 then start sendflag = 0 jumpflag = 0 val = unstack ! VALUE SENT BACK stkpnt = savestk ! RESET STACK stack(val) return finish ! SENDFLAG=1 finish ! SENDFLAG NOT >1 return ! SENDFLAG=0 finish ! JUMPFLAG=1 val = unstack return if nextfun = nil repeat stack(val) ! RESULT OF USER FUN-VALUE FROM LAST LINE end ! END APPLYUSR ! ! ! ! routine dump(string (80) errmess) integer i integer sysval byte integer name type, argno !%SHORTINTEGERNAME SWITCH type == byteinteger(addr(sysval)) !SWITCH==SHORTINTEGER(ADDR(SYSVAL)+2) argno == byteinteger(addr(sysval) + 1) ! routine dumpitem(integer i) if i & wm = wm then start printstring("W") write(i >> 8, 5) return finish if i & lm = lm then start printstring("L") write(i >> 8, 5) return finish if i & nm = nm then start printstring("N") spaces(3) if i < 0 then write(i >> 8 ! t8, 0) else write(i >> 8, 0) return finish printstring("UNDEF") end ! END DUMPITEM nooline(1) prstring("DUMPING") nooline(1) selectoutput(1) newlines(5) printstring("********* DUMP STARTS **********" . date . " " . time) newline printstring("ERROR - " . errmess) newline newline printstring("WORD AREA") newline printstring(" INDEX WORD BASE VALUE ") printstring("FNTYPE FNSWITCH FNARGNO/PREC LIST INDX") newline cycle i = 0, 1, 1022 if wa(i) = "?" then -> rep else start write(i, 5) spaces(2) printstring(wa(i)) spaces(9 - length(wa(i))) dumpitem(bvalue(i)) sysval = fnval(i) write(type, 10) if type # 8 then start write(sysval & X'FFFF', 10) if type # 4 then write(argno, 14) finish else start spaces(11) write(sysval & X'FF', 14) spaces(2) printstring("L") write(sysval << 8 >> 16, 4) finish newline finish rep: repeat newline printstring("LIST AREA") newlines(2) printstring("FUNCTION SPACE") newline if lpoint1 = listop then start printstring("NO NEW FNSPACE") newline -> semisp finish cycle i = listop, 1, lpoint1 - 1 write(i, 5) spaces(2) dumpitem(la(i)) newline repeat newline listop = lpoint1 semisp: printstring("CURRENT SEMISPACE") newline if lpoint = labase then start printstring("NO LIST SPACE") newline -> env finish cycle i = labase, 1, lpoint - 1 write(i, 5) spaces(2) dumpitem(la(i)) newline repeat newline env: printstring("LOCAL ENVIRS") newline if topmark = 1022 then start printstring("NO LOCALS") newline finish else start cycle i = 1023, 1, topmark write(bname(i) >> 8, 5) spaces(2) dumpitem(bvalue(i)) newline repeat finish newline printstring("USER STACK") newline if stkpnt = 0 then start printstring("STACK EMPTY") newline finish else start cycle i = stkpnt, -1, 1 write(i, 5) spaces(2) printel(stk(i)) newline repeat finish selectoutput(0) prstring("DUMPED") nooline(1) end ! END DUMP ! ! routine initialise integer i string (64) in routine getfuns string (64) name integer sysval, tswitch byte integer name type, argno byte integer array name switch byte integer array format sf(1 : 2) type == byteinteger(addr(sysval)) switch == array(addr(sysval) + 2, sf) argno == byteinteger(addr(sysval) + 1) lp: readstring(name) if name = "END" then return sysval = 0 read(type) read(tswitch) if type # 4 then read(argno) setshortint(switch(1), tswitch) fnval(hash(name) >> 8) = sysval -> lp end ! END GETFUNS ! ! emasuser = uinfs(1) ! USER NAME AS STRING owner = emasuser masfile = "LOGOFILE" masread = masfile . "," . emasuser . ",R" maswrite = masfile . "," . emasuser . ",WR" cycle i = 0, 1, 1022 bvalue(i) = 0 fnval(i) = 0 fntext(i) = 0 fnparse(i) = 0 fnlen(i) = 0 oldfn(i) = 0 wa(i) = "?" repeat space4 = " " quoteon = 0 sourceptr = 1 fndefn = 0 diagflag = 0 condflag = 0 goflag = 0 hashval == intstr(2) work1 == string(addr(intstr(2)) - 1) lbrak == spechar(13) rbrak == spechar(14) tdev = 0 addrbinbuff = addr(binbuff(1)) device = tty userfile = "" cactfile = 0 mdind = 0 mdp = 0 charout = 0 hash1023 = 0 hash1024 = 0 indent = 1 prnum = 0 stkpnt = 0 stktop = 0 systkpnt = 0 jumpflag = 0 jumpout = 0 superjmp = 0 sendflag = 0 quitflag = 0 holdflag = 0 lpoint = la1b labase = la1b lpoint1 = lafnb listop = lafnb semisize = la2b - la1b clectflg = 0 topmark = 1022 basenvir = 1022 numtop = X'007FFFFF' numbot = X'FF800001' evalimit = 1000000 libload = 0 empty == names(2) space1 == names(4) enel == names(6) tab == names(8) true == names(9) false == names(11) quote == names(14) dots == names(16) lpar == names(17) rpar == names(18) comma == names(19) nil == names(20) undef == names(21) then == names(22) else == names(23) end == names(24) delete == names(25) undo == names(26) undos == names(27) to == names(28) do == names(29) err == names(30) logoname == names(31) quit == names(32) break == names(33) if == names(34) close == names(35) while == names(36) thinkaloud == names(37) fact == names(38) implies == names(39) toinfer == names(40) new == names(41) vbl == names(42) not == names(43) database == names(44) imprules == names(45) infrules == names(46) factkeys == names(47) impkeys == names(48) infkeys == names(49) up == names(50) down == names(51) langbrks == names(52) rangbrks == names(53) minus == names(54) quitotop == names(63) start == names(64) finish == names(65) and == names(66) repeat == names(67) apply == names(68) unminus == names(69) comment == names(70) def == names(71) ift == names(72) iff == names(73) selectinput(2) read(cfract) i = 1 lp: readstring(in) if in # "ENDUP" then start names(i) = hash(in) i = i + 1 -> lp finish else start nil = nil >> 8 << 8 ! lm ! CHANGE MARKER ON NIL FROM WM TO LM cycle i = 0, 1, 1022 assocwa(i) = nil repeat getfuns cycle i = 1, 2, 15 setval(names(i), names(i + 1), basenvir) ! INITVALS repeat initinf setval(thinkaloud, true, basenvir) setval(quitotop, true, basenvir) newfn = nil logotime = time100 selectinput(0) closestream(2) clear("2") getmaster !******* GRAPHICS INITIALISATION curpic = nil defpicture = 0 frameflag = 0 ! NOT WITHIN FRAME curmovie = nil ! NO CURRENT MOVIE curframe = nil grablist = nil return finish end ! END INITIALISE ! ! routine logo(integer stktop, envir, severity) integer val, fun, curfun, tstflg, in val = undef fun = nil in = nil curfun = nil tstflg = 0 prnum = prnum + 1 promp = numtostr(prnum << 8) . ":" prompt(promp) lp: if tdev = 8 then set42(chtxt) blevel = 1 readinline(promp) parsecnt = 0 plevel = 0 in = parseline(0) if in > 0 then start evalcnt = 0 evalappl(envir, fun, curfun, in, tstflg, val, severity) finish else -> lp if sendflag > 0 then start ! GO BACK TO APPLYUSR if prnum > 1 then start ! NOT AT BASE LEVEL prnum = prnum - 1 promp = numtostr(prnum << 8) . ":" prompt(promp) return finish else start ! AT BASE LEVEL sendflag = 0 jumpflag = 0 finish finish val = unstack if jumpflag = 1 then start ! ERROR RETURN OR USER HAS DONE ! CONTINUE, ABORT OR QUIT stkpnt = stktop ! RESET STACK - DISCARD EXCESS LEFT BY ERROR EXIT if prnum # 1 then start ! NOT AT BASE LEVEL if jumpout = -1 then start ! USER CONTINUE jumpout = 0 jumpflag = 0 prnum = prnum - 1 promp = numtostr(prnum << 8) . ":" prompt(promp) return finish if jumpout > 0 then start ! USER ABORT OR QUIT jumpout = jumpout - 1 stack(val) prnum = prnum - 1 promp = numtostr(prnum << 8) . ":" prompt(promp) return finish finish ! FINISH PRNUM#1 jumpflag = 0 ! EITHER PRNUM=1 OR PRNUM#1 AND JUMPOUT=0 jumpout = 0 superjmp = 0 finish ! FINISH JUMPFLAG=1 -> lp end ! END LOGO ! routine ontrap(integer class, subclass) integer flag integer array info(1 : 32) flag = readid(addr(info(1))) if subclass = 'Q' then quitflag = 1 else holdflag = 1 dresume(0, 0, addr(info(1))) end ! END ONTRAP ! ! ! ! ! ! ! on event 1 start -> reinit finish ! %FAULT 17 ->REINIT reinit: begin ! MAIN PROG STARTS ! reroutecontingency(3, 65, X'20100', ontrap, flag) newsmfile("T#LOGOSTK,436029") define("6,T#LOGOSTK") fstart = smaddr(6, flength) fnval == array(fstart, intform1) oldfn == array(fstart + 4092, intform1) fntext == array(fstart + 8184, intform1) fnlen == array(fstart + 12276, intform1) fnparse == array(fstart + 16368, parseform) systk == array(fstart + 17392, intform2) la == array(fstart + 25392, intform3) bname == array(fstart + 287536, intform4) bvalue == array(fstart + 295448, intform5) assocwa == array(fstart + 307452, intform1) stk == array(fstart + 311544, intform2) wa == array(fstart + 319544, sform1) source == array(fstart + 386029, sourceform) define("2," . masnum . "LOGNAM910") initialise if restart = 0 then start ! NOT A RESTART define("1,T#DUMP") newlines(2) printstring("LOGO - VERSION 9.10 (06/12/81) " . time) newlines(2) finish else start ! RESTART printstring("REINITIALISING AND RELOADING SAVED FUNCTIONS") newline selectinput(3) finish logo(stktop, basenvir, 0) ! end end of program