LoginLogin

Def codes for making codes

Root / General / [.]

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
END
also, 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

MAIN

DEF MAIN
 'entire program goes here
END
DEF BOUND(min%,var%,max%)
 RETURN MIN(MAX(min%,var%),max%)
END

DEF PLEASE DIE
END
S$="ABCDEFGH"
PLEASE POP(S$)

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).
A*B+!A*C
DEF PLEASE DIE
END
I've used this one before, though I named mine DROP after the Rust function of the same name.

DEF PLEASE DIE
END
S$="ABCDEFGH"
PLEASE POP(S$)
Reminds me of INTERCAL
PLEASE READ OUT ,1
PLEASE GIVE UP

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 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
If you want a REPLACE$ that is faster than/independent of SPLIT$/JOIN$ (though the function composition approach is neat) you can use:
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$
END
taken 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 'iirc
but that was before I found out FILL existed :/

Reminds me of INTERCAL
Yeah that was the intention. This also allows code like:
PLEASE DO PRINT "Hello, World!"
PLEASE DON'T CLS
Maybe 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:
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.

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?

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$
END
And 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
END
Miscellaneous 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
END
Better 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

Whoa this thread went BOOM! I wasn't expecting it to get this popular!

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
END
You 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.