For fun I thought I would try to compile the BEC (BASIC Emulation Compiler by William Yu) on my Ubuntu 64 laptop. I was able to get it to compile after renaming all operator variable names to _operator. I think I'm close and willing to look a little closer if there might be interest in this.
Update: The hello program that compiled with the Ubuntu 64 version when renamed to HELLO64.EXE and run under dosemu worked fine. So what this Linux based compiler is able to do is create DOS executables from BASIC source. (using precompiled DOS .LIB files) Based on the size of the examples I compiled under Ubuntu 64, we are looking at 135 KB of runtime overhead.
jrs@laptop:~/rapidq/bec-020s$ ./bec hello.bas hello
BASIC Emulation Compiler v0.21 (c)1998-99 William Yu
Compiling: hello.bas to hello
Compiling using standard ANSI.LIB
Successful compile!
1 statements, 2 lines Compile time: 0.000000
Variables: 0 strings, 0 integers
23 bytes code, 0 bytes data
jrs@laptop:~/rapidq/bec-020s$ chmod 755 hello
jrs@laptop:~/rapidq/bec-020s$ ./hello
winevdm: Cannot start DOS application Z:\home\jrs\rapidq\bec-020s\hello.
because the DOS memory range is unavailable.
You should install DOSBox.
jrs@laptop:~/rapidq/bec-020s$ ./bec EXAMPLE.BAS example
BASIC Emulation Compiler v0.21 (c)1998-99 William Yu
Compiling: EXAMPLE.BAS to example
Compiling using standard ANSI.LIB
Successful compile!
46 statements, 81 lines Compile time: 0.000000
Variables: 4 strings, 3 integers
1503 bytes code, 0 bytes data
jrs@laptop:~/rapidq/bec-020s$
BASEC v0.21 Command Summary
---------------------------
The BASIC Emulation Compiler is programmed by William Yu (c)1998-99
Please read and understand the GPL (GNU Public License) that applies
to this distribution (bec-020b) and source codes (bec-v020s).
E-mail: voxel@edmc.net
Http: http://www.basicguru.com/abc/basec.html
About Parser
------------
BEC.EXE was compiled and developed under DJGPP.
This parser only completes a single pass, all variables not declared
are declared "in place." This approach may cause problems if you're
in a loop, but usually only with strings...
You can use VAR.LST (the undeclared variable list that's generated)
and append this to your source code for better stability.
ANSI.LIB, etc. were compiled using DJGPP v2.8.1. The source code
compiles under other compilers, but does not always produce the correct
results. ie. using 16-bit C compilers
Special Thanks
--------------
Allegro library v3.0 by Shawn Hargreaves
Amp MPEG audio decoder by Tomislav Uzelac
JPEG Library courtesy of Tom Lane, Philip Gladstone, Luis Ortiz, Jim
Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi,
Ge' Weijers, and other members of the Independent JPEG Group.
Valid Data Types
----------------
BYTE ? 1 0 to 255
WORD ?? 2 0 to 65,535
INTEGER % 2 -32,768 to 32,767
DWORD ??? 4 0 to 4,294,967,295
LONG & 4 -2,147,483,648 to 2,147,483,647
SINGLE ! 4 ñ8.43x10^-37 to ñ3.37x10^38
DOUBLE # 8 ñ4.19x10^-307 to ñ1.67x10^308
STRING $ 32,767
STRING*n 65,535
Valid Arrays
------------
At the moment, the data type MUST be specified
DIM Number(-100 to 100) AS INTEGER
DIM Astring(1000) AS STRING
DIM A$(1000) ' doesn't work, it needs "AS STRING"
Valid Labels
------------
Line numbers with decimal points are valid
Example: 100.5 PRINT "Hello world!"
But, we usually use the colon to define a label
Example: Label1: PRINT "This is a valid label!"
Label2:
Separating Lines
----------------
Lines can be separated by using a colon
Example: ?"Hi!":?"Hi again!":?"Hi yet again!"
To continue a line, add the underscore ('_') character at the end
Example: PRINT "Hi, my name is " + _
"Cool Guy!"
Error Checking
--------------
I plan on wiping error messages completely with the '-whocares' switch.
Some error correction is done without the user knowing.
For example, Error: Overflow will never occur, but the result will,
obviously, not be what you want if that is the case.
The error messages you receive may not always be understandable...
ie. ?:INPUT$(1) gives an "improper placement of quotation mark" error.
PRINT 123456% would normally receive an illegal number in QB
DIM A$(1000) AS STRING would also receive an error
PRINT 100/0 should return a divide error, but doesn't
SWAP A!, A% should return type mismatch, but doesn't
BASEC Library (extension of ANSI library)
-----------------------------------------
LOG10, GET$(1)
ANSI Library
------------
$LIB <Libraries>
- N/A
- You can explicitly tell the compiler to use certain libraries.
ANSI.LIB, DOS.LIB, GRAPHICS.LIB, MM.LIB, UNIX.LIB
$STRING <integer>
- N/A
- Defines the default length of string used
- The default is 255, the maximum is 32767
- Do not use 32K, instead write 32767 or 1024 for 1K strings
- No expressions like 32 * 1024, just an integer value is accepted
ABS(n)
- Function returns the absolute value of integer expression n
- see also SQR
ASC(n)
- Function returns the ASCII value of the character
- see also CHR$
CHR$(n)
- Function returns the character of ASCII value n
- see also ASC
CINT(numeric-expression)
- Conversion function that returns the rounded integer expression
CDBL(numeric-expression)
- Converts expression to a double precision number
CLNG(numeric-expression)
- Converts expression to a long number
CSNG(numeric-expression)
- Converts expression to a single precision number
CLOSE [filenum [, filenum]]
- If arguments are omitted, then all open files are closed
- see also OPEN
COS(n)
- Function that returns the cosine of n (in radians)
- see also SIN, TAN
DATA
- Used to store numeric and string constands used by the READ statement.
- see also READ, RESTORE
DIM <variable> AS <data type> [*][Length]
- any legal variable name (max 80 characters)
- Underscores are legal (ie. My_Name)
- if string, you have an option of defining its length size
DO...LOOP [UNTIL <expression>]
- Control block that loops until expression returns true
- UNTIL <expression> is optional
EOF(filenum)
- Test file for End-of-file
- Returns a non-zero value if the file is at the end.
END IF
- Must be used to end a multiple line IF ... THEN ... ELSE block
- see also IF
ENVIRON$(environ-string)
- Function returns the value of the environment variable
- ie. ENViRON$("PATH") returns the entire PATH
- Returns a string
EXP(n)
- Exponential Function, returning the value of e raised to the power n
- see also LOG, LOG10
FIX(numeric-expression)
- Returns the whole number (truncating any fractions).
FOR i=start TO end [STEP n]...NEXT
- Control flow block that repeats a number of statements
- ie. FOR i = start to end [STEP n]
- see also STEP
FREEFILE
- Returns the next free file pointer that can be used.
- The range is between 1-100
- see also OPEN
GET filenum, [filepos], variable
- Reads from file to a buffer or variable
- File must be open of course
- filepos = 1 (the beginning of the file)
- see also OPEN
GET$(n)
- Function is similar to LINE INPUT or INPUT$ in both respects
- It reads whole lines and doesn't end until n characters are received
- In v0.20 GET$ ends on ENTER or EOF
- see also DOS_Library INPUT$
GOSUB <label>
- Branches to <label>
- see also RETURN
GOTO <label>
- Branches forward or backwards depending on <labal>
- see also LABELS
IF...THEN...ELSEIF...ELSE
- Control flow block that evaluates the boolean expression and returns
either true or false. ie. IF 10 < 20 THEN ?"True"
- see also END IF
INSTR([Start,] SearchString, FindString)
- Start searching at [Start] position of Search String
- SearchString is the string to be searched
- FindString is the string to be looked for
- Returns 0 if match not found
INT(numeric-expression)
- Returns the integer value of the numeric expression
KILL filename
- Deletes file
LCASE$(stringexpression)
- Function returns a string that has been lowercased
- see also UCASE$
LEFT$(stringexpression, n)
- Function that returns a string containing the leftmost n characters
of the string expression.
- see also RIGHT$, MID$
LEN(stringexpression)
- Function returns the length of the string
LOC(filenum)
- Returns the current file position
- see also LOF
LOF(filenum)
- Returns the length of file, in bytes.
- see also EOF
LOG(n)
- Returns the natural logarithm of n to the base e
- n must be > 0
- see also LOG10, EXP
LOG10(n)
- Returns the common logarithm of n to the base 10
- n must be > 0
- see also LOG, EXP
LTRIM$(stringexpression)
- Function that returns a string with leading spaces removed
- see also RTRIM$
MID$(stringexpression, start, length)
- Function that returns a portion of the string expression
- see also LEFT$, RIGHT$
OPEN "access", filenum, "filename"
- Access can be any string (it doesn't mean anything to the compiler).
For the moment, all open files are treated as read & write, but
unlike QB/PB, either binary or text functions can be used to manipulate
the file.
- Filenum is a valid file pointer number (1-100)
- Filename cannot be represented as a long filename, (ie. use the short
form instead). Under UNIX, long filenames are valid.
PRINT <expression>[,|;][<expression>][...]
- expression can either be integer or string
- use semi-colon to add more expressions after
- the comma has the same functionality as the semi-colon
PUT filenum, [filepos], variable
- Write buffer (variable) to file
- If the filepos argument is left blank, the file will read from the
current file position.
- filepos = 1 (the beginning of the file)
- see also GET
READ variable1[, variable2[, ...]]
- Reads values from DATA statement and assigns the values to the variables.
- see also DATA, RESTORE
REM
- Comment block, or use '
RESTORE
- Allows DATA statements to be reread from the beginning
- see also DATA, READ
RETURN
- Returns to the next instruction after the last GOSUB call
- see also GOSUB
RIGHT$(stringexpression, n)
- Function that returns a string containing the rightmost n characters
of the string expression.
- see also LEFT$
RTRIM$(stringexpression)
- Function that returns a string with trailing spaces removed
- see also LTRIM$
SEEK filenum, filepos
- Sets position of the file for next read/write
- The beginning of the file is position 1.
- see also OPEN, LOF, EOF.
SIN(n)
- Function that returns the sine of n (in radians)
- see also SIN, TAN
SHELL command$
- Execute command$
- Returns to main program once execution terminates
SLEEP [seconds]
- Seconds can be a fraction (ie. 1/10, or .1)
- Under DOS, SLEEP can be bypassed with a single key press.
SPACE$(n)
- Function returns a string with n number of spaces
- see also TAB
SQR(n)
- Function that returns the square root of n
- A negative expression is undefined, use ABS to safeguard from this
- see also ABS
STR$(numeric-expression)
- Converts numeric-expression to string
- see also VAL
STRING$(m, n)
STRING$(m, stringexpression)
- m, an integer expression, returning the length of string
n, an integer expression (0..255) which is an ASCII value to fill string
A string expression can be used instead, the first character is used to
fill the string.
SWAP variable1, variable2
- Exchange the value of the variables with one another
- The variables must be of the same type (ie. Numeric or String).
- Unlike QB, you can swap between different numerical types, for example
SWAP a!, a% is valid, although the results may be obscure.
TAB(n)
- Exact duplicate of SPACE$ (for now...)
- This is actually a device I/O function
- see also SPACE$
TAN(n)
- Function that returns the tangent of n (in radians)
- see also SIN, TAN
UCASE$(stringexpression)
- Function returns a string that has been uppercased
- see also LCASE$
VAL(stringexpression)
- Function returns the numeric value of the string of digits
WHILE <booleanexpression>...WEND
- Control flow block repeating a number of statements until expression
returns false
- see also WEND
DOS Library
-----------
CLS
- Clears the screen and homes cursor
COLOR Fore[, Back]
- Fore = 0..31, Back = 0..7
INKEY$
- Returns the string contents of the keyboard buffer
- Usually a one or two-byte string
- Extended keys are preceeded by CHR$(0) + KeyCode
- see also INPUT$
INPUT$(n)
- Wait for n key presses, and returns string of n characters
- see also GET$, INKEY$
LOCATE [Y][,[X][,[Cursor]]]
- Positions cursor, Y = Row, X = Column
- Cursor 0 = Hide, 1 = Normal, 2 = Block
GRAPHICS Library
----------------
Screen functions: PRINT, LOCATE, COLOR, and CLS all work in graphics mode.
CIRCLE (x,y),radius,color
- Draws a circle, all arguments must be specified
LINE (x1,y1)-(x2,y2),color[,b|bf]
- Draws a line, box (option B), or boxfill (option BF)
- Color is mandatory, unlike PB or QB
PAINT (x,y),color[,boundary_color]
- Fills a portion of the screen with "color"
- In QB/PB, the second color is optional, in BASEC, it's not used at all.
- You can specify the boundary color if you like, but it's only for
compatibility reasons that it takes it without giving an error message.
- The PAINT statement in BASEC will look for boundaries itself.
POINT (x,y)
- Function that returns the color of point-(x,y)
PSET (x,y),color
- Plots s single pixel to the screen at [x,y]
SCREEN Mode
- Mode (0, 7, 12 ,13)
- These modes are 256 colors, so SCREEN 7 is the same as SCREEN 13.
- Mode (11, 14)
- These modes are 24-bit, so you can view JPG files...
- Screen 11 is 640x480
- Screen 14 is 320x200
SHOWJPG(filename$, x, y, scale)
- Scale has factor (1,2,4, or 8)
- 1 = no scale, 2 = half size, etc...
SOUND Library
-------------
MP3.PLAY(filename$, loop)
- if loop is a non-zero value, the MP3 will repeat itself.
MP3.REPLAY
- Only rewinds MP3 file, does not play it.
MP3.RUN or MP3.POLL
- Execute these as often as possible as these are the main routines that
read the MP3 file and plays the music.
MP3.RUN is a function, and is always >= 0 if not done playing
MP3.POLL is a void function, that doesn't return a value, it's best
used if you want to repeat the music throughout your program.
MP3.FREE
- Make sure you free the MP3 from memory before you load a new one!