Werner's home on the Web

Musl - An interpreter for a BASIC language

ยท 507 words ยท 3 minutes to read

Also known as my Marginally Useful Scripting Language (I still have to pick the name).

Musl started out as a joke: I stumbled across the atariarchives.org website one evening and browsed through their books on programming games in BASIC. And by BASIC, I really mean old-school style BASIC, not this fancy new style structured language.

You know, like this:

10 PRINT "HELLO WORLD"

BASIC Games

Anyways, through my twisted sense of humour, I set out to write my own unstructured language. The original intention was to have a language that had only IF and GOTO statements. The joke was going to be to write some awesome application and watch the horror on my friends’ faces when they see the source code.

Out of principle, I decided that it should be an embeddable scripting language; that is to say, you can embed the interpreter into another application and have the other application execute custom scripts.

Here is a sample of what Musl code looks like:

LET a = 1
loop1:
x[a] = a * a
a = a + 1
IF a < 10 THEN GOTO loop1

If you look through the source code, you’ll find musl.c and musl.h that contains the core of the interpreter. The file main.c contains a simple driver program that shows you how to run the interpreter from another application, how to add new functions to the interpreter and how to access variables within the interpreter.

Over time it feature-crept a bit, and now includes these “features”:

  • Dictionaries (or hashes or whatever you want to call them)
  • FOR loops
  • GOSUB and RETURN
  • Regular expression support. It uses the regcomp() and regexec() functions that are part of POSIX, but if you want to compile it under Windows, Henry Spencer’s regex library compiles quite easily (with MinGW).
  • You can declare labels instead of using line numbers. Line numbers are supported, but not required.

Although the syntax may seem BASIC-like, Musl does not strive to be compatible with any known BASIC. The following is an example program:

# This is a test program for "IF x THEN FOR..." type
# situations, which actually took some complexity to get right
x = 0

@start: PRINT(X): IF X THEN PRINT("STARTING...")
10 IF X THEN FOR I = 1 TO 10 DO
20 IF I = 4 THEN GOTO lbl
30 PRINT("X is ", X, "; I is ", I)
40 IF I = 7 THEN NEXT
50 IF I > 2 THEN GOSUB 100
@lbl: NEXT

@foo: IF x = 1 THEN END
x = x+1
GOTO start

#### END ####

100 PRINT("in sub")
RETURN

Source Code ๐Ÿ”—

The latest version of Musl is available on github at https://github.com/wernsey/musl.

Compiling ๐Ÿ”—

On Linux you can compile it by just typing

make

at the command prompt.

I use MinGW to compile these things under Windows.

If you don’t have the regular expression library, you can comment out the following lines in Makefile.mingw:

# CFLAGS += -DWITH_REGEX -I/c/libs/regex
# LFLAGS += -L/c/libs/regex -lregex

To compile, just type

make -f Makefile.mingw

in the MinGW shell.