MBASIC programming language

MBASIC is an interpreted language for Alchemy OS. It is mostly compatible with Mobile BASIC.

Last update: 2013-06-03

Contents

1 Introduction

1.1 Installation

To install MBASIC interpreter go to the package manager and install mbasic package. Alternatively, you may execute the following command in the terminal:
pkg install mbasic

2 Using interpreter

2.1 Interactive mode

To start interpreter in interactive mode open terminal and type
mbasic
To exit interpreter type 'exit'. In MBASIC letter case is not meaningful so you can also type 'Exit' or 'EXIT'.

In interactive mode interpreter reads commands from the terminal and executes them immediately. One of the core MBASIC commands is PRINT, which prints its argument.

> Print "Hi"
Hi
> PRINT 2*3
6
Letter case is not meaningful, so you may write "PRINT", "Print" or "print".

Instead of executing commands immediately, you may start writing program. To add command to the program start it with numeric label. It is common to enumerate commands not by consecutive numbers but rather with numbers 10, 20, ... This way you can insert later command between these indices if you need.

> 10 INPUT "Your name:", NAME$
> 20 PRINT "Hello, " + NAME$ + "."
> 5 REM This is just a comment
To review you current program use LIST command. To execute program, use RUN.
> LIST
5 REM This is just a comment
10 INPUT "Your name:", NAME$
20 PRINT "Hello, " + NAME$ + "."
> RUN
Your name:
> John
Hello, John.
If you enter command with index that is already used, existing command will be replaced by new one. Finally, you may delete command from program entering just number.

To save your current script in a file use SAVE command.

> SAVE "myprog.bas"
Existing program can be loaded in interpreter using LOAD command.

2.2 Script execution

You can execute program from a file using MBASIC interpreter. To do that pass it as argument after -run.
> mbasic -run myprog.bas

If you want to turn your script into application you need also to add the following line as the first line of your script:

#!/bin/mbasic -run
Then you can copy your script under /bin and give it execution permissions.
> cp yourscript.bas /bin/yourscript
> chmod +x /bin/yourscript

3 Variables

Variables are used to store data in memory. MBASIC distinguishes three data types: integer numbers, floating point numbers and strings. Variable names consist of alphanumeric characters and possibly a suffix. Suffix is used to determine variable type.
Type Suffix Examples
floating point number no suffix P VAR1 ANGLE
integer number % I% VAR2% TIMES%
string $ D$ VAR3$ NAME$
Suffix is a part of name, so N and N% are different variables.

Variable can be accessed by its name. If variable does not exist, it will be created. Numeric variables initially contain 0, string variables are initialized to empty string. Assignment operator '=' is used to assign values to variables.

> 10 I% = 2
> 20 PRINT 5 + I% * 2
> RUN
9

4 Commands

Each command has the following syntax
command arg1, ..., argN
One line may contain more than one command in which case they must be separated by colon.
I% = 2 : I% = 5 - I% : PRINT I%
The following sections describe commands separated by categories. You may also use alphabetic index.

4.1 Standard commands

PRINT expr
Evaluates expression and prints in on output.

INPUT prompt, VAR
INPUT prompt, VAR%
INPUT prompt, VAR$
Prints prompt and asks user for input. Inputed value then stored in specified variable.

LIST
LIST line
LIST from, to
Lists program stored in memory. Without arguments lists the whole program, with one argument - only specified line, with two arguments - anything between given indices.

LOAD "filename"
Loads program from the specified file. Old program is removed and all variables are cleared.

SAVE "filename"
Saves current program in the specified file.

REM anything
Adds program comment. What follows REM is completely ignored by MBASIC.

NEW
Starts new program. Old program is removed and all variables are cleared.

RUN
Runs program stored in memory.

END
Terminates running program.

EXIT
Terminates running program. When used in interactive mode, exits from interpreter.

REQUIRE "module"
Loads named module. Modules contain additional commands and functions that can be used in MBASIC.

4.2 Mathematical mode

DEG
All subsequent calls to trigonometric functions (SIN, COS, TAN) will assume that argument is given in degrees. Inverse trigonometric functions (ASIN, ACOS, ATAN) will return result as degrees.
RAD
All subsequent calls to trigonometric functions (SIN, COS, TAN) will assume that argument is given in radians. Inverse trigonometric functions will return result as radians.

4.3 Flow control

GOTO line
Causes program execution to proceed to given line. Example:
> 10 PRINT 1
> 20 GOTO 40
> 30 PRINT 2
> 40 PRINT 3
> RUN
1
3

GOSUB line
RETURN
GOSUB/RETURN is used to write subroutines. GOSUB remembers current line and then proceeds to given line number. RETURN returns execution back to the remembered position.
> 10 GOSUB 100
> 20 PRINT "Between subroutines"
> 30 GOSUB 100
> 40 END
> 100 PRINT "Subroutine"
> 110 RETURN
> RUN
Subroutine
Between subroutines
Subroutine

