This project was motivated by an assignment I did in CS 24 (Computing Systems) during my Sophomore year at Caltech, where we had to create an assembly generator (
asmgen) for the TEENY-BASIC programming language. After this, it occurred to me that I could simply expand the code-base for the language to include some additional simplistic features.Firstly, in the original TEENY-BASIC programming language, variables are defined with the
LET command, and all variables have to be single-character uppercase letters, and these variables strictly denote either strings, integers, or floating point numbers. So, for instance, the syntax for setting a variable \(X\) to 3 or setting a variable \(Y\) to \(3.14\) or setting a variable \(Z\) to "Hello, World!" would be:
LET X = 3;LET Y = 3.14;LET Z = "Hello, World!";
Secondly, TEENY-BASIC also allows users to print strings, numbers, and even the values of variables through the
PRINT command. For instance, the snippets of code below would allow you to print the value of \(X\), print "Hello, World.", and print the number \(1729\), respectively.PRINT X;PRINT "Hello, World.";PRINT 1729;
Thirdly, TEENY-BASIC allows conditionals as a functionality through the
IF...THEN...ENDIF command. For example, define the variables \(A=3\) and \(B=6\). It is only valid to compare strings to other strings, and to compare integers or floats to each other. The code below uses the IF command to allow you to check whether A is greater than, less than, or equal to B. It then uses the PRINT command to output an appropriate message to the user.LET A = 3;LET B = 6;IF A < B, THEN PRINT "A is less than B." ENDIF;IF A = B, THEN PRINT "A is equal to B." ENDIF;IF A > B, THEN PRINT "A is greater than B." ENDIF;
TEENY-BASIC additionally supports the use of nested conditionals (
IF commands nested within IF commands). For instance, given variables \(A = -2\) and \(B = 3\), the code below uses nested conditional statements to tell you which variables are positive.LET A = -2;LET B = 3;IF A > 0, THEN IF B > 0, THEN PRINT "A and B are positive." ENDIF ENDIF;IF A > 0, THEN IF B <= 0, THEN PRINT "A is positive, B is not positive." ENDIF ENDIF;IF A <= 0, THEN IF B > 0, THEN PRINT "A is not positive, B is positive." ENDIF ENDIF;IF A <= 0, THEN IF B <= 0, THEN PRINT "A andd B are not positive." ENDIF ENDIF;The final, and most computationally powerful, functionality of TEENY-BASIC is the
WHILE command. The WHILE command repetitively runs a segment of code until a condition is met. The segment of code (called a sequence) is defined as all the code after the line containing the while statement that is also before a closing ENDWHILE command for the loop. For instance, the following snippet of code can be used to print the message "Hello, World!" 20 times.LET I = 0;WHILE I < 20 DO PRINT "Hello, World!";ENDWHILE
The applications of
WHILE loops are endless. The above code snippet shows how it can automate a fundamentally simple task of printing a message instead of forcing the user to type the same line 20 times, which is terribly space-inefficient. A more practical application of the while loop can be to compute and print the factorial of a non-negative integer stored in variable \(X\).IF X <= 1, THEN PRINT 1 ENDIF;LET P = 1;WHILE X > 1 DO LET P = P * X;LET X = X - 1;ENDWHILEPRINT P;However, here is where the TEENY-BASIC functionality ends. The Tim programming language adds onto TEENY-BASIC through the fundamental addition of some obvious commands such as the
FOR loop and REPEAT loop. Additionally, Tim supports the exponentiation, modulo, and quotient operators. Furthermore, Tim has an in-built list feature that can allow users to perform basic array operations such as sorting and frequency-counting. Moreover, Tim allows more complex choices of variable names, as long as they are not a pre-defined Tim keyword. Finally, Tim allows to directly view the TYPE of a variable. The remainder of this section explains these functionalities, and finally provides some examples of robust and versatile algorithms that Tim is capable of executing.In Tim, the
FOR loop can be executed using the FOR...TO...NEXT command. The FOR loop instantiates a local counting variable that is not accessible within the code of the program, and runs the code sequence as many times as it takes for the counting variable to traverse from the start value to the end value while it increments by 1 each time. For instance, the following code snippet prints all the numbers between \(5\) and \(20\).FOR I = 5 TO 20PRINT I;ENDFOR
Next, Tim supports the execution of
REPEAT loops using the REPEAT...UNTIL command. The original WHILE command is a pre-condition loop: it first checks that a condition is met. If the condition is met, it runs the code sequence, and then continues to keep re-running the code sequence as long as the original condition is met. However, the REPEAT...UNTIL command is a post-condition loop: it runs the code sequence first, and then checks that the condition is not met, and then repeats this process until the condition is met. For instance, the code below prints the first \(N\) Fibonaccci numbers.LET A = 0;PRINT A;LET B = 1;PRINT B;LET Count = 2;REPEATLET C = A;LET A = B;LET B = A + B;PRINT B;LET Count = Count + 1;UNTIL Count = 20;
Next, in addition to addition, subtraction, multiplication, and division, Tim performs some fundamental operations such as exponentiation with integer powers, as well as finding modulos and quotients. The code snippets below can be used to calculate and print the outputs of \(0.5^2, 2^{10}, 3^{-2}\), and \(6^0\), respectively.
PRINT 0.5^2;PRINT 2^10;PRINT 3^(-2);PRINT 6^0;Similarly, the code snippet below can be used to calculate and print the remainders (after division) of 1) \(3\) with \(5\), 2) \(8\) with \(5\), 3) \(0.2\) with \(0.1\), and 4) \(-0.4\) with \(0.1\), respectively.
PRINT 3%5;PRINT 8%5;PRINT 0.2%0.1;PRINT (-0.4)%0.1;Likewise, the code snippet below can be used to calculate and print the quotients of 1) \(3\) with \(5\), 2) \(8\) with \(5\), 3) \(0.2\) with \(0.1\), and 4) \(-0.4\) with \(0.1\), respectively.
PRINT 3//5;PRINT 8//5;PRINT 0.2//0.1;PRINT (-0.4)//0.1;In addition to the string, integer, and float type, Tim also supports the implementation of lists of either strings, integers, or floats (though not more at once). The Tim lists can be stored as variables by the regular Tim syntax, and must be instantiated with a fixed type and size. Elements in Lists of
TYPE string as instantiated with "", whereas elements in Lists of TYPE integer and float are instantiated with 0 and 0.0 respectively. The following code snippets illustrates how to create Tim lists of strings, integers, and floats, respectively, of size \(N=10\).LET N = 10;LET X = LIST(STRING, N);LET Y = LIST(INTEGER, N);LET Z = LIST(FLOAT, N);Additionally, the Tim
TYPE command can allow users to find the type of a specific variable. For instance, an exhaustive list of Tim types are STRING, INTEGER, FLOAT, LIST_STRING, LIST_INT, LIST_FLOAT, and NONE. The code snippets below use the TYPE command to find the types of various variables, and then prints these types to the user.LET A = 10;LET B = "Hello, World!";LET C = 0.502;LET D = LIST(STRING, 10);LET E = LIST(INTEGER, 10);LET F = LIST(FLOAT, 10);PRINT TYPE(A);PRINT TYPE(B);PRINT TYPE(C);PRINT TYPE(D;PRINT TYPE(E);PRINT TYPE(F);PRINT TYPE();Furthermore, Tim
lists have three key features. Firstly, it allows 0-valued indexing. So, for instance, the code below can be used to initialize an integer list \(A\) with 3 elements, and sets them to 60, 65, and 70, respectively.LET X = LIST(INTEGER, 3);LET X[0] = 60;LET X[1] = 65;LET X[2] = 70;Secondly, Tim
lists allow full-stack operations. So, Tim allows operations between an integer or float array and a scalar float or integer, where it uniformly applies the operation with the scalar parameter to every value in the array. For instance, the code snippet below demonstrates the result of full-stack addition of 7.0 to a LIST_FLOAT, the full-stack product of a LIST_INT by 5, the full-stack exponentiation of a LIST_INT from 2, and finally, the full-stack exponentiation of a LIST_INT by 2.0.LET X = LIST(INTEGER, 3);LET Y = LIST(FLOAT, 3);LET z = LIST(INTEGER, 3);LET X[0] = 60;LET X[1] = 65;LET X[2] = 70;LET Y[0] = 3.2;LET Y[1] = 3.1;LET Y[2] = 2.8;LET Z[0] = 3;LET Z[1] = 4;LET Z[2] = 5;PRINT Y = Y + 0.70;PRINT X = X * 5;PRINT X = X ^ 2;PRINT 2 ^ Z;The output of these
PRINT commands are [3.90, 3.80, 3.50], [300, 325, 350], [3600, 4225, 4900], and [8, 16, 32], respectively.
Thirdly, Tim
lists allow pointwise operations. So, for instance, given either two LIST_INT's or two LIST_FLOAT's, Tim allows pointwise operations between the operators by adding a . after the operation. For instance, the code snippet below demonstrates the result of a pointwise addition of two LIST_INT's, the pointwise product of two LIST_FLOAT's, and the modulo operator between two LIST_FLOAT's.LET A = LIST(INTEGER, 3);LET B = LIST(INTEGER, 3);LET X = LIST(FLOAT, 3);LET Y = LIST(FLOAT, 3);LET A[0] = 60;LET A[1] = 65;LET A[2] = 70;LET B[0] = 6;LET B[1] = 9;LET B[2] = 12;LET X[0] = 6.2;LET X[1] = 9.2;LET X[2] = 12.2;LET Y[0] = 2.4;LET Y[1] = 2.25;LET Y[2] = 1.987;LET C = A +. B;LET D = X *. Y;LET E = X %. Y;The output of these
PRINT commands are [66, 74, 82], [14.88, 20.7, 24.2414], and [1.4, 0.2, 0.278], respectively.Implementing Robust Algorithms on Tim
This section provides the implementation of several notorious algorithms that can be implemented in Tim. Firstly, we present a code snippet for the insertion-sort algorithm.LET N = 5;LET A = LIST(INTEGER, N);LET A[0] = 12;LET A[1] = 11;LET A[2] = 13;LET A[3] = 5;LET A[4] = 6;FOR I = 1 TO NLET K = A[I];LET J = I - 1;WHILE (J >= 0) * (K < A[J]) DOLET A[J + 1] = A[J];LET J = J - 1;ENDWHILELET A[J + 1] = K;ENDFORPRINT A;Secondly, we present a code snippet for an approximation of Euler's constant, \(e\), which is defined as \(e^x = \sum\limits_{k=0}^\infty \frac{x^k}{k!}\). Thus, \(e = \sum\limits_{k=0}^\infty \frac{1}{k!}\). We define the n-pproximation of \(e\) as the sum of first \(n\) terms in the summand, \(e_n = \sum\limits_{k=0}^n \frac{1}{k!}\)
LET N = 3;LET S = 0.0;FOR K = 0 TO IF K = 0, THEN S = S + 1 ENDIF;IF K = 1, THEN S = S + 1 ENDIF;LET P = 1;IF K > 1, THEN
FOR F = 1 TO KLET P = P * F;ENDFORLET S = S + 1/P;ENDIFPRINT S;Thirdly, we present a code snippet that detects prime numbers.
PRINT X;LET N = 17;IF N = 0, THEN PRINT "NOT PRIME" ENDIF IF N = 1, THEN PRINT "NOT PRIME" ENDIF LET Prime = 1;IF N > 1, THEN FOR F = 2 TO N - 1IF TYPE(N/F) = TYPE(0), THEN PRINT "NOT PRIME";LET Prime = 0; ENDIF ENDFORIF Prime = 1, THEN PRINT "PRIME" ENDIFENDIFFinally, we present a code snippet that checks if a string is a palindrome.
LET X = "TACOCAT";LET Length = 0;LET Value = -1;WHILE TYPE(X[Length]) != NONE DOLET Length = Length + 1;ENDWHILELET Not = 1;LET Start = 0;WHILE (Start < Length) * (Not = 1) DOIF X[Start] != X[Length] THEN
PRINT "Not a Palindrome."LET Not = 0;ENDIFLET Length = Length - 1;LET Start = Start + 1;ENDWHILEIF Not = 1, THEN PRINT "Palindrome" ENDIFENDWHILE
To the top