A... basic BASIC interpreter written in Go. This is my own flavour of BASIC, and can be experimented with by visiting https://calluml.xyz/?program=basic.
Whilst the 'proper' way to parse languages today is to use an Abstract Syntax Tree, this is more of a toy project primarily intended for fun. The way it works is simply to parse the program token by token and recursively evaluate them. That is to say, for the statement
10 PRINT 3+ABS(5*-7)
The program will be interpreted like so:
-> PRINT
-> EVALUATE NEXT STATEMENT: 3+ABS(5*-7)
--> 3 LITERAL
--> + OPERATOR
--> EVALUATE NEXT STATEMENT: ABS(5*-7)
---> ABS
---> EVALUATE NEXT STATEMENT: 5*-7
----> 5 LITERAL
----> * OPERATOR
----> EVALUATE NEXT STATEMENT: -7
-----> -7 LITERAL
----> 5*-7 = -35
---> ABS (-35) = 35
--> 3 + 35 = 38
-> PRINT 38 ===> Print 38 to screen
At the time of writing, this does mean that mathematical operators are evaluated right-to-left in a coalescing manner (although brackets are respected), but a future feature could be group mathematical operators together and then evaluate them according to BODMAS rules.
CalBASIC has 4 types:
NUMBER: Underlying type is afloat64, but integers are automatically dealt with.STRING: It's a string. Based on the Gostringtype.ARRAY: Arrays in CalBASIC are not strictly-typed: they containVARIANTtypes (not accessible to the user) which mean that an array can contain mixed types.NULL: Null.
Variable names can be of any case and any length that is not a reserved keyword. Variables are declared with the LET keyword:
10 LET a = 3
and can be set by:
20 a = 4
Currently, once a variable has been initialised its type cannot be changed, but because of the new VARIANT type for arrays, I may make everything VARIANT and completely remove strong typing.
If/else statements are formed of the following syntax:
10 IF <CONDITION> THEN
20 <ACTIONS>
30 ELSE
40 <ACTIONS>
50 ENDNested if statments are supported. GOTO statements are only supported as the only action in an if statement, so:
10 IF A == 3 THEN GOTO 30 END
is valid, but including a GOTO inside a block is not.
For statements are formed of the following syntax:
10 FOR i = 1 TO 10
20 <ACTIONS>
30 NEXTThe step can be set by adding STEP <NUMBER> after the TO keyword.
GOTO statements are not supported inside a for loop.
Nested FOR loops are supported.
Arrays are declared with the DIM keyword:
10 DIM a(10)
The DIM function takes a list of dimensions, so multi-dimensional arrays are supported:
20 DIM a(10, 10)
Arrays are 0-indexed, and accessed with square brackets:
30 a[0][0] = 3
CalBASIC provides a small library of standard functions:
ABS(x): Returns the absolute value ofxLOG(x): Returns the natural logarithm ofxSQR(x): Returns the square root ofxSIN(x): Returns the sine ofxCOS(x): Returns the cosine ofxTAN(x): Returns the tangent ofxVAL(x): Returns the numerical value ofxPRINT(x): Printsxto the screenLEN(x):- If
xis a string, returns the length ofx - If
xis an array, returns the length of the first dimension ofx
- If
CalBASIC supports the following operators:
+: Addition-: Subtraction*: Multiplication/: Division^: Exponentiation%: Modulo
CalBASIC also supports the following comparison operators:
==: Equality<>: Inequality>: Greater than<: Less than>=: Greater than or equal to<=: Less than or equal toAND: Bitwise ANDOR: Bitwise ORXOR: Bitwise XOR
Booleans are represented by the number type -- 0 is false, 1 is true.
- Basic arithmetic
- Variables
- IF statements
- FOR loops
- Standard functions
- LEN function
- User Input
- User keyboard monitoring
- Arrays
- LEN function
- User-defined Functions
- CALFAX Terminal Control
- CALFAX Terminal Graphics
- String indexing
- String concatenation
- Comments
User input may be a difficult one to achieve -- it seems that WASM-compiled Go blocks until the run function has returned. I am going to experiment with some callbacks.