IF condition THEN command
Executes specified command only if condition evaluates to non-zero value.

FOR var% = start TO end STEP inc
NEXT var%
All lines between FOR/NEXT are iterated using var% = start, var% = start+inc, var% = start+2*inc and so on until var% becomes larger than end. Step can also be negative. If STEP part is omitted, step is 1.

4.4 File I/O

Files in MBASIC are accessed through the channels. There are 10 channels, from #0 TO #9. Channel is always the first argument after a command. An example of putting three bytes in the file:
10 OPEN# 0, "test.txt", "OUTPUT"
20 PUT# 0, ASC("H")
30 PUT# 0, ASC("i")
40 PUT# 0, ASC("!")
50 CLOSE# 0

OPEN# channel, file$, mode$
Opens file on the given channel in the specified mode. Mode is one of "INPUT", "OUTPUT" or "APPEND".

CLOSE# channel
Closes channel.

PUT# channel, byte
Writes byte value to the channel. Channel must be in OUTPUT or APPEND mode.

GET# channel, VAR%
Reads byte from the channel as value from 0 to 255. If channel is at end, variable is set to -1. Channel must be in INPUT mode.

PRINT# channel, expr
Writes given value to the channel in format that can be later read by INPUT#. Channel must be in OUTPUT or APPEND mode.

INPUT# channel, VAR%
INPUT# channel, VAR
INPUT# channel, VAR$
Reads value from the channel. This command recognizes format used by PRINT#.

4.5 Graphics

Graphical commands allow to draw on the screen. To turn on graphical mode you should first execute a command
REQUIRE "ui"
After that new empty screen will appear.

CLS
Clear graphical screen. Fills entire screen with white color.

SETCOLOR red, green, blue
Sets current color to paint with. Arguments are three numbers from 0 to 255.

PLOT x, emphy
Changes color of the given point to the current one.

DRAWLINE x1, y1, x2, y2
Draws the line using current color.

DRAWRECT x, y, width, height
Draws the outline of the rectangle with given top-left corner and size.

FILLRECT x, y, width, height
Fills the rectangle with given top-left corner and size.

DRAWROUNDRECT x, y, width, height, arcwidth, archeight
Draws the outline of the rectangle with rounded corners.

FILLROUNDRECT x, y, width, height, arcwidth, archeight
Fills the rectangle with rounded corners.

DRAWARC x, y, width, height, startangle, arcangle
Draws the arc.

FILLARC x, y, width, height, startangle, arcangle
Fills the arc.

DRAWSTRING str$, x, y
Draws the specified string at given position.

BLIT x, y, width, height, tox, toy
Copies the specified rectangle to given position.

5 Expressions

5.1 Numbers and strings

MBASIC recognizes number literals as integers and numbers with dot as floating point decimals.

String is any sequence of characters between double quotes. MBASIC also recognizes the following escape sequences in strings.

Sequence  Meaning
\n  Newline
\t  Tabulation character
\\  Backslash
\"  Double quote
\xnn  ASCII character with hexadecimal code nn
\unnnn  Unicode character with hexadecimal code nnnn

5.2 Operators

Arithmetic operators.
Operator Description
a + b Addition
a - b Subtraction
 -a Unary minus
a * b Multiplication
a / b Division
a ^ b Power

Comparison operators.
The result of comparison is either 1 (true) or 0 (false).

Operator Description
a = b Equals to.
a <> b Not equals to.
a < b Less than.
a <= b Less than or equals to.
a > b Greater than.
a >= b Greater than or equals to.

Logical operators.
The result of logical operation is either 1 (true) or 0 (false).

Operator Description
a AND b True if both arguments are nonzero.
a OR b True if any of arguments is nonzero.
NOT a True if a is zero.

String concatenation.

Operator Description
a$ + b$ The result is a combination of strings a$ and b$.

Bitwise operators.
These operators work with integer numbers as 32-bit sequences. The result is a bitwise operation on corresponding pairs of bits.

Operator Description
a BITAND b Bitwise AND.
a BITOR b Bitwise inclusive OR.
a BITXOR b Bitwise exclusive OR.

6 Standard functions

6.1 Mathematical functions

ABS(number)
Returns an absolute value of the number.

MOD(a%, b%)
Returns remainder from division.

SIN(angle)
Returns sine of the angle.

COS(angle)
Returns cosine of the angle.

TAN(angle)
Returns tangent of the angle.

ASIN(num)
Returns arcsine of the argument.

ACOS(num)
Returns arccosine of the argument.

ATAN(num)
Returns arctangent of the argument.

EXP(num)
Returns Euler number e raised to the power of argument.

LOG(num)
Returns natural logarithm of the argument.

SQR(num)
Returns square root of the argument.

RND(dummy%)
Returns random integer number. Argument is not used and is for compatibility with MobileBASIC.

6.2 String functions

ASC(string$)
Returns code of the first character of the string.

