Def codes for making codes
randoCreated:
Here we can share ideas for that, and what we have developed for user defined instructions. ill start.
DEF MULTI2 LABLE1, LABLE2 WHILE 1 GOSUB LABLE1 GOSUB LABLE2 WAIT 1 WEND 'LABLES HERE ENDalso, note that you dont want any loops after the lables before the end, its already in a loop and if you do it wont ever make it to the other gosub.
Just post some useful DEF blocks? Okay...
Spoiler
COMMON DEF ENABLE3D FONTDEF 0, "00010000"*32 END COMMON DEF DISABLE3D FONTDEF 0, "00000000"*32 END COMMON DEF GPSET3D X, Y, EYE IF X MOD 2==EYE THEN GPSET X, Y END COMMON DEF GLINE3D X1, Y1, X2, Y2, EYE VAR RISE=Y2-Y1 VAR RUN=X2-X1 VAR X,Y,OFF IF RUN==0 THEN IF Y1>Y2 THEN SWAP Y1,Y2 FOR Y=Y1 TO Y2 GPSET3D X1, Y, EYE NEXT RETURN ENDIF VAR M=RISE/RUN VAR ADJUST, THRESHOLD, THRESHOLDINC, DELTA IF M>=0 THEN ADJUST=1 IF M<0 THEN ADJUST=-1 IF M>=-1 AND M<=1 THEN THRESHOLD=ABS(RUN) THRESHOLDINC=ABS(RUN)*2 DELTA=ABS(RISE)*2 OFF=0 IF X1>X2 THEN SWAP X1,X2 Y=Y2 ELSE Y=Y1 ENDIF FOR X=X1 TO X2 GPSET3D X, Y, EYE OFF=OFF+DELTA IF OFF>=THRESHOLD THEN Y=Y+ADJUST THRESHOLD=THRESHOLD+THRESHOLDINC ENDIF NEXT ELSE THRESHOLD=ABS(RISE) THRESHOLDINC=ABS(RISE)*2 DELTA=ABS(RUN)*2 OFF=0 IF Y1>Y2 THEN SWAP Y1,Y2 X=X2 ELSE X=X1 ENDIF FOR Y=Y1 TO Y2 GPSET3D X, Y, EYE OFF=OFF+DELTA IF OFF>=THRESHOLD THEN X=X+ADJUST THRESHOLD=THRESHOLD+THRESHOLDINC ENDIF NEXT ENDIF END
This ternary function saves me sooo much space and time. Super flexible, works anywhere, and for any type of variable.
DEF IFF(A,B,C) IF A THEN RETURN B ELSE RETURN C END
Here's a more limited ternary expression useful for code golf (e.g. OSP/QSP).DEF IFF(A,B,C) IF A THEN RETURN B ELSE RETURN C END
A*B+!A*C
I've used this one before, though I named mine DROP after the Rust function of the same name.DEF PLEASE DIE END
When parsing, these are crucial to have
'GET AN ARRAY OF SUBSTRINGS 'STRING, DELIMITER, ALLOW_EMPTY_STRINGS DEF SPLIT$(S$,D$,E%) VAR I%,J%,A$[0],L%=LEN(S$),D%=LEN(D$) REPEAT J%=INSTR(I%,S$,D$) IF J%<0 THEN J%=L% IF E%||J%-I% THEN PUSH A$,MID$(S$,I%,J%-I%) I%=J%+D% UNTIL J%==L% RETURN A$ END 'JOIN AN ARRAY OF STRINGS TOGETHER 'STRING_ARRAY, DELIMITER DEF JOIN$(S$,D$) IF !LEN(S$) THEN RETURN "" IF LEN(S$)==1 THEN RETURN S$[0] RETURN JOIN$(S$,D$)+D$+POP(S$) END 'REPLACE ALL OCCURRENCES OF A$ WITH B$ 'STRING, A, B DEF REPLACE$(S$,A$,B$) RETURN JOIN$(SPLIT$(S$,A$,1),B$) END
When parsing, these are crucial to haveIf you want a REPLACE$ that is faster than/independent of SPLIT$/JOIN$ (though the function composition approach is neat) you can use:'GET AN ARRAY OF SUBSTRINGS 'STRING, DELIMITER, ALLOW_EMPTY_STRINGS DEF SPLIT$(S$,D$,E) VAR I,J,A$[0],L=LEN(S$),D=LEN(D$) REPEAT J=INSTR(I,S$,D$) IF J<0 THEN J=L IF E||J-I THEN PUSH A$,MID$(S$,I,J-I) I=J+D UNTIL J==L RETURN A$ END 'JOIN AN ARRAY OF STRINGS TOGETHER 'STRING_ARRAY, DELIMITER DEF JOIN$(S$,D$) IF !LEN(S$) THEN RETURN "" IF LEN(S$)==1 THEN RETURN S$[0] RETURN JOIN$(S$,D$)+D$+POP(S$) END 'REPLACE ALL OCCURRENCES OF A$ WITH B$ 'STRING, A, B DEF REPLACE$(S$,A$,B$) RETURN JOIN$(SPLIT$(S$,A$,1),B$) END
DEF REPLACE$(S$,A$,B$) VAR W$,I% VAR O%=LEN(O$) VAR N%=LEN(N$) COPY W$,S$ I%=INSTR(W$,O$) WHILE I%!=-1 W$=SUBST$(W$,I%,L%,N$) I%=INSTR(I%+N%,W$,O$) WEND RETURN W$ ENDtaken from Yarn. also your use of reals instead of ints is somewhat disturbing
I used to use
DEF FILL_ARR ARR,A FOR I=0 TO LEN(ARR)-1 ARR[i]=A NEXT END 'iircbut that was before I found out FILL existed :/
Reminds me of INTERCALYeah that was the intention. This also allows code like:
PLEASE DO PRINT "Hello, World!" PLEASE DON'T CLSMaybe I should've defined it as DEF PLEASE DO:END though. Anyway, here's a function to read any type of DATA:
DEF READANY OUT ISSTRING%,NUMBER,STRING$ IF FALSE THEN DIM A[0] READ A ISSTRING%=(A>0)==3 IF ISSTRING% THEN STRING$=A NUMBER=0 ELSE NUMBER=A STRING$="" ENDIF END
Anyway, here's a function to read any type of DATA:Not sure I'm following this correctly. STRING$ is not used outside of declaration, and instead an undeclared NUMBER$ is used? When I ran the code, I got a Type mismatch error on the line of calling (not inside the DEF block). And what's up with the IF FALSE THEN ... shenanigan? And how exactly does line 4 distinguish between strings and numerics? A string is always equal to 3, so how would it distinguish between 3-num and 3-str? Also, line 4 always returns 0 for TYPE%, unless A is a negative value.DEF READANY OUT TYPE%,NUMBER,STRING$ IF FALSE THEN DIM A[0] READ A TYPE%=A>0<1 IF TYPE% THEN NUMBER$=A NUMBER=0 ELSE NUMBER=A NUMBER$="" ENDIF END
Not sure I'm following this correctly. STRING$ is not used outside of declaration, and instead an undeclared NUMBER$ is used? When I ran the code, I got a Type mismatch error on the line of calling (not inside the DEF block). And what's up with the IF FALSE THEN ... shenanigan? And how exactly does line 4 distinguish between strings and numerics? A string is always equal to 3, so how would it distinguish between 3-num and 3-str? Also, line 4 always returns 0 for TYPE%, unless A is a negative value.Oh... what the heck... I SWEAR I typed STRING$ there... Anyway I updated my post to fix the mistakes. DIM A[0] creates an untyped variable, and only makes it an array when that line is executed. If it's skipped, the variable stays untyped and you can set it to whatever type you want. A>0 will always be 0 or 1, unless A is a string, when it's 3 for some reason (I meant to write >1 there, not <1) So this post isn't useless, here's a WORKING mod function (Unlike the MOD operator which only produces the correct result for positive integers)
DEF WRAP(A,B) RETURN A-FLOOR(A/B)*B END
Has the method for creating an untyped variable changed? I swear it used to be done simply by declaring DIM A, which could be set to any type only once and only inside a def block. Looking through my old programs, this is how I've done it, so it must've been a feature at one point?No, that just creates a float (or integer with OPTION DEFINT) My favorite join function:
DEF JOIN$(ARRAY$[],DELIMITER$) VAR STRING$ FOR I=0 TO LEN(ARRAY$)-1 IF I THEN INC STRING$,DELIMITER$ INC STRING$,ARRAY$[I] NEXT RETURN STRING$ ENDAnd a similar debug function so you an actually see what is in an array...
DEF DEBUG A ?"["; FOR I=0 TO LEN(A)-1 IF I THEN ?","; ?A[I]; NEXT ?"]" END
These are simple but some of my favorites.
REDIM A,L
redimensions a pre-existing array that has at least one element (it can't determine the type of an array if it has no elements). It can add or remove elements.
TRIM A,M,N
trims the elements of array A at positions M through N inclusively.
COMMON DEF REDIM A[],L% DIM AL%=LEN(A) IF(L%>AL%)&&(AL%>.)THEN IF.THEN DIM T[.] IF(CHECK TYPE(A[.])==2)THEN(T)=("")ELSE(T)=. WHILE(L%>AL%)PUSH(A),(T)INC(AL%)WEND ELSEIF(L%<AL%)THEN WHILE(L%<AL%)_(POP(A))DEC(AL%)WEND ENDIF END
COMMON DEF TRIM A[],M%,N% DIM P0%=(M%),P1%=(N%):IF(P0%>P1%)THEN SWAP(P0%),(P1%) DEC(P1%),(P0%-1) WHILE(P1%>.)DISCARD(A),(P0%)DEC(P1%)WEND ENDMiscellaneous functions to make the previous two functions work:
REM Returns the type of X COMMON DEF CHECKTYPE(X) IF(X||0)==3THEN RETURN(2) RETURN(X*0-&H80000000<0) END REM Voids whatever value is given to it COMMON DEF _ N END REM Discards element of array A at position P% COMMON DEF DISCARD A[],P% COPY(A),(P%),(A),(P+1),LEN(A)-(P%+1)_(POP(A)) END
Better redim (works on empty arrays):
DEF REDIM ARRAY[],NEWLEN IF LEN(ARRAY)<NEWLEN THEN COPY ARRAY,NEWLEN,ARRAY,0 ELSE WHILE LEN(ARRAY)>NEWLEN IF POP(ARRAY) THEN ENDIF WEND ENDIF ENDBetter trim (Note: range is exclusive-end):
DEF TRIM ARRAY[],START,END% COPY ARRAY,START,ARRAY,END%,LEN(ARRAY)-END% REDIM ARRAY,LEN(ARRAY)-(END%-START) END
CHKPROJECT: Check if the project named P$ exists.
DEF CHKPROJECT(P$) DIM F$[0] VAR T$ VAR I% COPY T$,P$ IF RIGHT$(T$,1)!="/" THEN INC T$,"/" IF T$=="[DEFAULT]/" THEN T$="/" IF T$=="[SYS]" THEN T$="SYS/" IF T$=="/" THEN RETURN TRUE IF T$=="SYS/" THEN RETURN TRUE IF T$=="./" THEN RETURN TRUE FILES "//",F$ FOR I%=0 TO LEN(F$)-1 IF F$[I%]==T$ THEN RETURN TRUE NEXT RETURN FALSE ENDYou may omit the trailing slash a la CHKPROJECT("HELLO") and it will handle that for you (to mirror the behavior of FILES.) This is probably the simplest way to do this check, but it's the most effective. If you give it a name that can't possibly be a valid project name it'll just tell you false, anyway.