home *** CD-ROM | disk | FTP | other *** search
-
-
- 1. WHAT IS BOZOL?
- 2. BOZOL COMMANDS AND FUNCTIONS - STARTER SET
- 3. BOZOL PROGRAMMING RULES
- 4. HOW TO ADD COMMANDS AND FUNCTIONS
- 5. CALLING BOZOL FROM YOUR OWN PROGRAMS
-
- 1. WHAT IS BOZOL?
-
- BozoL (The Bozo Language) is an extremely simple interpretive
- language written in PowerBASIC. It is designed to be easy to
- use, easy to modify, and to run as fast as possible.
-
- Some of the rules in BozoL may seem a bit wierd, but there is a
- reason for this. After writing a BASIC interpreter (EBASIC.ZIP)
- I discovered that the fundamental design of BASIC makes it
- extremely difficult to parse and interpret with any sort of
- reasonable speed. BozoL is purposely designed to run as fast
- as possible as an interpreted language.
-
- Why BozoL?
-
- Every now and then a situation may arise where you will want to
- incorporate a command language into your programs. BozoL can be
- easily modified to do things relevant to your program's needs.
- Suppose you have a database program and you want to allow your
- users to program their own custom procedures without having to
- go back to the original source code and add them in.
-
- BozoL is a language skeleton. All of the dirty work has been
- done already. BozoL already contains expression parsing, program
- flow control, basic logic, and other fundamental building blocks
- of a programming language (print, input, variables, etc).
-
- BozoL is simple. There are not a lot of rules, punctuation, or
- wierd symbols in the language. It is a real beginner's language.
-
- All you need to do now is add your own custom commands and key-
- words to the language. See section 4, "How to add commands and
- functions" for the exact details on how to do this.
-
- Prototypes and Applications
-
- Suppose you have a library of routines that pop up boxes, print
- menus, display pictures, etc. You can take these routines and
- make BozoL commands out of them. For instance, if you have a
- PowerBASIC subroutine that displays a message inside a red box
- on the center of the screen, you can make a BozoL command which
- calls this subroutine. So now in BozoL you can say
-
- REDBOX "press any key to continue!"
-
- and BozoL will call your subroutine. Using this technique, you
- can take an entire library, or many libraries, and make BozoL
- commands out of all of those subroutines.
-
- I'll give you a more advanced example. Suppose you have a Power-
- BASIC library that features pull-down menus, dialog boxes, list
- boxes, a text editor, and data entry screens. If you took every
- callable SUB and FUNCTION in this library and made BozoL commands
- out of them, then you could use the BozoL language to write
- really neat user-interface programs, prototypes, or even finished
- products. Instead of shipping an EXE, you can ship the BozoL
- interpreter along with an interpreted BozoL program that can
- be easily modified by your customers without ever having to
- give them the source code or customizing the program yourself.
-
- Software upgrades could be faxed to your customers or even
- dictated over the phone.
-
- Process Control
-
- You could use BozoL to control machinery. You could add commands
- like TURN EVERYTHING OFF or DISPLAY STATUS OF MIXER 1. By inventing
- commands and adding them to the language you could turn BozoL into
- a high level language that does almost anything, for any purpose.
- Users could enter direct statements or run programs that display
- menus and perform certain tasks, and easily add to or modify the
- system without a lot of complicated programming. Consider these
- possible additions to the language:
-
- DISPLAY SCHEMATIC
- BLOCK PHONES
- ELECTRIC FENCES OFF
- DISENGAGE SECURITY IN DINOSAUR EMBRYO LAB
-
- With the fundamental building blocks of the language already in
- place (like GOTO, GOSUB, IF, LOAD, RUN, SAVE, PRINT, INPUT, LOCATE,
- COLOR, LET, etc) you can easily build a custom language that works
- well, runs fast, can handle almost any programming task, and can
- call subroutines written in BASIC, C, Assembler, or BozoL. Since
- most of the nitty gritty is compiled in (like what do do when the
- command BLOCK PHONES is issued) it will almost always seem to
- run just as fast as a compiled program.
-
- 2. BOZOL COMMANDS AND FUNCTIONS - STARTER SET
-
- As I mentioned in part 1, all of the fundamental building blocks
- of the language, its structure, variable handling and flow control
- have already been built in. All you need to do is add new key
- words and the code that is executed when BozoL sees the key word.
-
- These are the key words that are built in to BozoL already:
-
-
- ASC ASCII BE CALC CASE CHR CLS
- COLOR CR EQUAL EQUALS EVAL FALSE GOSUB
- GOTO IF IN INKEY INPUT IS LCASE
- LEFT LEN LET LIST LOAD LOCATE LOWER
- LTRIM MID NOT PRINT PROMPT QUIT RETURN
- RIGHT RTRIM RUN SAME SAVE SET SUBSTR
- TAB TO TRUE UCASE UNTIL UPPER WHAT
- WHILE WITH
-
- (... and added since this writing...)
-
- END
-
- See the file BOZOL.REF for a complete description of each command
- and examples of how to use them in your programs.
-
- 3. BOZOL PROGRAMMING RULES
-
- BozoL is funny for a couple of reasons. First, the syntax is
- probably unlike any language you have ever seen. As I mentioned
- earlier, this is to make it easier for the interpreter to
- parse and execute its statements. Easier means faster.
-
- BozoL also has keywords which don't do anything. The reason for
- these keywords is to make the awkward syntax a bit easier to
- stomach. Remember these keywords when adding your own commands
- to BozoL. They can come in handy.
-
- Keywords that don't do anything:
-
- "TO", "IN", "WITH", "IS", "BE", "EQUAL", "OF", "THE"
-
- You will see me using these in program examples every once in a while.
- For instance, to assign a value to a variable you could say
-
- SET A TO 1
-
- Although the word "TO" is not really necessary. You could also
- say
-
- SET A 1
-
- but that looks silly and its meaning would not be clear to someone
- who does not know all about BozoL (like anyone does but me!).
-
- Which brings up another rule: BozoL statements are parsed with
- spaces, commas, or semicolons. It does not matter which you use
- and it does not matter how you mix them. For instance, these
- expressions are all the same:
-
- SET A TO 1
- SET A,1
- SET;A;1
- SET A TO 1
-
- Also, multiple statements can be on the same line. In fact, it
- is necessary to put multiple statements on the same line in some
- cases. Multiple statements are separated by colons, just like
- BASIC.
-
- SET A TO 1: PRINT A: PRINT "GoodBye!":END
-
- Now here's another bit of silliness: BozoL will also allow
- you to place multiple statements on a line without using colons
- to separate them, BUT if you do not use colons the statements will
- be executed in REVERSE ORDER.
-
- For example, if you said
-
- PRINT 1: PRINT 2: PRINT 3
-
- BozoL would display this on the screen:
-
- 1
- 2
- 3
-
- But if you said
-
- PRINT 1 PRINT 2 PRINT 3
-
- then BozoL would print this:
-
- 3
- 2
- 1
-
- This is the magic of "stack parsing", which is how BozoL processes
- statements and functions. For more info on stack parsing, read
- the comments in the source code.
-
- This is not mean't to be funny or wierd. It is very useful. For
- example, you could say
-
- WHILE NOT LEN INKEY: NEXT RECORD: PRINT NAME,ADDRESS,PHONE
-
- or you could also say it like this:
-
- PRINT NAME,ADDRESS,PHONE OF THE NEXT RECORD WHILE NOT LEN INKEY
-
- Do you see the difference between the two lines? There is none.
- In the first line we broke up the sentence with colons to indicate
- a specific order of the actions. In the second line we said
- everything we wanted to do and with the help of a couple of
- placeholder keywords (OF and THE) which do nothing, and without
- the colons it almost seems like english!
-
- So to review, we have "placeholder" commands which do nothing but
- make the syntax more readable, and we have a language syntax which
- goes forwards or backwards depending on whether or not you use
- colons to separate multiple statements. If you follow me this
- far then we'll go on. If not, go back a few pages.
-
- Bozol, as it is right now, leaves out some basic language functions
- which may be considered important. Particularly file I/O. There
- are no facilities to open, read, write, or append any sort of
- file except for LOAD and SAVE. Most of the major string handling
- and arithmetic is included, as well as basic user interface
- primatives: INPUT, PRINT, PROMPT, and INKEY.
-
- BozoL variable names can be any letter or word which does not
- have a numeric value and is not already defined as a keyword.
- A BozoL variable can be of any data type. BozoL does not
- distinguish between strings and numeric data. If a BozoL variable
- contains alphabetic characters it is treated as 0 in arithmetic
- functions or functions which require a numeric parameter.
- Variables which contain numeric data (like the number 100) can
- be treated as strings in string functions like LEFT, RIGHT and
- MID, etc.
-
- BozoL programs are limited to 256 defined variables and all
- variables are retained when a new program is RUN. A BozoL
- program can be no more than 1000 lines in length. There is
- no effective limit to how many statements can occur on a single
- line.
-
- A line of code in BozoL can contain multiple statements which
- are separated by colons, but it may also contain statements
- separated by carriage return-line feed pairs. Each line in
- the program can contain up to 32K of statements. The entire
- BozoL program cannot exceed 64K in size, unless, of course,
- you modify the source code and DIM HUGE the array which contains
- the program.
-
- Error checking is done by the PowerBASIC compiler except where
- necessary. If an error occurs, BozoL will display an error
- message and ask if you wish to continue the program or exit to
- DOS. In the BozoL program, only the subroutine PROGRUN terminates.
- If you called PROGRUN from another program your program will
- simply resume.
-
- Entering Statements
-
- By default, BozoL begins in command line mode, like GWBASIC. You
- can enter direct statements, LOAD, or RUN a program. When the
- program ends BozoL will return you to the command line unless the
- program is terminated with END or QUIT.
-
- If you preceed a direct statement with a line number from 1 to
- 1000, the statement will not be executed. Instead it will be
- entered into memory. You can then type LIST to see all of the
- lines currently in memory. Any blank lines will not be displayed.
-
- To try it out, run BozoL and type these three lines:
-
- 1 PRINT "This is the beginning!"
- 2 BE UNTIL LEN INKEY
- 3 PRINT "This is the end!"
-
- Then type LIST. BozoL will re-display the lines that you entered.
- Then type the command RUN. BozoL will print "This is the beginning!"
- and will wait for you to press any key. After you press any key
- BozoL will print "This is the end!" and the program will terminate,
- leaving you at the BozoL command prompt.
-
- Notice line 2, where we could have just said UNTIL LEN INKEY we
- added the dummy word BE in front of it just because it makes the
- purpose of the line a little more descriptive.
-
- Now if you typed SAVE "PROG1", BozoL would write these three
- lines to a file called "PROG1" in the current directory. At any
- time in the future you can type LOAD "PROG1" to reload the
- program into memory, and then LIST or RUN, or you can just type
- RUN "PROG1" to load and run the program. You may have already
- decided that it will be much less of a chore to write your
- programs in an external text editor. I thought about adding a
- fullscreen editor to BozoL, but the best editor I have (PBWRITE)
- is almost four times larger than all of BozoL by itself. If
- you want to add a text editor, do it yourself.
-
- You must remember that when you create a program using an editor
- you may not use line numbers. Line numbers can only be used to
- enter a program at the BozoL command line. Line numbers are
- not retained by BozoL when a program is saved to disk.
-
- Assigning variables
-
- To assign a value to a variable you can use the SET or LET
- statements. They both work the same way. You can use either
- depending on your favorite syntax.
-
- LET A BE EQUAL TO 1
- SET NAME TO "ERIK"
-
- Notice the use of the "dummy" keywords BE EQUAL TO and TO in these
- statements. They are not necessary but can be used to provide
- additional readablility in your source code.
-
- Using functions
-
- Functions (like CHR, LEN, or UCASE) may require variables as
- arguments. Since BozoL does not distinguish between numeric and
- character data types you can use any kind of variable as an
- argument to a function. Unlike BASIC or any other language,
- arguments to a function are not included in parenthesis.
-
- For example, to print ASCII code 1 in BASIC you would say
-
- PRINT CHR$(1)
-
- However in BozoL you would say
-
- PRINT CHR 1
-
- A statement like this in BASIC:
-
- PRINT LTRIM$(RTRIM$(UCASE$(A$)))
-
- Would look like this in BozoL:
-
- PRINT LTRIM RTRIM UCASE A
-
- Evaluating expressions
-
- Unlike languages which employ recursive descent parsing, BozoL
- does not naturally incorporate arithmetic into its syntax. To
- trigger an arithmetic evaluation you must use the CALC keyword.
- CALC has some synonyms which do the exact same thing but may
- be preferred for better language readability. The keywords
- CALC, EVAL, WHAT, and CASE all do the same thing.
-
- If you want to use arithmetic (+-/*^<> or =) to evaluate an
- expression you must tell BozoL to do so. For example, if you
- wanted to print 1+1, you must say
-
- PRINT CALC 1+1
-
- you could also say
-
- PRINT EVAL 1+1 or PRINT WHAT 1+1 or PRINT CASE 1+1
-
- in which case BozoL would print the number 2 on the screen. If
- you were to say
-
- PRINT 1+1
-
- then BozoL would print "1+1" on the screen. The reason for doing
- it this way greatly increases the speed of the interpreter. It
- also greatly reduces its complexity.
-
- Again, having four synonyms for CALC may seem unnecessary but they
- come in handy when writing different kinds of statements. For
- example you could use the dummy word IS to make a statment that
- goes like this
-
- PRINT WHAT 1+1 IS
-
- or you could make your source code more readable by using CASE
- in conjunction with the IF statement, like
-
- IF CASE A=B: PRINT "They Match"
-
- Program Logic
-
- BozoL features the statements IF, WHILE, and UNTIL to embody its
- logic. You can add others if you like. It's easy.
-
- When a WHILE or UNTIL statement is executed, the expression which
- follows it is immediately evaluated. If the expression is true,
- UNTIL will cause BozoL to immediately abort the current line and
- go on to the next one, or end the program if there are no more
- statements. WHILE is the exact opposite of UNTIL. For example,
-
- PRINT "Hi There!" UNTIL LEN INKEY
-
- This statement will print "Hi There!" over and over again on the
- screen until the function INKEY returns something with a length.
- That is, until a key is pressed.
-
- PRINT "Hi There!" WHILE NOT LEN INKEY
-
- will do the same thing. As long as the expression remains true,
- WHILE and UNTIL will continue to execute the entire line over
- and over again.
-
- IF is similar. When BozoL gets to the IF, the expression following
- IF will be evaluated. If the expression returns a non-zero value,
- the remainder of the line will be executed. If you are using
- colons to delimit the individual statements on the line, this
- means the remainder of the line following the IF statement. If
- you are not using colons to delimit the statements on the line
- this refers to the statements which preceed the IF statements.
-
- In other words, the statement
-
- IF EVAL A=B: PRINT "They Match"
-
- Will print "They Match" on the screen if A is equal to B. Also,
- the line
-
- PRINT "They Match" IF EVAL A=B
-
- will do the same thing.
-
- Program flow control
-
- All of the program flow control in native BozoL is contained within
- the simple GOTO and GOSUB...RETURN command sets. At any point in
- your program you may include a label which is on a line by itself
- and is not a BozoL keyword. Labels can be any word or words as long
- as they are unique. To jump to a label, just say GOTO ABC, where
- ABC would be the label name.
-
- GOSUB works the same way, except BozoL remembers the line number
- where you GOSUBed from. At any later point you may execute a
- RETURN statement and BozoL will resume program execution at the
- next line following the GOSUB, unlike BASIC which will resume
- execution at the next statement, which may be on the same line.
-
- You can GOSUB up to 32 times until you must return. If you try
- to GOSUB more than 32 times without ever returning BozoL will
- give you an overflow error. You can increase the size of the
- GOSUB stack by modifying the source code, although it will
- probably never be necessary.
-
- You can also GOTO or GOSUB to a line number, but this is not
- advisable. If you write BozoL programs in a text editor you
- must not include line numbers. If you have a GOTO 10 in your
- program and then insert a line before line 10, GOTO 10 will
- then go to the wrong line.
-
- Finally, you may GOTO or GOSUB to a line number which is
- contained in a variable. For example, you could say
-
- SET A TO 100
- GOTO A
-
-
- 4. HOW TO ADD COMMANDS AND FUNCTIONS
-
-
- BozoL is kind of useless unless you intend to add your own
- custom commands and functions. That is, after all, the whole
- point to having an interpreted language written in PowerBASIC.
-
- Adding commands and functions is easy. You must be aware of
- the difference between a command and a function. A command
- is a keyword which actually does something, like PRINT or
- INPUT or LAUNCH THE MISSILES. A function is a keyword which
- may have parameters, operate on those parameters, and then
- leave behind a return value to be acted on by another function
- or a command.
-
- For example, CHR is a function. CHR does not execute anything,
- rather, it looks at the parameter which follows it and pushes
- a new parameter onto the stack.
-
- CHR 1
-
- This will do nothing.
-
- PRINT CHR 1
-
- BozoL will look at the 1 and push it onto a special stack. Then
- it will look at CHR. CHR will read the 1 off of the stack and
- push a happy face back onto the stack. PRINT will then see the
- happy face on the stack and print it.
-
- Read that paragraph again and again if you didn't understand it.
- It can take a while to sink in if you're not familiar with the
- concepts.
-
- To add a custom keyword you first need to think up a name for
- the keyword, and then what it does. Gee, that's kind of like
- creating a new SUB or FUNCTION in PowerBASIC, isn't it? It
- is very similar.
-
- Lets start with an example. BozoL does not have a NEW command,
- which would erase the current program in memory and stop
- execution. Adding NEW to BozoL is easy.
-
- All of the commands in BozoL are broken up into a handful of
- include files which have a .CMD extension. These include
- LOGIC.CMD, which contains IF, WHILE, and UNTIL, FUNCTION.CMD
- which contains many rudamentary functions like ASC, CHR,
- UCASE, LEFT, RIGHT, and MID, and others.
-
- LOAD, RUN, and other related commands are in the include file
- LOADRUN.CMD. If you look at this file you can see where the
- guts of these commands are defined. Each commands starts out
- with a CASE statement (remember, we are in PowerBASIC now).
-
- These files are included in the middle of a big SELECT CASE
- loop which is in the subroutine EXEC in the file BOZOL.BAS.
- If you look at this file and sub you can see where all of the
- *.CMD files are included.
-
- NEW would belong with the other commands in LOADRUN.CMD, although,
- of course, you could put them anywhere. Pull LOADRUN.CMD up into
- the PowerBASIC editor and page down to the end of the file.
-
- Add a new item to this CASE structure. Add a few spaces to the
- end of the file and type in the line
-
- CASE "NEW"
-
- This officially defines a new command in the BozoL language. Now
- all you need to do is enter some code to carry out what you want
- the NEW command to do. We want to erase the program and stop
- execution of the program. The program is stored in a shared array
- called PROGRAM$(), so the next line would be this:
-
- REDIM PROGRAM$(1000)
-
- This would effectively erase the contents of the program array.
- Next you need to make sure the program stops. BozoL thinks
- that the program is running as long as the shared variable
- PROG% is true. Add the statement
-
- PROG%=0
-
- Now all you need to do is recompile BOZOL.BAS. Try it out!
- Enter a small program and type LIST. Then type NEW. Then
- type LIST. Voila! It's gone! You just added a new command
- to BozoL!
-
- Commands that use arguments
-
- By the time BozoL gets to a command, all possible arguments are
- on a special stack called the Argument Stack. This is actually
- a string array that can store up to 16 arguments at a time. Since
- mose functions and commands only require one or two arguments this
- is quite adequate.
-
- You can ask for these arguments one at a time by using the
- PowerBASIC function POPARG$. For example, the print command
- keeps printing whatever is returned by POPARG$ until it runs
- out of arguments. The shared variable ArgPtr% contains the
- number of arguments currently on the stack. You may find this
- variable useful if you want to create commands and functions that
- accept a variable number of arguments.
-
- Lets try adding a new command. Fund the place in BOZOL.BAS
- where all of the *.CMD files are included. Add a new include
- file called "CUSTOM.CMD"
-
- Next, create CUSTOM.CMD.
-
- The first line of CUSTOM.CMD should be CASE something, where
- something is the new command you want to add. Lets add a
- special purpose function which returns the entire contents of
- a file. this function does not really do anything by itself,
- but it will be a keyword you can use in other expressions.
-
- CASE "GETFILE"
- Buf% = FREEFILE
- OPEN POPARG$ FOR BINARY AS #Buf%
- GET #Buf%, LOF(Buf%), A$
- PUSHARG A$
- CLOSE #Buf%
-
- After you have added these lines, recompile BozoL and run it.
- Try out this new command by typing in this direct statement
-
- PRINT GETFILE "\AUTOEXEC.BAT"
-
- Your whole AUTOEXEC.BAT file should print out on the screen!
-
- Notice that we used POPARG and PUSHARG to manipulate the BozoL
- argument stack. We didn't want to print "GETFILE", we wanted
- GETFILE to literally return the entire contents of a file,
- so use used POPARG$ to find out what file name followed the
- GETFILE keyword, opened the file, read the whole file into a
- single variable, and then pushed the whole file onto the argument
- stack. Then PRINT looked at the argument stack to see what was
- there and finds the entire contents of your AUTOEXEC.BAT. PRINT
- then prints it on the screen.
-
-
- 5. CALLING BOZOL FROM YOUR OWN PROGRAMS
-
- In addition to being able to custom the language, you will also
- want to call the BozoL interpreter from your own programs. BozoL
- requires the DIM and SHARED statements which exist at the top of
- BOZOL.BAS to be already defined in your own program. Once you
- have done this all you need to do is call the subroutine PROGRUN.
- PROGRUN requires an array as a parameter, preferably PROGRAM$(),
- although you can pass it any other string array if you like. You
- must also specify whether or not you want BozoL to actually start
- running the program in PROGRAM$ or to display a command prompt
- and wait for someone to type RUN. This is done by placing a
- true or false value into the shared variable PROG%. If PROG% is
- true then the program will run. If it is false then PROGRUN
- will just display an OK prompt and wait for a command to be
- entered at the keyboard. If you simply want to invoke the
- interpeter, just call PROGRUN with prog% set to 0.
-
- If the program contained in PROGRAM$ ends without and explicit
- END or QUIT statement, the user will be returned to a command
- prompt. END or QUIT exits the PROGRUN sub completely, returning
- control to your program, or to DOS, depending on how you may
- have it set up
-