CHR$(code)
Returns one-character string that represents character with given code.

LEN(string$)
Returns number of the characters in the string.

LEFT$(string$, num)
Returns substring that consists of given number of characters from the beginning of the string.

RIGHT$(string$, num)
Returns substring that consists of given number of characters from the end of the string.

MID$(string$, start, num)
Returns substring that consists of given number of characters from the given position of the string.

LEFT$(string$, num)
Returns substring that consists of given number of characters from the beginning of the string.

STR$(num)
Returns string representation of given number.

VAL(string$)
Converts string into a number. Raises error if string does not represent a number.

7 Writing extensions

Extensions for MBASIC are written in Ether. Extension can define new functions using addfunction and new commands using addcommand.

Consider example:

/* File: example.e */

use "mbasic"
use "io"

// command without arguments
def hello() {
  println("Hello!")
}

// command that increases variable by one
def inc(ivar: [Int]) {
  ivar[0] += 1
}

// function that returns sum of two numbers
def sum(a: Int, b: Int): Int = a+b

def Init_example(vm: BasicVM) {
  vm.addcommand("HELLO", "", hello)
  vm.addcommand("INC", "I", inc)
  vm.addfunction("SUM", "ii", 'i', sum)
}
Our extension is called "example". So it must be compiled in file example.so and must contain function Init_example which accepts BasicVM object. To be accessible from MBASIC it should be put under /lib/mbasic/.
ex example.e -o example.so -lmb
install example.so /lib/mbasic/

Now we can test it:

/home> mbasic
> REQUIRE "example"
> HELLO
Hello!
> I% = 2
> PRINT I%
2
> INC I%
> PRINT I%
3
> PRINT SUM(2, 3)
5

The first parameter for addcommand is a name that will be used in MBASIC. The next parameter specifies number and types of arguments.

Letter Ether type MBASIC value
a Any any expression
i Int numeric expression (integer)
f Double numeric expression (float)
s String string expression
I [Int] reference to integer variable
F [Double] reference to float variable
S [String] reference to string variable

For functions, third parameter is a return type of function. Use 'i' for Int, 'f' for Double and 's' for String. These are the only types MBASIC knows and can deal with.

Finally, the last parameter is a reference to Ether function that implements command. Make sure that its arguments and returned type match those specified in previous parameters, otherwise MBASIC might crash.

8 Ether API for MBASIC

Types

type BasicVM;
Basic virtual machine is a MBASIC interpreter.

Constants

const VM_IDLE = 0
Indicates that virtual machine is stopped and ready to receive commands.

const VM_RUN = 1
Indicates that virtual machine executes code passed to it.

const VM_EXIT = 2
Indicates that virtual machine reached EXIT command and stopped.

Functions

def BasicVM.new(usestd: Bool): BasicVM;
Creates new virtual machine instance. If usestd is true, standard commands and functions are also loaded.

def BasicVM.reset();
Resets virtual machine to initial state. Removes all lines of code, clears all variables and unloads all modules.

def BasicVM.run(label: Int = 0): Int;
Runs stored MBASIC program starting from given line number. When called without argument, starts from the beginning.

def BasicVM.parse(text: String): Bool;
Parses and evaluates MBASIC code. Lines starting with command are executed immediately. Lines starting with number are stored and can be later executed using BasicVM.run.

def BasicVM.get_state(): Int;
Returns current state of virtual machine.

def BasicVM.set_ivar(name: String, value: Int);
Sets new value to an integer variable. Variable name must end with %.

def BasicVM.set_fvar(name: String, value: Double);
Sets new value to a float variable.

def BasicVM.set_svar(name: String, value: String);
Sets new value to a string variable. Variable name must end with $.

def BasicVM.get_ivar(name: String): Int;
Returns current value of specified integer variable.

def BasicVM.get_fvar(name: String): Double;
Returns current value of specified float variable.

def BasicVM.get_svar(name: String): String;
Returns current value of specified string variable.

def BasicVM.addfunction(name: String, args: String, rettype: Int, impl: Function): Bool;
Defines new MBASIC function.

def BasicVM.addcommand(name: String, args: String, impl: Function): Bool;
Defines new MBASIC command.

9 Alphabetic index

ABS            LEN
ACOS           LIST
ASC            LOAD
ASIN           LOG    
ATAN           MID$
BLIT           MOD
CHR$           NEXT
CLOSE#         NEW
CLS            OPEN#
COS            PLOT
DEG            PRINT
DRAWARC        PRINT#
DRAWLINE       PUT#
DRAWRECT       RAD
DRAWROUNDRECT  REM
DRAWSTRING     REQUIRE
END            RETURN
EXIT           RIGHT
EXP            RND
FILLARC        RUN
FILLRECT       SAVE
FILLROUNDRECT  SETCOLOR
FOR            SIN
GET#           SQR
GOSUB          STEP
GOTO           STR$
IF             TAN
INPUT          THEN
INPUT#         TO
LEFT$          VAL