@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u; C style strings - arbitrary ; length ending with a null byte;--------------------------------; Written Sept 3rd, 1987;T} by John DiMarco ;--------------------------------; Complete permission is given to ; duplicate this work, so long as ; tU}his message is included in any; duplicate. MODULEBYTE NULL=0BYTE ARRAY C_TMP(255)PROC AtoC(BYTE ARRAY A,C) ; ConverV}t from Action-style string ; to C style string ; Assume A,C are defined and ; C is as long as A. BYTE i FOR i=1 TOW} A(0) DO C(i-1)=A(i) OD C(A(0))=NULLRETURNCARD FUNC AC(BYTE ARRAY A) ; Convert an Action-style string X}; to a C style string BYTE i,j j=A(0) FOR i=1 TO j DO A(i-1)=A(i) OD A(j)=NULLRETURN (A) CARD FY}UNC CSLength(BYTE ARRAY C) CARD i i=0 WHILE C(i)<>NULL DO i==+1 ODRETURN (i) CARD FUNC CA(BYTE ARRAY C) ; CoZ}nvert a C style string to an ; Action style string BYTE i,j j = CSLength(C) FOR i=0 TO j-1 DO C(j-i)=C((j-i)-1)[} OD C(0)=jRETURN (C)PROC CtoA(BYTE ARRAY C,A) ; Convert from C style strings to ; Action style strings ; Assume \}C,A are defined and ; C is less than 255 bytes long. BYTE i FOR i=0 TO 255 DO IF C(i)=NULL THEN EXIT FI ]} A(i+1)=C(i) OD A(0)=iRETURNPROC CPrintD(BYTE Channel,BYTE ARRAY C) CARD i i=0 WH^}ILE C(i)<>NULL DO PutD(Channel,C(i)) i==+1 ODRETURNPROC CPrint(BYTE ARRAY C) CPrintD(0,C)RETURNPROC CPrint_}DE(BYTE Channel,BYTE ARRAY C) CPrintD(Channel,C) PutD(Channel,155) RETURNPROC CPrintE(BYTE ARRAY C) CPrintDE(0,C)RE`}TURN PROC CInputSD(BYTE Channel,BYTE ARRAY C) InputSD(Channel,C_TMP) AtoC(C_TMP,C)RETURN a}PROC CInputS(BYTE ARRAY C) CInputSD(0,C)RETURNPROC CInputMD(BYTE Channel, BYTE ARRAY C, BYTE max) InputMD(Channel,C_TMb}P,max) AtoC(C_TMP,C)RETURNPROC COpen(BYTE channel, BYTE ARRAY filestring, BYTE mode, aux2) CtoA(filestring, C_TMP) Oc}pen(channel, C_TMP, mode, aux2)RETURNPROC CXIO(BYTE channel, mystery, cmd, aux1, aux2, BYTE ARRAY filestring) CtoA(filesd}tring,C_TMP) XIO(channel,mystery,cmd,aux1,aux2,C_TMP)RETURNINT FUNC CSCompare(BYTE ARRAY C1,C2) INT r1,r2 CARD i ie}=0 WHILE C1(i)=C2(i) AND C1(i)<>NULL AND C2(i) <> NULL DO i==+1 OD r1=C1(i) r2=C2(i)RETURN (r1-r2) PROCf} CSCopy(BYTE ARRAY DEST,SRC) ; Make sure DEST is big enough!!! CARD i BYTE X i=0 DO DEST(i)=SRC(i) IF Sg}RC(i)=NULL THEN EXIT FI i==+1 OD RETURNPROC CSCopyS(BYTE ARRAY DEST,SRC, CARD START,STOP) ; Makeh} sure DEST is big enough!!!! ; Also make sure START and STOP are ; within SRC. CARD i i=START WHILE SRC(i-1)<i}>NULL AND i<=STOP DO DEST(i-START)=SRC(i-1) i==+1 OD DEST(i-START)=NULLRETURN PROC CSAssign(BYTE ARRAYj} DEST,SRC,CARD START,STOP) ; Make sure DEST is big enough!!!! ; Also make sure START and STOP are ; within SRC. CARD k}i i=0 WHILE SRC(i-1)<>NULL AND i<(STOP-START+1) DO DEST(i+START-1)=SRC(i) i==+1 ODRETURNPROC CStrB(BYTE numbl}er, BYTE ARRAY C) StrB(number,C_TMP) AtoC(C_TMP,C)RETURNPROC CStrC(CARD number, BYTE ARRAY C) StrC(number,C_TMP) Am}toC(C_TMP,C)RETURNPROC CStrI(INT number, BYTE ARRAY C) StrI(number,C_TMP) AtoC(C_TMP,C)RETURN BYTE FUNn}C CValB(BYTE ARRAY C) CtoA(C,C_TMP)RETURN (ValB(C_TMP))CARD FUNC CValC(BYTE ARRAY C) CtoA(C,C_TMP)RETURN (ValC(C_TMP)o})INT FUNC CValI(BYTE ARRAY C) CtoA(C,C_TMP)RETURN (ValI(C_TMP)) CValC(BYTE ARRAY C) CtoA(C,C_TMP)RETURN (ValC(C_TMP)E When I first purchased an Action!cartridge, I was favourably impressedwith the clarity, power, and - most especially - q} with the speed of thelanguage and the compiler. But I have come across what I consider tobe two major shortcomings with t r}helanguage which have made it less thanwonderful. Firstly, nested functioncalls are prohibited. This makes it necessary t s}o store function results in temporary variables for use in subsequent function calls. This makes source code unnecessarily t}lengthy and can detract from its clarity. Secondly, because the firstbyte of an Action! string is thelength of that strin u}g, strings canbe no longer than 255 characters.This detracts from the usefulness ofaction strings for storage of any larg v}e amounts of data. I much preferstrings as they are managed in C, where a string is any number of characters terminated by w} a null (ASCII 0) byte. In C, strings canbe arbitrarily long, and thus canbe used for word processor text buffers, for ex x}ample. There was really nothing I coulddo about Action!'s inability to support nested function calls, butC-style stri y}ngs were really quite easy to implement in Action!, and so I wrote and tested this packagein a couple of hours. All I did z}wasrewrite all the standard Action!string functions (Scopy, SCompare,SAssign, etc.) and the standard input/output routine {}s (PrintE, InputS, even Open and XIO) to supportC-style strings rather than Action!strings. I also included a coupleof co |}nversion routines to convertAction! strings to C strings and viceversa. With this package, it is possible to support both }}Action! andC style strings in the same program, and convert between them at will. To include these routines in yourprogr ~}am, simply add an 'INCLUDE"CSTRINGS.ACT"' to the beginningof your program.The routines are as follows:PROC AtoC(BYTE AR }RAY A,B) - This routine assumes that A is an Action! string and B isa BYTE ARRAY which is at least asbig as A. It w }ill convert the Action!string A to the same string in Cstyle format, which it will store inB. A should not contain a null. }(ATASCII 0 or '')PROC CtoA(BYTE ARRAY A,B) - This routine assumes A is aC style string, and converts it toan Act }ion! string which it stores inB. The C style string should not belonger than 255 characters, otherwiseonly the first 255 c }haracters willbe converted. CARD FUNC AC(BYTE ARRAY A) - This routine converts thestring A from an Action! string }to aC style string. A should not containa null. CARD FUNC CA(BYTE ARRAY A) - This routine converts thestring A fr }om a C style string to anAction! string. A should not belonger than 255 characters. CARD FUNC CSLength(BYTE ARRAY A) } - Returns the length of theC style string A. The NULL byte is not included in this figure.PROC CPrint, CPrintE, CPrint }DE, CPrintD - Print out a C style string. Any C style string of arbitrary length may be printed. Syntax isexa }ctly the same as in the Action!manual.PROC CInputS, CInputSD, CInputMD - Input a C style string. Only strings of l }ength less than orequal to 255 characters may be input.Syntax is as in Action! manual.PROC COpen, CXIO - Open a ch }annel or performan XIO function where the filespecis a C style string. Only filespecsof length less than or equal to 255 }characters are permitted (butwhy you'd need more, I don't know!)Syntax as in Action! manual.PROC CSCompare, CSCopy, CSCop }yS, CSAssign - Compare or copy C style strings. Numerical arguments to these functions are CARDs ratherthan B }YTEs, since C style strings arenot limited to a length of 255 characters. Syntax as in Action!manual.PROC CStrB, CStrC, }CStrI - Convert a BYTE, CARD, or INTto a C style string. Syntax as inAction! manual.BYTE/CARD/INT FUNC CValB, CVal }C, CValI - Convert a C style string toa BYTE, CARD, or INT. Syntax as inAction! manual. MISC }ELLANOUS NOTES: You may easily change the NULLbyte to some value other than ATASCII0 by changing the NU }LL variable atthe beginning of the CSTRINGS.ACTfile. Note, however, that the CSCompare routine will not work correctly if } you do so. The routinesuse BYTE ARRAY C_TMP(255) as a globaltemporary buffer, and thus no globalvaria }ble of the name C_TMP is permitted. I hope these routines help you in making better use of the Action!programming langua }ge.Thurs, Sept. 3, 1987. -- John DiMarcoUUCP: jdd@csri.toronto.eduaking better use of the Action!programming langua K; INSTR.ACT ; in-string? function for Action! ; By Bill Kendrick New Breed Software 1994 ; (Originally written for Glen}n Saunders ) ; Accepts string to search in, string to look for, ; starting point in string to start searching; ; r}eturns first location that string to look for is ; found in the string to search in, or 0 if it cannot ; be found. Byte }Func InStr(Char Array String, Sub Byte Start) Byte Where,TempWhere,InSub,Look Where=0 ; init for this call T}empWhere=0 InSub=1 If String(0)>=Start+Sub(0)-1 And String(0)>0 And Sub(0)>0 Then ; be sure enough room for it! } For Look=Start To String(0) Do If String(Look)=Sub(InSub) Then If InSub=1 Then TempWhere=Look } Fi ; this might be it InSub=InSub+1 If InSub>Sub(0) Then Where=TempWhere ; it IS it! } Look=String(0) ; easy way to POP a FOR loop :) Fi Else If TempWhere<>0 Then Look=T}empWhere Fi InSub=1 ; no, that's not it! TempWhere=0 Fi Od ; Look Fi Return(Where)} PROC TEST() CHAR ARRAY A(100),B(100) BYTE W DO PRINTE("ENTER STRING") INPUTS(A) PRINTE("ENTER S}EARCH") INPUTS(B) W=0 DO W=INSTR(A,B,W+1) PRINTBE(W) UNTIL W=0 OD ; SEARCH UNTIL NO MORE } PUTE() UNTIL B(0)=0 OD RETURN W=INSTR(A,B,W+1) PRINTBE(W) UNTIL W=0 OD ; SEARCH UNTIL NO MORE (;The following Action! routine will provide you with a fix for the bugs ;in divide in Action! It should be self-explanatory.}.. MODULE ; NEWDIVI.ACT ; (c) 1983 ACS ; Copyright (c) 1983 ; by Action Computer Services (ACS) ; Permission is granted to} duplicate ; and/or distribute the contents of ; this file to any licensed user of ; OSS ACTION. This copyright notice ; mus}t be replicated in all such ; copies. Copies of this file may ; not be sold or otherwise used for ; monetary gain. ; This f}ile fixes the problems with ; the ACTION! divide routine and ; should be included within all your ; ACTION! programs until su}ch time ; as an update ROM is available. ; TO USE: ; 'INCLUDE' this file in front ; of all your PROCedures and ; } FUNCtions. ; e.g. INCLUDE "D2:NEWDIVI.ACT" PROC DivI=*() [ $20 $A06C $85 $86 $A2 $10 $26 $82 $26 $83 $26 $86 $26 $8}7 $38 $A5 $86 $E5 $84 $A8 $A5 $87 $E5 $85 $90 $04 $85 $87 $84 $86 $CA $D0 $E5 $A5 $82 $2A $26 $83 $A6 $83 $4C} $A032] PROC REMI=*() [$20 DivI $86A5 $87A6 $60] SET $4EA=DivI SET $4EC=RemI ; End of MODULE NEWDIVI.ACT 3 $A6 $83 $4ClFrom hufnagel Thu Dec 1 09:16:15 1994 Return-Path: Received: by zippy.sonoma.EDU (4.1/SMI-4.0) id AA23081; Th}u, 1 Dec 94 09:16:14 PST Date: Thu, 1 Dec 94 09:16:14 PST From: hufnagel (Michael Hufnagel) Message-Id: <9412011716.AA2308}1@zippy.sonoma.EDU> To: kendrick Subject: here Status: RO >From KENDRICK@sonoma.edu Thu Dec 1 08:26:00 1994 To: bob@z}ippy.sonoma.EDU, LYLEM@sonoma.edu, HUFNAGEL@sonoma.edu, comp-sys-atari-8bit@cs.utexas.edu Subject: Recursion in Act}ion! This seems to do it! (STACKTST.ACT/.C/.BAS) The following file is the C code I first came up with when I was thin}king of how to go about adding a local-variable stack to Action! so that PROCedures and FUNCtions can be made to do recursio}n. I tested it out in Think C++ on a Macintosh but didn't trust it since, well, C handles this by itself, so all I could} be doing is wasting memory! But never fear, two files follow this: -----------------begin-stacktst.c-------------------}--- /* StackTst.c: Stack Test program for adding recursion to Action! */ #include "stdio.h" int sp; int stack[1024]; } void overflow() { printf("Overflow\n"); } void underflow() { printf("Underflow\n"); } void init() { sp=0;} } void push(int x) { stack[sp]=x; sp=sp+1; if (sp>1024) overflow(); } int pop() { if (sp==0) underfl}ow(); else { sp=sp-1; return(stack[sp]); } } /* -- */ int factorial(int n) { int m; if (n<=1) m=}1; else { push(n); m=factorial(n-1); n=pop(); m=m*n; } return m; } void main() { prinf("6!=%d\n",f}actorial(6)); } /* By Bill Kendrick 11/29/1994 */ /* See STACKTST.ACT... */ -----------end---------- Well, since I} didn't trust it, I started writing another text program in QBASIC on an IBM. Of course, at first I started out writing the} thing with "SUBS" and "FUNCTIONS"! Duh! QBASIC probably uses a stack for local variables too! So I started over and jus}t used GOSUBS and passed variables to my GOSUB'd functions via "x" and "n" variables. The code looks much more drawn out t}han it needs to be in a higher level language, but for you Atari BASIC and TurboBASIC XL users, you may find this useful no}netheless. BTW: This seems to work too! :) ----------begin-stacktst.bas------- 1 ' StackTst.Bas 2 ' by Bill Kendrick 11}/29/1994 3 ' Test of StackTst.c code in (Q)BASIC without using real 4 ' FUNCs. 5 DIM stack(100) 6 GOTO 1000 10 ' pus}h 11 stack(sp) = x 12 sp = sp + 1 13 RETURN 20 ' pop 21 sp = sp - 1 22 x = stack(sp) 23 RETURN 100 ' factorial 1}01 IF n <= 1 THEN 102 m = 1 103 ELSE 104 x = n ' \ push(n) 105 GOSUB 10 ' / 106 n = n - 1 ' \ 107 } GOSUB 100 ' > m=factorial(n-1) 108 m = x ' / 109 GOSUB 20 ' \ m=pop() 110 n = x ' / 111 m }= m * n 112 END IF 113 x = m ' return(x) 114 RETURN 1000 ' main 1001 n = 6 ' \ 1002 GOSUB 100 ' > pri}nt factorial(6) 1003 PRINT x ' / 1004 END ----------end---------- Finally, after this last sucessful trial, I cam}e up with the following Action! code, based on the C code above. I ran it, got "720" as a result (6!=720), screamed and ju}mped up and down; proceeded to tell the person on the other line what had just happened (giving her a breif description of }recursion and factorial), then apologized and asked her to repeat what she was saying a moment before. ANYWAYS, I ha}dn't booted any DOS with the thing and was planning on using SIO2PC's Print-Thru and Atari's built in P:rinter device to ma}ke a copy of the thing as a file on my PC, but accidentally hit "D" for DOS instead of "E" for editor in Action!'s monitor }and poof it was gone and I was enjoying the OS's Self-Test menu . The following is obviously not my ORIGINAL code , AND IS NOT IDENTICAL to the C code! This gives you a menu letting you chose between FACTORIAL, FIBONACCI, and ACKERMA}NN recursive functions. ACKERMANN has not been tested, and when doing FACTORIAL and FIBONACCI, remember that I used INTs, s}o when it calculates values over 32767 or below -32768, the variable will have over-/under-flowed and answers will be wrong}, but hell, at least it works for INTs! :) ----begin-stacktst.act----- ; STACKTST.ACT ; Local variable stack handler f}or ; Action! test program. ; By Bill Kendrick 11/29/1994 DEFINE STACKSIZE="200" DEFINE LARGESTTYPE="CARD" } ; Type mismatches don't create errors, ; so use the largest (2-bytes) available C}ARD SP ; Stack pointer LARGESTTYPE ARRAY STACK(STACKSIZE) ; Stack storage space PROC OVE}RFLOW() PRINTE("OVERFLOW") ; Display error PRINT("STACK POINTER ABOVE ") PRINTCE(STACKSIZE) BREA}K() ; and abort program RETURN PROC UNDERFLOW() PRINTE("UNDERFLOW") PRINTE("STACK POINT}ER BELOW 0") BREAK() RETURN PROC INIT() ; All we need to do here is reset the SP=0 } ; stack pointer either before a RETURN ; recursive function's called} or at ; program start. PROC PUSH(LARGESTTYPE V) STACK(SP)=V } ; Store value SP=SP+1 ; Increment stack pointer IF SP>=STACKSIZE-2 THEN ; }Test for overflow OVERFLOW() FI RETURN LARGESTTYPE FUNC POP() LARGESTTYPE V IF SP=0 THEN } ; Test for possible underflow UNDERFLOW() ELSE SP=SP-1 ; Decrement stack pointe}r V=STACK(SP) ; Retrieve value FI RETURN(V) ; ---------------------------------- INT FUN}C FACTORIAL(INT N) INT M ; Temporary variable; its value is } ; RETURN'd IF N<=1 THEN ; 1!=1.. M=1 ELSE PUSH(N) ; P}ush before recursion M=FACTORIAL(N-1) ; Call function for N-1, store in M N=POP() } ; (Get old N after last recursion was ; returned from) M=M*N } ; Multiply.. FI RETURN(M) ; ..and return value INT FUNC ACKERMANN(INT X,}Y) INT R R=0 IF X=0 AND Y>=0 THEN R=Y+1 ELSEIF Y=0 AND X>0 THEN PUSH(X) PUSH(Y) R=ACKERMANN}(X-1,1) Y=POP() X=POP() ELSE PUSH(X) PUSH(Y) R=ACKERMANN(X,Y-1) Y=POP() X=POP() PU}SH(X) PUSH(Y) R=ACKERMANN(X-1,R) Y=POP() X=POP() FI RETURN(R) INT FUNC FIBONACCI(INT N) INT R1,}R2 ; Temporary variable; its value is ; RETURN'd IF N=0 O}R N=1 THEN ; FIB(0)=0,FIB(1)=1 R1=N R2=0 ELSE PUSH(N) ; Push bef}ore recursion R1=FIBONACCI(N-1) ; Call function for N-1, store in M N=POP() PUSH(R1) } ; Push before recursion PUSH(N) ; Push before recursion R2=FIBONACCI(N-2)} ; Call function for N-1, store in M N=POP() R1=POP() ; (Get old N after l}ast recursion was ; returned from) FI R1=R1+R2 RETURN(R1) } ; ..and return value PROC MAIN() INT A,B,RESULT INIT() ; Init Stack PRINTE("}1=FACTORIAL") PRINTE("2=ACKERMANN") PRINTE("3=FIBONACCI") A=INPUTB() IF A=1 THEN PRINTE("Factorial") } ; Title/instructions: PUTE() ; (blank line (PUT End Of Line)) PRINTE("Enter '}A' and I will") PRINTE("show you 'A!'.") PUTE() PRINTE("Enter '0' to quit.") DO PUTE() PRIN}T(" A=") ; Prompt (no EOL after) A=INPUTI() ; Read integer RESULT=F}ACTORIAL(A) ; Call function PRINT("A!=") ; Display results PRINTIE(RESULT) } UNTIL A=0 OD ; Quit when A=0 ELSEIF A=2 THEN PRINTE("Ackermann") ; Title/ins}tructions: PUTE() ; (blank line (PUT End Of Line)) PRINTE("Enter 'A' and 'B' and I") } PRINTE("will show you") PRINTE("ACKERMANN(A,B).") PUTE() PRINTE("Enter '0' to quit.") DO PUTE(}) PRINT(" A=") ; Prompt (no EOL after) A=INPUTI() ; Read integer } PRINT(" B=") ; Prompt (no EOL after) B=INPUTI() ; Read integer } RESULT=ACKERMANN(A,B) ; Call function PRINT("ACKERMANN(A,B)=") ; Display results PRINTIE(}RESULT) UNTIL A=0 OD ; Quit when A=0 ELSEIF A=3 THEN PRINTE("Fibonacci") }; Title/instructions: PUTE() ; (blank line (PUT End Of Line)) PRINTE("Enter 'A' and I }will show") PRINTE("you FIBONACCI(A).") PUTE() PRINTE("Enter '0' to quit.") DO PUTE() PRINT}(" A=") ; Prompt (no EOL after) A=INPUTI() ; Read integer RESULT=FI}BONACCI(A) ; Call function PRINT("FIBONACCI(A)=") ; Display results PRINTIE(RESULT) } UNTIL A=0 OD ; Quit when A=0 FI PRINTE("Bye!") RETURN -----end----- Final notes: With} the C code, you are restricted (unless you can get C to ignore type mismatches) to using INTs (or whatever you make your }stack out of); oh, wait, perhaps I'm wrong. It has been a while. Well, anyways, don't TRUST any code you make using that (w}hy would you use the C one is beyond me ) until you have TESTED it thoroughly. In BASIC, you should be restricted to} "reals"/"floats"/whatever you want to call them. This of course includes INTs because BASIC handles conversion to/from f}or you (this is in QBASIC; Atari BASIC / TurboBASIC XL don't actually have any other type other than INTs). In Action!, }CARD is the largest type (2-bytes) and everything else is as big or smaller (INT=2 bytes, addresses=2 bytes, BYTEs=1 byte, } CHARs=1 byte, POINTERs=2 bytes, etc.). Be warned not to try to do recursion with CHAR ARRAYs (strings) or any other type }of array, or with records without being careful, and perhaps rewriting some of the PUSH/POP code. Also, I'm sure you could} do something like this as well: PROC PUSH(BYTE many, CARD a1,a2,a3,a4,a5,a6) ; I think Action! handles } ; only 8 params max. ... PROC POP(BYTE many, CARD POINTER a1,a2,a3,a4,a5,a6) ; not FUNC }any more to pass more than one value at a time to/from the stack. Well, that's it! Have fun! Has anyone found an easier}/better way to do recursion in Action! !? Later! -bill! kendrick@vax.sonoma.edu ||| kendrick@zippy.sonoma.edu Willi}am (Bill) Kendrick / | \ ** New Breed Software ** NEW BREED SOFTWARE: Atari 8-bit and IBM PC software! E-mail for info! } ll) Kendrick / | \ ** New Breed Software ** NEW BREED SOFTWARE: Atari 8-bit and IBM PC software! E-mail for info! B%DOS SYSB*)DUP SYSBSCSTRINGSACTB%pCSTRINGSDOCB INSTR ACTB NEWDIVI ACTB]STACKTSTTXT