BASIC English, An Attempt at a Programming Language Interpreter

Version 0.79
Matt Roberts
Email

BASIC English has a rather lofty goal, coupled with a highly inept implementation. It's supposed to be useful to those who have the type of organized mind that would allow them to write computer programs, but who don't have the time to learn a programming language. To that end, I'm trying to write something that allows one to communicate with the computer in English. It's inspired by the BASIC programming language and is reminiscent of the remedial college English courses, hence the name.

That said, probably its main claim to fame at the moment is that it's helping me learn the C programming language, and it doesn't do much just yet. Hopefully, that'll change as time goes on. The source code, heavily commented because I'm a novice and need all that extra information, is included for your amusement.

The reason I'm trying to learn C is purely for the fun of it. So, you're welcome to email me with comments, criticisms, gifts of money or cookies, etc., and I'll read those emails. I may not respond, though, and I may or may not take your advice. If I do take your advice, there's a good chance it won't happen for a long while. In other words, if it goes on the list, it'll go on the bottom of the list, and it's a long list. Just so you know.

You may have noticed the interpreter is called yai. That's because it was originally called Yet Another Interpreter, since it's well, yet another programming language interpreter. In case you were wondering.

You may want to consider that the interpreter wasn't written with network safeguards in mind, so it's probably full of security holes. Maybe I'll tackle that another day, but for now you should simply be aware that it probably shouldn't be used on any network with more than one actual user unless you're willing to risk having that network compromised.

This is probably important: The interpreter wasn't designed with a lot of handholding in mind. Error messages are few and far between. What that means is that very often it'll either do or try to do exactly what you told it to do, even though it wasn't designed to do it. If you want to experiment and try to discover "undocumented features" that's fine. But you should know that if it isn't in the documentation, it hasn't been tested, and if it is documented, it's only been tested to the extent shown in the manual. If it isn't in the file you're reading right now, I can't guarantee you won't break something you can't afford to break. So any playing around you do is your own responsibility.

Programmers' Notes

You may have noticed that I use global variables, complicating my life in many ways. The answer is: Because I like 'em, sue me.

You may also have noticed that I often use routines I wrote myself instead of the built-in routines available in C. For instance, in at least one spot I wrote a routine that's longer than it would have been if I'd used strstr(). The answer is: Because it's fun. You'll recall that I've already said I'm learning C purely for the fun of it, and part of the fun is writing my own routines instead of using C's high-level functions. So you'll see more of that sort of thing rather than less as time goes on, and I don't intend to stop "reinventing the wheel."

I've organized the variables, functions, and commands alphabetically. Most people organize them by type. The answer is: It really doesn't matter what system you use for this sort of thing as long as it's consistent. Organizing alphabetically helps me find what I'm looking for faster than if I organized by type. What can I say, I'm weird.

I tend to avoid pointers when I can. I'd rather use "char somestring[0]" than "char *somestring" even though they mean the same thing for all practical purposes. The answer is: I'm comfortable with arrays, and I'm not with pointers. I don't know why, that's just the way it is.

I originally wrote the assign command to strip the quotes off string literals because it made my life easier. This may have caused difficulties with the greater than routines, or there may have been other troubles unrelated to the assign command. Regardless of which was the case, I was faced with the choice of rewriting the assign command and possibly every other routine that depended on it, with no guarantee that would fix the problem, or trying something different with the greater than routines. What I decided was to compare the ASCII value of each character of variable[j+1][0] with the same of each character of variaval. If they're not equal, I break out of the for loop and make decisions based on whether the character in variable[j+1][0] is greater then or less than the character in variaval. If they're both equal up to the point that I come to the end of one or the other of the strings, the longer one is "greater". For instance, "bambi0" would be greater than "bambi". It looks like C treats the lower number as greater than the higher, so "Bambi" is greater than "Theory". That doesn't make sense to me, so I've gone the opposite direction, where "Theory" is greater than "Bambi". The source code in the neithero function is heavily commented in case you want more information on my skewed perception of the known universe. :)

About Money and Other Fun Stuff

BASIC English and any files related to it are free. However, all contributions are cheerfully accepted. :)

The Warranty

There isn't any. For free you get no promises. That said, I don't want to embarrass myself by writing something that doesn't work or that causes damage of any sort. So you should be fine.

This is probably important: The interpreter wasn't designed with a lot of handholding in mind. Error messages are few and far between. What that means is that very often it'll either do or try to do exactly what you told it to do, even though it wasn't designed to do it. If you want to experiment and try to discover "undocumented features" that's fine. But you should know that if it isn't in the documentation, it hasn't been tested, and if it is documented, it's only been tested to the extent shown in the manual. If it isn't in the file you're reading right now, I can't guarantee you won't break something you can't afford to break. So any playing around you do is your own responsibility.

Of course, if you find bugs, and I can just about guarantee you will, you should let me know about them using the email address at the top of this document. If possible, you should include enough of the code that failed that I can reproduce the error on my system. That should make it easier to find the problem and correct it.

The Systems

This program was written and tested on the following systems:

A Dell Latitude D620, with a dual-core Celeron Processor running at 1.3GHz per core, 4 gigabytes of RAM (the system only sees 3), and a 100 Gb hard drive. Operating system is Linux Mint 12 (Lisa), and the programming language is GCC.

Using the Program

To use the program, enter the Terminal and navigate to whatever directory you've stored the program in. You'll have to compile it. I use gcc yai.c -o yai, and I'm going to assume you've done the same thing, but you can call it whatever you want. Then type ./yai filename, where filename is anything you want. If it can't open the file, it'll complain and exit. A sample file, test.txt, has been included for you to sneer at, or even modify for your own purposes if you like.

I'm trying to avoid using functions that are unique to gcc, so hopefully it'll compile on other systems with other compilers without too much fuss. No promises, though.

Commands, Keywords, Etc.

Please note: Although the commands and whatnot are listed in upper case, everything has to be in lower case for the interpreter to recognize it.

' Used as a comment. It must be on its own line. More information in the section on rem.

' This is a comment will be ignored by the interpreter.

A Used with the choose command to generate a random number.

ACTION Used with the load command in the execution of a menu, telling the interpreter what to do when a specific key is pressed.

ADD Allows you to add two values, either of which can be a constant or a variable. Syntax is

add numericvalue to numericvalue

Here's a test script which illustrates how it's designed to work:

rem Adding a constant to a variable
rem *
assign 3 to a
add 2 to a
print sum
rem *
rem Adding two constants
rem *
add 2 to 13
print sum
rem *
rem Adding two variables
rem *
assign 7 to gedit
add gedit to a
print sum
rem *
rem Adding a variable to a constant
rem *
assign 9 to vlc
add vlc to 2
print sum

The answers were 5, 15, 10, and 11, so I think I've got it approximately right anyhow.

I wish I could guarantee that all the bugs have been squashed, but I'm not nearly that confident. Hopeful, though.

AM Used with the at statement when specifying a time between midnight and 1AM. Starting at 1, you can leave off the AM if you want because AM will be assumed.

AND Used in an if statement to test two conditions. If both are true, the conditional statement is carried out:

if truecondition1 and truecondition2 dosomething

Example:

if a equals 5 and gedit equals 12 add 2 to a

Also used in count loops.

Attempting to use and as a variable name will probably work sometimes, but it very probably won't work some other times. So I recommend against it.

ASSIGN Allows you to assign a value to a numeric variable, although you can't do much with it right now. Syntax is

assign value to variablename

So if you wanted to give the variable "a" the value of 3, you'd type

assign 3 to a

You can also assign the value of a variable to another variable. If you've previously assigned 3 to a, and then type

assign a to q

q will now have the value 3.

If a is uninitialized (never assigned a value), it will remain uninitialized and q will have the value 0.

Currently, all you can do is print it and perform some math on it. (You can then print out the sum, difference, product, or quotient.

If I remember correctly, your variable's name can be up to 19 characters long, and the variable type is an integer.

You can, now that I've remembered to code it (oops), assign the sum to a variable. Here's a script file showing this:

assign 3 to a
assign a to q
print a
print q
add a to q
print sum
assign sum to a
print a

Of course, most of what's above isn't necessary to assign the sum. It was there from a previous test, and it was as convenient a way as any to get the values into the variables for the addition. The main thing is that once there's a value in sum, you can assign it to a variable. If there has been no addition, sum will be zero and you can assign that to a variable if you like.

Please note: The variable sum is reserved. All that really means is that trying to use the assign command to place a value into sum won't work. The interpreter will allow you to assign the value without complaint, but when you try to access that value, it'll be replaced by either the sum of the last addition or by zero if there have been no additions yet. So you can assign a value, but you can't do anything with it afterward.

You can also assign the difference of a subtraction to a variable, thus:

assign difference to variablename

You can assign the product of a multiplication with

assign product to variablename

And you can assign the quotient of a division with

assign quotient to variablename

You can assign the random number gotten with the choose command:

assign choice to variablename

You can assign the value returned by the find command:

assign string to variablename

As of 0.39.01, you can assign values to string variables print those values, and perform other operations based on equality in if statments. Neither the and nor the or operators are supported with strings as yet.

In order to be recognized as a string variable, the value has to have a $ at the end, like a$, test$, etc. Think of the $ as a stylized st, and pronounce a$ as a-string, because a-dollar sounds stupid and isn't what it means anyway.

Syntax for assigning a constant to a string variable is

assign "constantstringvalue" to variablename$

Constants must be in quotes.

Syntax for assigning the value of one string variable to another is

assign firstvariable$ to secondvariable$

AT You might call this a conditional statement, if you're willing to stretch the term. It allows you to play a media file at a specific time. I wouldn't be surprised if it could run other programs on other files, but it's only been tested on an mp4 file using Firefox, and I'm pretty sure it'll run as advertised with media files. But with the limited testing it's gotten, I'm not making any promises. Syntax is

at xx:xx play mediafile with player

or

at xx:xx browse mediafile with browser

Where the x's are the time, mediafile is the media file you want to play, and player is the name of your media player. An example, should you need one, is in test.txt and is the one I used to test this statement.

If the player or browser has been set using those options, you can leave off the "with player/browser" part.

The view and edit commands are also supported, if you prefer to use those commands for some reason. You'll need to use the "with" keyword, though, unless you want to play the file with whatever's in your player setting.

You can use either 24-hour time, or what I think of as "human time" with PM. So

at 5:24 PM, play foobar.wav with firefox

would work. Or you could just use 17:24 if that's comfortable for you. You can use AM if you want, but it'll be ignored except between midnight and 1AM, because it's assumed to be AM unless you specify otherwise either with PM or with 24-hour time notation. You can prove to yourself that AM is ignored by specifying 17:24 AM. The file will play at 5:24 in the afternoon anyway. The use of 24-hour notation with PM won't work right, as I discovered when I forgot to remove the PM. 17:24 PM means 29:24 to the interpreter, as it turns out. :)

The exception, as noted above, is between midnight and 1AM. If it's midnight or after, you have to specify AM or the interpreter will assume you mean noon or after. So, if you want the file to play at a quarter after midnight, you'd type

at 12:15 AM play foobar with vlc

or browse if that's what you prefer.

I don't feel like messing with my system clock, and I don't feel like staying up until midnight, so this hasn't been tested. But I can't think of any reason it wouldn't work. If it doesn't work, you can still run things between midnight and 1AM by using 00:xx, as in

at 00:15 play foobar with firefox

Conversely, you should not use PM between noon and 1PM, because it'll confuse the interpreter and things won't work. There's no such thing as 24:15, even in 24-hour time, so the interpreter is likely to hang. Just leave off the PM, though, and it'll assume you mean noon by default and all will be well.

I also discovered that, on my laptop, all sorts of weird things would happen if it started to overheat. That shouldn't be an issue except with older laptops but, if you have one of those elderly beasts like I do, you should be aware that you might get some odd error messages if things get too warm for your old machine.

Essentially, this statement turns the interpreter into a rather bloated alarm clock. However, Firefox gave control back to the interpreter as soon as it started running the file. If your preferred player does the same, you could use this statement to execute the commands of your choice at a specific time. So it might be handy on some limited level, with hopefully fewer limitations as we go along.

In addition to this statement, at is used with other commands as a keyword to indicate position.

BACKGROUND Changes the background color. In order to change the entire background of the terminal at once, you'll need to use the cls command. Otherwise, the background change will just scroll up as you print, which is fine if that's what you want. You will, of course, want to be printing your text in a color other than the background, unless you're working undercover.

background black
cls
print "Black Background"
background red
cls
print "Red Background"
background green
cls
print "Green Background"
background yellow
cls
print "Yellow Background"
background blue
cls
print "Blue Background"
background magenta
cls
print "Magenta Background"
background purple
cls
print "Purple Background (Same as Magenta)"
background cyan
cls
print "Cyan Background"
background gray
cls
print "Gray Background"

BLACK Used with the color command to change the text color to black, resetting to normal text. Also used with the background command to change the background color.

BLUE Used with the color command to change the text color. Also used with the background command to change the background color.

BOLD Allows you to set the bold attribute in text:

bold on
print "Bold Text"
bold off
print "Back to normal text"
color bold black
print "Bold Black Text"
color bold red
print "Bold Red Text"
color bold green
print "Bold Green Text"
color bold yellow
print "Bold Yellow Text"
color bold blue
print "Bold Blue Text"
color bold magenta
print "Bold Magenta Text"
color bold purple
print "Bold Purple Text (Same as Bold Magenta)"
color bold cyan
print "Bold Cyan Text"
color bold white
print "Bold White Text"

BRIGHT Used with the color command to change the text color, only works with magenta and purple.

BROWN Used with the color command to change the text color, same as dark red.

BROWSE Calls an external browser to view pages, images, media files, and like that. You can specify a browser with the browser= setting if you like. It works much like the play command, and in fact uses the same routine, but the play command won't pay any attention to your browser setting and will attempt to use the player setting if available or throw an error if not.

If you specify a browser using the browser setting, you don't have to specify it in the program line, though you can and it should still work. If you've specified a browser, the syntax is simply

browse page

where page is a web page or local file that can be viewed by the browser. For instance, if the browser is specified, you could just type

browse /home/retrojunkie/slapstik/celebpic/aaliyahh/ah001.jpg

But you can still type

browse /home/retrojunkie/slapstik/celebpic/aaliyahh/ah001.jpg with firefox

or whatever browser you're using if you want to.

If you haven't specified a browser, you have to use the with keyword:

browse /home/retrojunkie/slapstik/celebpic/aaliyahh/ah001.jpg with firefox

for example.

It'll probably run almost any program on almost any file if you use the with keyword, in case that of use to you.

BROWSER Used with the browse command, it lets you specify a browser to use if the with keyword isn't in the program line. Syntax is

browser=browsername

For example:

browser=firefox

You have to type it exactly as shown, no spaces, because I'm too lazy to write the routines to deal with whitespace. Maybe later, but don't count on it soon. Not surprisingly, it needs to be before any lines using the browse command and ideally would be placed at the top of the file along with the other settings.

CENTER Tries to center the specified text in the current row. Syntax is

center "String you want to print"

The text has to be in quotes, and variables aren't supported at the moment.

CHOICE Used to assign or print the random number generated by the choose command:

assign choice to rndnumvr

Once assigned, you can perform math on it or whatever you want to do.

print choice

Just like it says, prints it on the screen.

This is another system variable, meaning you can assign to it just fine, but you can never get the value you assigned back out of it, because it'll either give you the last random number generated or 0.

CHOOSE This generates a random number between the minimum and maximum values set in the program line:

choose a random number from minimum to maximum

For instance:

choose a random number from 1 to 10

If you don't get the syntax right, something is almost certain to go awry since I haven't gotten around to plugging in any error handling routines.

Once you've got the random number, you can assign it to a variable with

assign choice to variablename

at which point you can print it, use it in mathematics, and like that. It should never generate a number less than the minimum value set in the program line, but it's been only sketchily tested and you never know what you might wind up with.

CLOSE Closes a file previously opened with create or open. There's no message as to success or failure, because generally it fails because the file isn't open. In that case, there's no harm done, so there's no point in talking about it. Syntax is

close filename

Where filename is the name of your file, surprise. The interpreter will try to use the filename to keep track of which one you want closed, and I think that's been coded successfully. If you find differently, let me know.

CLS Clears the terminal screen by printing a blank line 25 times. The cursor is then repositioned in the upper left corner of the terminal screen. I'm given to understand that some terminals have more than 25 lines by default, but I wrote it for my system, which is 25 lines by 80 columns. Maybe I'll do something more sophisticated later. The cursor positioning routine was from "mitchi" to whom many thanks.

A holdover from BASIC, this would probably be more English-like if it were "clear screen" or even just "clear" but I haven't gotten to it yet.

COLOR Changes the text color:

color gray
print "Gray Text"
color black
print "Black Text"
color dark gray
print "Dark Gray Text"
color bold black
print "Bold Black Text"
color red
print "Red Text"
color dark red
print "Dark Red Text"
color rust
print "Rust Text (Same as Dark Red)"
color brown
print "Brown Text (Same as Dark Red)"
color bold red
print "Bold Red Text"
color green
print "Green Text"
color dark green
print "Dark Green Text"
color bold green
print "Bold Green Text"
color yellow
print "Yellow Text"
color dark yellow
print "Dark Yellow Text"
color olive
print "Olive Text (Same as Dark Yellow)"
color bold yellow
print "Bold Yellow Text"
color blue
print "Blue Text"
color dark blue
print "Dark Blue Text"
color bold blue
print "Bold Blue Text"
color magenta
print "Magenta Text"
color bright magenta
print "Bright Magenta Text"
color bold magenta
print "Bold Magenta Text"
color purple
print "Purple Text (Same as Magenta)"
color bright purple
print "Bright Purple Text (Same as Bright Magenta)"
color bold purple
print "Bold Purple Text (Same as Bold Magenta)"
color cyan
print "Cyan Text"
color dark cyan
print "Dark Cyan Text"
color bold cyan
print "Bold Cyan Text"
color white
print "White Text"
color bold white
print "Bold White Text"

COLUMN Used with the load command in the execution of a menu, telling it how many columns from the left side of the terminal screen to begin printing the menu items. If omitted, it should just start printing at the far left of the screen.

COPY Copies a file. This latest routine includes some minimal error checking. It also seems quite a bit faster than the first routine, though it's still pretty slow with larger files. But it works, which I find satisfactory for the moment. The syntax is

copy source path and filename ~to destination~ destination path and filename

For instance:

copy "/media/E65CA3355CA30003/Music/e.mp4" to "/home/retrojunkie/slapstik/programm/working/e.mp4"

As always, syntax has to be exact or you'll get odd results at best.

I've tested this with a text file, a jpeg file, and an mp4 file. I watched the entire 22 minutes of the mp4 to make sure nothing had gone awry, and it was fine.

You have to specify the destination file name, but you can specify whatever destination name you want. So you can copy /temp/test.txt to /backups/test2016-1-20.backup if you want, it won't hurt anything.

It'll refuse to overwrite existing files, saying the file exists and specifying which file it means. I might make it a little less fussy later, in order to automate backups and like that, but I haven't gotten to it yet.

This routine was taken from a program written by Marko Martinovic and respectfully kicked until it did approximately what I wanted it to.

COUNT A very primitive loop. Syntax is

count from start to finish and assign count to variable
(Do Stuff)
next

Thus far, this has only been tested with one command between the count and the next, thus:

count from 1 to 3 and assign count to a
print a
next

Looking at the code, I can't see any reason it wouldn't work with up to 25 commands between the count and the next, but I haven't tested that yet.

You can also count backward, like so:

count from 3 to 1 and assign count to b
print b
previous

At the moment, you can only count by "ones" and I don't know when I'll change that. I've got some ideas about it, though, and I don't think it would be terribly difficult, so it'll probably happen at some point.

The keyword count is used as a variable by the interpreter, and probably won't work properly if you try to assign a variable to it. It would likely work fine until the first time you called a count loop, at which point the value you stuck in there would be replaced. So I recommend against trying to assign anything to it except in a count loop.

CREATE This comes in two varieties, depending on whether you specify file, folder, or directory:

file Opens a text file for writing. The file is created if it doesn't exist. If it fails to open the file, it says so and moves on. If it's successful, it says that and leaves the file open so you can write to it. Syntax is

create file filename

You should be aware that if the file exists, the contents will be erased. So you need to either be sure the file isn't already there, or that it has contents that can be replaced.

folder Creates a folder (makes a directory). Syntax is

create folder directoryname

If it can't make the directory, it'll tell you so and move on. You get no information other than "failure" at the moment. Otherwise, it just makes the directory with no comment.

directory Does exactly the same thing as the create folder command, just using a different word.

CYAN Used with the color command to change the text color. Also used with the background command to change the background color.

DARK Used with the color command to make a darker shade of the specified color. You should be aware that there is no dark magenta, only standard magenta (which is pretty dark), bright magenta, and bold magenta. The same holds true for purple, which is a synonym for magenta.

DATE Gets and formats the system date, and copies it to a variable. You can print it using the print command, like so:

date
print "Today's date is ";
print date;
print "."

which would give you something like

Today's date is March 4, 2016.

You can also use date with the print to command.

You should be aware assigning a value to a variable named date would be a study in frustration. The interpreter will allow you to assign the value, but every time you try to access it you'll either get a blank or the result of the last date command.

DELETE Deletes a file, not amazingly. There's none of that "are you sure?" nonsense, and I haven't even looked into an undo feature, so you need to be certain that you've selected a file you can afford to lose. Syntax is:

delete filename

where filename is, again not incredibly, the name of the file you want to get rid of.

If the file can't be deleted, you'll get an error message to that effect. Otherwise, it'll just delete the file without any message.

DIFFERENCE Used to hold the result of a calculation produced with a subtract statement. Another "system" variable you can assign to but never get the value you assigned back out of, because it'll always give you the result from the last subtraction or zero if no subtraction has taken place yet. You can print the difference or assign it to a variable.

DIRECTORY Used in the create command, as a synonym for folder.

DIVIDE Divides two values. Here's a test script:

assign 3 to a
divide 2 by a
print quotient
assign quotient to b
print b
divide 2 by 13
print quotient
assign 7 to gedit
divide gedit by a
print quotient
assign 9 to vlc
divide vlc by 2
print quotient

You should get 0.666667 twice, then 0.153846, 2.333333, and 4.500000 on your terminal screen.

DO A primitive conditional loop. The best explanation is probably an example:

assign 0 to a
do
add 1 to a
assign sum to a
print a
until a equals 3

A do loop can only handle comparisons of equality between a variable and an integer in the "until" line at the moment. However, you should be able to do (you should pardon the expression) an end run around that by including something like the following (untested) line:

.
.
if a$ equals "Done" assign 3 to a
until a equals 3

That would allow you to use a string comparison to end the loop, for all intents and purposes. Again, though, I haven't tested it. It just seems like it would work.

DO: Used at the beginning of a block if statement, thus:

if a is less than 4 do:
stuff to do
more stuff to do
yet more stuff to do
done

You should be able to use as many program lines as you like, of such allowed types as are currently available.

DONE Used with the load command to tell the interpreter to end the menu and return to the main script. Also used at the end of a block if statement to tell the interpreter you're um, done.

EDIT Runs a specified external program on a specified file. It works exactly the same as the play command, but doesn't recognize a default editor, so you'll always need the with keyword to make it work properly. Syntax is

edit file with editor

where you substitute your own file and editor names.

It'll probably run almost any program on almost any file if you use the with keyword, in case that's any use to you.

EMPTY Deletes all the files in a specified directory. There's none of that "Are you sure?" nonsense, and I wouldn't even know where to start looking into an undo feature, so you're expected to know what you're getting rid of. Syntax is

empty directorypath/name

So, you might decide to delete everything in the temp directory while you're in the /home/retrojunkie/slapstik/programm/working directory. In that case, you could either type

empty /home/retrojunkie/slapstik/programm/working/temp

or

empty test

There are no messages as to success or failure, but you can check it if you like by using the list files command:

list files test

or

list files /home/retrojunkie/slapstik/programm/working/temp

in this case.

You shouldn't add a trailing slash on the end, because the interpreter does that for you. So

empty test/

would turn into

empty test//

which would probably fail.

The directory itself is not removed, in case you want to keep it. For instance, I use temporary directories a fair bit. I trash the files every once in a while, but I keep the directories around for the next time I need them. So I don't want to delete the directory along with the rest of the stuff.

EQUAL Part of the "is not equal to" state, used in if statements.

EQUALS Tests the equality between the values of two variables, used in an if statement.

FILE Used with the create command to open a text file for writing. Also used with the open command.

FILES Used with the list files command to list the files in a specified directory, or the current one if none is specified.

FIND Finds a phrase inside another phrase. Syntax is

find "search phrase" in "phrase to search"

For example:

find "test" in "This is a test"

It then assigns the position in the string where it found the phrase to the "system variable" string. If the phrase was not found, string will contain the value -1. You can then assign string to another variable, which you can then print. You can probably perform math on and with it as well, but I haven't tested that.

Once you've got the position from the variable string, you can use it with the starting statement to slice up your string. See that section for more information.

FOLDER Used with the create command to create a folder (make a directory).

FROM Used in various statements to indicate a source or a range.

GRAY Used with the color command to change the text color to gray. Also used with the background command to change the text color.

GREATER Part of the greater than state, used in if statements.

GREEN Used with the color command to change the text color. Also used with the background command to change the background color.

IDLE Pauses the program for the specified number of seconds. Syntax is:

idle xx

where xx is the number of seconds to wait. There are error-handling routines that seem to work, though they've been only sketchily tested.

IF A primitive conditional statement. Syntax is

Equality:

if conditionistrue dosomething

Here's a script file to demonstrate:

assign 3 to a
print "At start, a=";
print a
print
print "The sum=";
print sum
if a equals 3 add 2 to a
print
print "After if statement, the sum is ";
print sum

In this case, the condition is true and the addition is performed. I also tested the same file with 4 assigned to a, and the addition didn't happen. So I'm assuming it works, such as there is of it.

You can also use the and operator to test if two conditions are both true. If they are, the statement is carried out. If not, then not:

if condition1istrue and condition2istrue dosomething

Example:

if a equals 5 and gedit equals 12 add 2 to a

Attempting to use and as a variable name will sometimes work and other times won't. So I recommend against it.

The or operator is available as well, and tests if one or the other of two conditions are true. If one or the other is, the statement is carried out. If both are false, the statement is ignored and the interpreter goes to the next line. Syntax is:

if condition1istrue or condition2istrue dosomething

Example:

if a equals 5 or gedit equals 11 add 2 to a

Attempting to use or as a variable will work sometimes and won't work some other times. So I recommend against it.

You should be able to run most of the interpreter's available commands with an if statement. I've only tested a few commands, but I can't think of a reason why it wouldn't work with almost everything.

You can also test for equality with string variables:

assign "testing and testing" to test$
print test$
assign test$ to a$
print a$
if a$ equals "testing and testing" print "Variables match."

The goofy value for test$ is the result of my trying to code so you can include the words "and" and "or" in your string variables without having the interpreter wet itself. It's kind of kludgy, but it seems to work. Actually, I'm not real enthused about the coding for the if statements in general, but I haven't come up with anything better quite yet.

After some quick and sloppy testing with string variables and the and operator, it appears to work. But I had to do this quickly, so I'm not offering any warranty on this one. :)

The or operator seems to work with string variables as well.

Two variables can be compared. An example:

assign a to q
if a equals q print "Variables a and q match."

You can also compare two string variables, such as if infinity$ equals finity$ etc.

You can compare two variables on either side of an and or or statement. These have been tested and are known to work, as entered into test.txt:

if infinity$ equals finity$ and a equals 3 print "This worked."
if infinity$ equals finity$ and a equals q print "This worked too."
if infinity$ equals finity$ and a$ equals test$ print "Still working."
if a equals q and infinity$ equals finity$ print "I think we're done with the and operator."
if infinity$ equals finity$ or a equals gedit print "Or works."
if a equals q or infinity$ equals ctest$ print "Or still works."
if infinity$ equals finity$ or a equals q print "Or is continuing to work."
if a equals gedit or infinity$ equals finity$ print "Or is still working."
if infinity$ equals finity$ or a equals 7 print "I'm running out of ideas for the Or operator."
if a equals 7 or infinity$ equals finity$ print "I think I'm done with the Or operator for now."

Inequality:

I'm doing this a piece at a time, to make sure I don't introduce more bugs at once than I can squish at one sitting:

if a is not equal to 7 print "Here's a primitive inequality."
if a$ is not equal to "Florida" print "Here's another."
if a is not equal to gedit print "Yet Another."
if infinity$ is not equal to ctest$ print "Still another."
if a is not equal to 4 and gedit is not equal to 12 print "Numeric constants with and seem to work."
if a$ is not equal to "Florida" and infinity$ is not equal to "media" print "String constants seem to work as well."
if a is not equal to gedit and gedit is not equal to q print "Numeric variables with and appear to be working."
if a$ is not equal to infinity$ and infinity$ is not equal to ctest$ print "String variables too."
if infinity$ is not equal to a$ and a is not equal to 4 print "Mixing variable types worked with inequality."
if a is not equal to 7 and infinity$ is not equal to a$ print "Seems to work the other direction too."
if a is not equal to gedit and infinity$ is not equal to a$ print "Inequality statements, and operator, mixed, no constants."
if infinity$ is not equal to ctest$ and q is not equal to gedit print "Same as above, other direction."
if infinity$ is not equal to a$ or a is not equal to q print "Simple or statement, working with inequality."
if infinity$ is not equal to a$ or a is not equal to 3 print "Another."
if a is not equal to q or infinity$ is not equal to a$ print "And another."
if a is not equal to gedit or infinity$ is not equal to finity$ print "Yet another."
if infinity$ is not equal to "test2" or a is not equal to 7 print "Getting there."
if a is not equal to q or infinity$ is not equal to "Canterbury" print "Closer to there."
if infinity$ is not equal to finity$ or a is not equal to 7 print "Almost done."
if a is not equal to 7 or infinity$ is not equal to finity$ print "Done."

Greater Than:

Equality and inequality really aren't sufficient. There are plenty of situations where you'll want to know if one value is larger than the other. This section shows my progress with the greater than routines.

if sat is greater than a print "Simple example of the greater than operator."
if sat is greater than 3 print "Greater than with constants."
if player$ is greater than recommended$ print "Theory is greater than Bambi."
if player$ is greater than "Bambi" print "Theory is still greater than Bambi."
assign 12 to tue
if sat is greater than a and tue is greater than sat print "And statements should be working with Greater Than."
if sat is greater than a and test$ equals a$ print "Mixing states, greater than and equals."
if a is greater than 2 and player$ is not equal to test$ print "Mixing states, greater than and not equal."
if a$ is greater than player$ and tue is greater than a print "Greater Than, and statement, string variables first."
if sat is greater than a or sat is greater than tue print "Or statements should be working with Greater Than."
if a is greater than sat or tue is greater than sat print "Or statement, numeric variables, first half false."
if sat is greater than a or test$ equals infinity$ print "Mixing states, greater than and equals."
if a is greater than 2 or finity$ is not equal to infinity$ print "Mixing states, greater than and not equal to."
if a$ is greater than player$ or a is greater than tue print "Greater Than, or statement, string variables first."

You may want to bear in mind that lower-case letters are "greater" than upper-case, so "t" is greater than "T" and "test" is greater than "Theory" no matter how silly that may seem.

Less Than:

if a is less than sat print "Simple example of the less than operator."
if a is less than sat and sat is less than tue print "Simple and statement with less than."
if a is less than 4 and player$ is not equal to test$ print "Mixing states, less than and not equal."
if a is less than sat and test$ equals a$ print "Less Than, mixed states, less than and equals."
if player$ is less than a$ and a is less than tue print "Less than, and statement, string variables first."
if a is less than sat or tue is less than sat print "Simple or statement with less than."
if sat is less than a or sat is less than tue print "Or statement, less than, first half false."
if sat is less than a or test$ equals a$ print "Mixing states, less than and equals."
if a is less than 2 or test$ is not equal to infinity$ print "Mixing states, less than and not equal."
if a$ is less than player$ or a is less than tue print "Less Than, or statement, string variables first."

As always, you should bear in mind that if it isn't listed here, it hasn't been tested. And, as always, if you find something that should work but doesn't, I'd appreciate hearing about it.

Mixed States:

The if routines, even after a massive rewrite, are still quite sloppy. However, they're neatened up enough that I was able to add the first version of the routines allowing you to mix states (equality, inequality, etc.) in and/or statements:

if a equals 3 and player$ is not equal to "Theory and Reality" print "I'm pretty sure mixing states needs more work."
if a equals q and player$ is not equal to a$ print "Let's see if mixing states with variables will work."
if player$ equals "Theory" and a is not equal to 4 print "Still mixing states as expected."
if a$ equals test$ and a is not equal to gedit print "Expectations confirmed."
if a is not equal to 4 and player$ equals "Theory" print "So far so good."
if player$ is not equal to "Test" and a$ equals test$ print "Not bad."
if a is not equal to gedit and infinity$ equals finity$ print "Twisting and Testing."
if player$ is not equal to a$ and a equals 2 print "Do the twist."
if updates equals 7 or player$ is not equal to "Theory" print "Now we try mixing states with Or."
if updates equals available or player$ is not equal to "This value shouldn't matter" print "This should work."
if player$ equals "Theory" or a is not equal to 4 print "This should work as well."
if a$ equals test$ or a is not equal to gedit print "No reason this shouldn't work."
assign 10 to mb
if mb equals 3 or player$ is not equal to "Fri" print "Or statement, mixed states, first half is false."
if mb equals a or player$ is not equal to recommended$ print "As above, all variables, no constants."
if player$ equals "Bambi" or b is not equal to 3 print "As above, string constants first."
if player$ equals a$ or mb is not equal to q print "As above, string variables first."
assign 9 to sat
if sat is not equal to 3 or player$ equals "Jul" print "Inequality first, constants, first half is true."
if sat is not equal to a or player$ equals recommended$ print "As above, variables."
if player$ is not equal to "Bambi" or sat equals 3 print "As above, string constants first."
if player$ is not equal to a$ or mb equals 10 print "As above, string variables first."
if sat is not equal to 9 or player$ equals "Theory" print "Constants, first half is false."
assign sat to pm
if sat is not equal to pm or a$ equals test$ print "Numeric variables first."
if a$ is not equal to test$ or sat equals pm print "String variables first."
if a$ is not equal to test$ or sat equals 9 print "Mixing variables and constants."
if sat is greater than a and test$ equals a$ print "Mixing states, greater than and equals."
if a is greater than 2 and player$ is not equal to test$ print "Mixing states, greater than and not equal."
if sat is greater than a or test$ equals infinity$ print "Mixing states, greater than and equals."
if a is greater than 2 or finity$ is not equal to infinity$ print "Mixing states, greater than and not equal to."
if a is less than 4 and player$ is not equal to test$ print "Mixing states, less than and not equal."
if a is less than sat and test$ equals a$ print "Less Than, mixed states, less than and equals."
if sat is less than a or test$ equals a$ print "Mixing states, less than and equals."
if a is less than 2 or test$ is not equal to infinity$ print "Mixing states, less than and not equal."

I'm calling mixed states officially finished. Again, if you find something that should work according to this manual, but doesn't, please tell me about it.

Block If Statements:

If you want to do a bunch of stuff when an if statement evaluates as true, you can use a block if:

if a is less than 4 do:
  add 4 to 5
  print sum
  assign "Block If Test" to retrojunkie$
  print retrojunkie$
  print tab(20), "Block If Test"
  center "Block If Test"
done

You can indent as shown above, but only with spaces. Using the tab key probably won't work, unless your text editor expands tabs into spaces.

Only minimal testing has been done on the block if routines, because I'm lazy and because I'm freaking sick of the if statement routines. Been working on 'em for months, and I'm calling them done until I or someone else finds a bug.

IN Used with the find command

IS Part of the inequality, greater than, and less than states, used in if statements.

ITEM Used with the load command in the execution of a menu, indicating the name of a menu option.

JUMP Tells the interpreter to jump to a subroutine and execute the lines it finds until a return command is found. It then comes back to the part of the program that called the subroutine and continues execution from the next line. Syntax is

jump to label

Here's a sample script file illustrating its use:

print "Here we are in the main program."
print
jump to subrouti
print "And here we are back in the main program again."
quit
label subrouti
print "Here we are in the subroutine."
print
return

It should print:

Here we are in the main program.

Here we are in the subroutine.

And here we are back in the main program again.

Your subroutines should be at the end of the script file, preferably after a quit command, because if the interpreter encounters a return command without a jump, things might get weird. They probably won't, but they might. So you should separate the subroutines from the main program just to be on the safe side. It's also just good programming practice, makes things neater.

LABEL Indicates a place for the jump command to um, jump to.

LESS Part of the less than state, used in if statements.

LINE NUMBERS You can add line numbers to your program if you like. They're ignored, and won't affect the order in which the program lines are executed. You could probably use a line number as a label, with a line like LABEL 40, but I haven't tested that. I did this largely because I could, but it may have some use if you have a routine from a program with line numbers that you want to use with the interpreter. You'd still have to make some major changes to the routine in order to make it work, but at least you wouldn't have to worry about the line numbers.

10 print "This is a test." or 10print "This is a test." will both print This is a test. on your screen.

LIST FILES Lists the files in a given directory. If no directory is specified, it lists the files in the current directory. If one is specified, it lists the files in that directory or tells you if it can't find the directory specified. Syntax is

list files

or

list files pathname

LOAD This is intended to load and run a menu. I thought it might be useful if you wanted to set up something for someone who isn't computer-savvy enough to write a script file. Unfortunately, it really isn't anything I care about and it was rather a longer project than I'd first expected, so it's received only the sketchiest of testing, in the form of menutest.txt and menutest.mnu, which should be included. In case they aren't, menutest.txt is simply

load menu menutest.mnu

while menutest.mnu consists of

menu column 10
menu item=Alarm Clock
menu action=at 16:29 play /home/retrojunkie/slapstik/programm/working/e.mp4 with firefox
menu item=Quit
menu action=done

There can be up to ten options in the menu. When it displays the menu, the user will press the key corresponding to the choice they want, and then press Enter. Here are the options explained in more detail:

menu column Tells the interpreter how far in to begin printing the menu items. If you omit it, the menu should just appear on the far left side of the terminal screen.

menu item Just the name of the menu option, which can be anything you like. Of course, you're probably going to want something descriptive, but you could use anything you want, as an All Fools Day prank for instance. The last item should always be Quit or Exit or something of that nature. Otherwise, there'll be no way out except Ctrl-C.

menu action This is what the interpreter will do when you choose the letter corresponding to the action. It should be able to do anything the main interpreter can do, except the options will be in menu form, and you can have a maximum of ten options in your menu. The line menu action=done is the only way to tell the interpreter that the user wants out of the menu. You can omit this if you think it'll help keep said user out of the rest of the system and limit them to only the options you choose.

LOCATE Moves the cursor to the specified position on your terminal screen. Syntax is

locate column,row

I've discovered over the years that I often get things backward. So if the position of the cursor doesn't look right to you, try just reversing the numbers. That often works for me. :) The obligatory example:

locate 20,10
print "Locate Test"

MAGENTA Used with the color command to change the text color. Also used with the background command to change the background color.

MAKE Does different things depending on its use:

make private code Randomly generates a password from lower-case letters, upper-case letters, numbers, and symbols. I included this mostly because I could, I think, but it might be handy to someone. Syntax is simply

make private code

And it'll spit out a randomly generated password for you.

You should be aware that not all web sites accept all special characters for use in passwords, so you may have to alter your password to suit the needs of the site you're visiting. Also, there's no guarantee that all the options will be included, so if the web site insists on at least one upper-case letter or at least one lower-case letter, you again might have to alter your password to suit. And as a security side note, eight characters may be a little short. You can always change the source code to allow for more if you don't feel secure. Still and all, the passwords generated aren't bad, and can be altered readily to suit your needs or preferences.

make new variable Makes a new numeric variable with the name you specify and initializes it to zero. It checks to see if the variable already exists. If it does, it'll set its value to zero without comment. Syntax is:

make new variable variablename

It works exactly the same as

assign 0 to variablename

and you can use whichever you prefer.

MENU Used with the load command in the execution of a menu.

MOVE Moves a file. Syntax is

move "pathname" to "pathname"

You have to specify both the path and filenames for both the source and destination, but you have the option of specifying a different filename for the destination. So you can move and rename at the same time, if you like.

If the destination filename already exists, the move will fail with a message to that effect. In other words, it'll refuse to overwrite existing files. Maybe I'll change that at some point, but I doubt it. At the moment, I like the added security of not trashing an important file just because it had the same name as the one I was trying to move.

If you're moving to a different directory on the same drive, it'll probably be pretty quick. But if you're moving a large file to a different drive, it's likely to be quite slow. Just so you're aware.

MULTIPLY Multiplies two numbers. Sample script:

assign 3 to a
multiply 2 by a
print product
assign product to b
print b
multiply 2 by 13
print product
assign 7 to gedit
multiply gedit by a
print product
assign 9 to vlc
multiply vlc by 2
print product

You should get 6 twice, then 26, 21, and 18 printed on your terminal screen.

NEW Used with the make command to create a new numeric variable.

NEXT Used to indicate the outer boundary of a count loop.

NOT Part of the "is not equal to" state, used in if statements.

NUMBER Used with the choose command to generate a random number.

OFF Turns the bold attribute back off for text and resets the color to black, used with the bold command.

OFFLINE An option for the web setting. In fact, it's the only option at the moment. More information in the section on the web setting.

OLIVE Used by the color command as a synonym for dark yellow.

ON Sets the bold attribute on for text, used with the bold command.

OPEN This comes in two flavors, as follows:

open file The interpreter tries to open the file specified for reading. If it fails to open the file, it says so and moves on. If it's successful, it says nothing. Syntax is

open file filename.extension

open window: A useless command for anyone who doesn't use the Gnome Terminal, because that's all it does, open a new Gnome Terminal window. Syntax is

open window

OR Used in an if statement to test whether one or the other of two conditions is true:

if condition1istrue or condition2istrue dosomething

Example:

if a equals 5 or gedit equals 11 add 2 to a

While the interpreter will blithely allow you to use or as a variable name, trying to get the value will only work sometimes. Therefore, you probably shouldn't.

PLAY Uses the media player of your choice to open a media file and plays it. No error-checking goes on here, and I haven't tested it to see what it'll do if the file doesn't exist, so you're on your own there. Maybe later. You can specify the player in the program line, thus:

play file with player

substituting your own file and player names. You can also specify a default player, with the player setting, in which case you can just type

play file

It'll probably run almost any external program on almost any external file if you use the with keyword, in case that's of use to you.

PLAYER This web setting allows you to specify the default player to use with the play command. Syntax is

player=filename

where filename is the name of the player you want to use.

It has to be exactly as shown, with no spaces, because I don't feel like fiddling with whitespace at the moment.

PM Used with the at keyword to specify a time after noon while still using 12-hour time notation or, as I like to think of it, human time.

PREVIOUS Used in a count loop when counting backward.

PRINT You can use this to print a message on the screen. You enclose it in quotes, like this:

print "Hello, World!"

If you just use the print command with nothing after it, it'll print a blank line. If you use the tab option, it'll move to a specified column before printing. You can use the to option to print to a file. You can use the time option in conjunction with the time command to print the current time. You can use the date option to print the date. Get more information in the sections on the date, tab, time, and to options.

The default action, when printing a message, is to print said message and then move to the next line. If you don't want it to do that, you can stick a semicolon on the end, thus:

print "This is a test of the ";
print "semicolon option."

which should print

This is a test of the semicolon option.

This would be handy when using print in conjunction with the date and time commands. I don't know what use it would have otherwise.

The semicolon option is also available when using the print to option.

If you leave off the quotes, the interpreter assumes you want to print a numeric variable. If that variable exists and has a value, it gets printed. Otherwise, it'll tell you that the variable wasn't found. Syntax is

print variablename

You can also print the result of a previous addition:

print sum

If you haven't performed an addition prior to the print statement, you'll probably get a zero, but you might get something weird too, I haven't looked at it that closely.

You can print the result of a previous subtraction:

print difference

the result of a previous multiplication:

print product

and the result of a previous division:

print quotient

You can also print a previously assigned string variable:

print stringvariablename$

You should be able to print a random number returned by the choose command:

print choice

but I haven't tested it yet, so I'm not making any promises. You can, however, assign the number to a variable and then print that, because that's been tested.

You can print a line previously read with the read command:

print line

If no line has been previously read, you'll most likely get a blank line for your trouble.

Lots of holdovers from BASIC here, because I often don't notice until later. This one is from back in the days when all output actually was printed, on a line printer. No display screens, just the printer. Later LPRINT was added to specify sending data to a printer, and PRINT was used to send information to the screen. Not very English-like, but maybe I'll put in a say or write command one of these days.

PRODUCT Holds the result of a multiplication. Another "system" variable you can assign to all day but never get the value you assigned back out of, because when you try to print it or assign it to something, it'll always return either the product of the last multiplication or zero if no multiplication has yet occurred. So don't do that.

PURPLE Used with the color command, as a synonym for magenta. Also used with the background command to change the background color.

QUIT Does what it says. Ends the program before all the lines have been processed and returns you to the terminal. Just like the system command, but more English-like.

QUOTIENT Holds the value of a division. Another "system" variable you can assign to but never get the value you assigned back out of, because when you try to print it or assign it to something, it'll always return either the quotient of the last division or zero if no division has yet occurred.

RANDOM Used with the choose command to generate a random number.

READ Reads a line from a file previously opened, thus:

read line from filename.extension

Another "system" variable, you can assign a value to line but never get it back because it'll just return what was last read from the file or a blank line if nothing has been read yet.

RED Used with the color command to change the text color. Also used with the background command to change the background color.

REM Short for remark, it's used to denote a comment. It does this by virtue of having no instructions for what to do if a line beginning with rem is encountered. Any line it doesn't have instructions for is ignored. So you can use any word that doesn't have a purpose yet, such as comment, marigolds, or any punctuation mark. This could change at any moment, though, so you should probably consider rem and the apostrophe to be the main comment "keywords".

Any comment has to be on its own line for the time being. I might fix that, or I might not, but for now if you want to comment your program you'll have do it above or below the part of the program you're commenting. There should be a space between rem and the comment. It'll probably work if you don't, but that could change.

rem This is a comment. will be ignored by the interpreter.

RENAME Just what you'd expect, it renames a file. Syntax is

rename "file1" to "file2"

Where file1 and file2 are the file you want to rename and the new name for the file. As always, syntax must be exact. If it isn't, you'll get some odd results.

The destination is checked to see if it exists before attempting the rename. If it does exist, you'll get the message

filename appears to exist, skipping...

If it can't rename the file for any other reason, it'll tell you it can't with no further details and move on. Otherwise, it'll just rename the file with no comment.

RETURN Tells the interpreter to return to the main program from a jump command. I don't think there'll be any problem if the interpreter encounters a return command without a matching jump, but I can't guarantee that. So I recommend you separate the subroutines from the main program, preferably at the end with a quit command in between the main program and the subroutines. It's also just good programming practice, as it makes things neater in general.

REVERSE VIDEO This causes the foreground color to become the background color and vicey the versey for whatever text is printed next. To turn it off, you'll have to use bold off or color black, and reinstate your previous color, thusly:

reverse video
print "Reverse Video"
color black
color bold white
print "Reverse Video Off"

The above example assumes you were printing in bold white before you invoked the reverse video.

RUST Used with the color command as a synonym for dark red.

SAVE Saves the file you opened using the create command. It doesn't close it, so you can write more to it after if you want to. I have no idea why you'd want to, but you can. Syntax is

save filename

where filename name is the file you opened with the create command. Actually, you could probably just use the word save by itself at the moment, but if I get around to having more than one file open at once, you'll need that filename. So you should probably include it just to be on the safe side.

SCORE Changes text attribute to scored text, which is to say text with a line through the middle. Turning it off involves using color black or bold off, both of which set the text color to black, so if you want to retain any other color, you'll have to reset it explicitly, for instance:

score
print "Scored Text"
color black
color bold white
print "Scored Text Off"

The example above assumes you were printing in bold white before you specified scored text.

STARTING Allows you to assign a string variable starting at the position returned by the find command:

find "test" in "This is a test"
assign string to te
starting at te assign "This is a test" to b$
print b$

In this example, the word test would be printed on the screen.

You can indicate starting and ending points using the to keyword:

find "Test" in "Testing"
assign string to t0
starting at t0 to 4 assign "Testing" to d$
print d$

This would print the word Test on the screen.

You can find string constants in string variables:

assign "Mares eat oats" to g$
find "eat " in g$
assign string to t4
starting at t4 assign g$ to h$
print h$

This would print eat oats on the screen. The trailing space after "eat" is because I was having trouble finding strings that included spaces, so I fixed it, and the sample script reflects those efforts.

You can also use the to keyword, so changing the "starting" line to

starting at t4 to 3 assign g$ to h$

would print the word eat on your screen.

You can use a numeric variable for the ending point using the to keyword:

assign "VLC Media Player" to pl$
find "VLC" in pl$
assign string to v0
assign 3 to nu
starting at v0 to nu assign pl$ to p2$
print p2$

would print VLC on your screen.

Thus far, this only works as shown above, but as far as I can see right now it should be enough to do most of the string parsing you might want.

STOP Quits the program and returns you to the terminal, just like the quit and system commands.

STRING A system variable used to hold the value returned by the find command. The interpreter will probably allow you to give it a value using the assign command but it will interfere with, and suffer interference from, the find command. So it's probably not a great idea.

SUBTRACT Subtracts one value from another. Syntax is

subtract value from value

Here's a sample script:

assign 3 to a
subtract 2 from a
print difference
assign difference to b
print b
print
subtract 2 from 13
print difference
assign 7 to gedit
subtract gedit from a
print difference
assign 9 to vlc
subtract vlc from 2
print difference

You should get a 1 printed on your terminal screen, twice, then 11, -4, and finally -7.

SUM Allows you to print the result of a previous addition:

print sum

If you haven't previously performed an addition, you'll probably get a "0" for your trouble.

You can also assign the value of sum to a variable:

assign sum to a

You should avoid, however, trying to assign a value to sum. The interpreter will cheerfully allow you to do so, but when you try to access that value, it'll be replaced with either the result of the last addition or with zero if there was no addition. So you'd never get to use that value, and your script might have startling or unfortunate results.

SYSTEM: Allows you to quit the program before all the lines have been processed. I'm not absolutely positive what value it has right now, but you can use it with an if statement to end the program early if you like. As the if statement options are expanded, this may have more use. This command is a holdover from BASICA/GW-BASIC, and the quit command would be more English-like if that's important to you.

TAB: Used with the print command to position the cursor at a specified column. Syntax has to be exact, and is as follows:

print tab(xx), "Thing you want to print"

xx is of course a number. I've included some basic error checking, so if you type print tab(1o) instead of print tab(10), it should trap it, inform you that 1o is not a number, and go on to the next line. I've tested the error routine, but it's entirely possible there's something I haven't thought of. If so, you may have to use Ctrl-C to break out of a hung program.

Remember, you have to type it as the example. If you type printtab or print tab (20), it probably won't work and may give you bizarre results. I might fix it so it's a bit more liberal, but my real interest was getting the thing working rather than making it easy to use. So for now, you have to get it right.

This keyword is a bit of a misnomer, and is another holdover from the days of BASIC. It would be more accurate to say print column(xx), since that's what it really does. It doesn't go to the next tab position, so if you're hoping for that you'll be disappointed.

THAN Part of the greater than and less than states, used in if statements.

TIME: Gets the system time, in the form "Time AM/PM" and puts it in the variable time. For example, at the time of this writing, it would return 12:20 PM. I think I've got it coded so it'll adjust for AM and PM, rather than printing a 24-hour time, but there could still be some issues that haven't occurred to me.

It doesn't do anything with the time except stick it in the variable. You can print it by using the print command with the semicolon option, thusly:

time
print "The time is currently ";
print time;
print "."

which would return

The time is currently 12:20 PM.

If you forget to use the time command before you print it, you'll get anything from a blank to the value that was in there the last time you used the command.

You can also use the time command with the print to command.

This is probably another variable name you shouldn't use with the assign command. I can't think of any reason the interpreter wouldn't allow you to assign the value but, as with the sum variable, you'd never get it back. All you'd get is either a blank or the results of the last time command.

TO This keyword is used with the print command to print text lines to the file you opened with create. For now, it also sends a "newline" at the end of the line, so each string you write to the file is on its own line unless you end it with the semicolon. Syntax is

print to filename, "string"

where filename and string are up to you. For instance, if you'd previously created test3.txt with the create command, you could then have a line such as

print to test3.txt, "Hello, World!"

It has to be exactly as shown, because both the comma and the quotes are markers to help the interpreter find the string you want to print. (The comma is used when printing the date to the file.) And, of course, the "to" tells it you want to print to a file rather than the display, so that has to be exact as well.

You can print the date and time to the file with

print to test3.txt, date

or

print to test3.txt, time

You can use the semicolon option (See the print command) the same as you would when printing to the display.

Using print to with just the filename, prints a blank line to the file:

print to test3.txt

This keyword is also used in various other statements, indicating a destination, range, or comparison. In some cases it helps the interpreter find things, and in other cases it's just a frill to make your script more English-like. It's mandatory, regardless, and the syntax has to be exactly as shown for the command in question.

UNDERLINE After encountering this command, the interpreter will underline any text written to the display. It should retain any other attributes it had. So if you had a color of dark green, the text would become dark green and underlined.

In order to turn off underlining, you'll need to use color black or bold off. If you want to retain the color you started with, you'll have to specify it again after color black. So, if you were printing in bold white and turned on underlining, and then wanted to turn off underlining but wanted to keep bold white as your color, you'd need to do something like this:

color bold white
print "Bold White Text"
underline
print "Underlined Text"
color black
color bold white
print "Underline Off"

UNTIL Used in a do loop to indicate the end of the loop and to show the condition for breaking out of said loop.

VARIABLE Used with the make command to create a new variable.

VIEW Like the edit command, this is identical to the play command, and is just to make your script file a bit more comprehensible if you should walk away from it and come back months later. You could just as easily use play or edit to do the same thing, but this one makes things a bit more legible. Syntax is

view file with viewer

substituting your own file and viewer names. There's no default viewer setting, so you'll have to use the with keyword.

It'll probably run just about any program on just about any file if you use the with keyword, in case that's any use to you.

WEB The browse, edit, play, and view commands will cheerfully attempt to load a web page if you have a line like

view www.retrojunkie.com with firefox

I'm in a position where I'm frequently offline, and I wouldn't want to have to clear tabs with nothing but error messages on them. So I wrote the web setting. The only option is offline, since if you're online you can just remove the line altogether or comment it out and the interpreter will attempt to access the web as normal. The web setting is used thus:

web=offline

and needs to be before any lines that use edit, play, or view to look at web pages. Ideally, it should be at the top of the file just to make sure it's set when you need it. Once the interpreter encounters that line, it'll respond to any attempts to edit/play/view a file starting with "http://" or "www.", or ending with ".com", with the message "This computer is offline and can't browse the web."

If you use Wine to run old DOS .COM programs, this setting will probably foil any attempts to do so from within the interpreter, though I haven't tested it.

It has to be exactly as shown, with no spaces between "web" "=" and "offline" or it almost certainly won't work. What can I say, I'm lazy.

WHITE Used with the color command to change the text color.

WINDOW Used with the open command, to generate another instance of the Gnome Terminal window.

WITH Used with the play, edit, view, and browse commands, to help get the name of the media player, text editor or other external program you want to use with your particular file. See the play, edit, view, or browse commands for examples of its use.

YELLOW Used with the color command to change the text color. Also used with the background command to change the background color.

Limitations (Aside from the Obvious)

The file has to be text. It probably won't do any harm if it isn't, but the interpreter won't have anything to interpret and most likely nothing will happen. I don't know for certain, however, that it won't do something bad, so I advise limiting yourself to text files for safety as well as practicality.

Each line can be a maximum of 199 characters long.

Each command, statement, function, etc. must be in lower case. This is due to sheer laziness; I have all the information I need to make everything case insensitive, but I have limited time to play with this thing and I'd rather concentrate on the guts of the program than on making it pretty. I'll probably fiddle with it when I don't have anything else to do and I have a pile of time to kill.

There can't be any blank lines in the text file. If there are, each executable line will be executed at least twice. For instance, if you have a text file called test.txt and it contains these lines:

cls
files

Now is the time for all good men to come to the aid of their party.
Now is the time for all good men to party.
Now is the party for all good times to come.

then the screen will clear, the files in the current directory will be listed, the screen will clear again, and the files in the current directory will be listed again. I have no idea why it does that, but I'm currently fiddling with other things so I'm not going to dig that particular hole right now.

Each variable's name is limited to, as I recall, nineteen characters. I should think that would be plenty, but you can always alter the code yourself if you want more. Spaces are not allowed in variable names. The numeric variable type is currently limited to integers for the most part, but floating point decimals are used for the quotients in the divide command.

You're currently limited to 198 variables, any mix of numeric and string types.

System variables can be assigned to, but with some you'll never get the value back once you've assigned it, instead getting back the value assigned into the system variable by the interpreter, or possibly a 0 or null string or something. Others will sometimes work just fine. Other times, the whole line will get bolluxed and the interpreter will just ignore it. So it's probably best if you avoid using those as well. I'll document each in its section as I go, but generally if you see the phrase "system variable" you should avoid using it for an assignment.

You can have up to 25 lines in between a count and a next in count loops. I don't really know what will happen if you try to add more than that, but I'm pretty sure it won't work right.

Any line that isn't an executable line is ignored. It's being done that way because it's easier. The advantage of doing it this way, aside from making the programming simpler, is that anything not recognized by the interpreter as an executable line can be used as a comment. The disadvantage is that if you misspell something to the point where the interpreter doesn't recognize it, the line is just skipped. This can lead to unintentional and potentially hazardous consequences.

As a side note, although some lines that can currently be used as comments may later be interpreted as commands, I expect I'll be reserving "rem" for comments. It's quick, easy to type, and obvious, so you should always be able to put in a line like

rem Mares eat oats and does eat oats, and little lambs eat ivy.

and the interpreter will ignore it.

These limitations are really a gracious plenty considering the tiny number of things the interpreter can do. Later, when the program does more (he said optimistically), the limits will be expanded.

Revisions

You should expect these revisions to be in the teensiest increments imaginable. I'm like that.

0.01, November 15, 2015: Initial file with command line argument options
0.01.01: Added usage information if no filename was specified
0.01.02: Added "File Not Found" error routines
0.01.03: Added the ability to read lines from the specified file
0.02: Added a command to clear the terminal screen
0.03, November 16: Added a command to list the files in the current directory
0.03.01, November 19: Added the ability to specify a directory for the files command
0.04, November 26: Added system command, to end the program early
0.05, December 4: Added open command, to open a file for reading
0.06: Added a command to get and print the system date
0.07: Added a command to get and print the system time
0.08, December 13: Added a command to open a text file for writing
0.08.01: Just a cosmetic change, positions the cursor in the upper left hand corner after a cls command, many thanks to "mitchi" for this
0.09, December 16: Added a command to play a media file with VLC.
0.10, December 20: Added code to allow specifying a player for the play command
0.11, December 21: Added an edit command, unnecessary but makes the script file a tad more legible.
0.12: Added a view command, again just for legibility
0.13, January 3, 2016: Added a print command to place the message of your choice on the screen
0.13.01: Fixed the print command so it'll print a blank line
0.14, January 7: Added a tab keyword so you can position the cursor at a specific column before you start printing
0.15, January 8: Added a quit command to exit the program and return to the terminal
0.15.01, January 10: Added error-checking routines to the print tab(xx) thingy, so it's less likely to hang if you misspell something
0.16: Added a web setting so you can tell the interpreter your computer is offline
0.17, January 13: Added a browse command and a browser setting, and made a few cosmetic changes
0.18, January 20: Added a copy command
0.18.01, January 24: Replaced the old copy routine with a faster one
0.18.02, January 25: Replaced the old copy routine with one that includes some error checking and is maybe just a weensy bit faster
0.19, February 5: Added an idle command to pause the script program for the specified number of seconds
0.20: Added a delete command
0.20.01, February 9: Minor changes to the open command
0.21: Added a default player setting and tightened up the code a bit
0.21.01, February 12: Added the ability to print to a file opened with the create command
0.22, February 13: Added a save command for the file opened with the create command
0.23, February 16: Added the beginnings of a find command, useless at the moment but hopefully useful later
0.24, February 17: Added a command to create a folder (make a directory)
0.25, February 19: Added a command to close a file opened with the create command
0.26, February 20: Added a command to rename a file
0.27, February 21: Added a statement allowing you to play a media file at a specific time
0.27.01, February 22: Added an option to the print command to print a message without moving to the next line
0.28, February 26: Added a command to move a file
0.28.01, February 27: Added a time option to the print command
0.28.02: Added the semicolon option to the time option
0.29: Added a stop command, because I could I suppose
0.29.01: Added a date option to the print command, complete with semicolon option
0.29.02, March 1: Added the date option to the print to command
0.29.03, March 2: Added the semicolon option when printing the date to a file with the print to command
0.29.04: Added the time option to the print to command, complete with semicolon option
0.29.05: Finally got all the semicolon options coded for the print to command
0.29.06: Added an option to print a blank line to a file
0.30, March 4: Added a command to delete all the files in a specified directory
0.31: Added a password generator, because why not, that's why
0.32, March 6: Added an option to load and run a menu script, I'm not even sure why
0.33: Added directory as a synonym for folder in the create command
0.34, March 7: Added a command to assign a value to a variable
0.35: Added a command to allow you perform a primitive addition on a variable and a constant and print the result
0.36, March 9: Added a command to create a new numeric variable and set its value to zero
0.36.01, March 10: Fixed the at statement so it can use 12-hour time with PM if preferred and added support for the browse, edit, and view commands
0.37, March 11: Added an if statement so the interpreter can execute program lines conditionally, primitive but basically functional
0.37.01, March 12: Discovered I'd forgotten to add the ability to assign the sum of a previous addition to a variable. Fixed now
0.38: Added an and operator for use in if statements
0.39: Added an or operator for use in if statements
0.39.01, March 16: Added an option to assign constant values to string variables and print them (I'm working on it)
0.39.02, March 17: Added the ability to assign the value from one string variable to another (assign a$ to b$ for example)
0.40, March 18: Added commands to allow for the use of subroutines
0.40.01: While preparing to add if statements to string variables I found the assign function was too messy to modify. Cleaned things up a little
0.41, March 20: Added a primitive loop option
0.42, March 22: Added a subtract command, very limited in scope at the moment
0.42.01: Updated the assign command so you can assign the result of a subtraction to a variable
0.43: Updated the count loop so you can count backward, but still only by ones
0.44, March 23: Added an option to generate and print a random number
0.44.01: Updated the subtract command to allow subtracting a constant from a constant
0.44.02, March 24: Updated the random number generator so you can (and have to) specify a maximum range for your random number
0.44.03, March 25: Updated the random number generator so it actually uses the minimum range set in the program line
0.44.04: Updated the subtract command to allow subtracting a variable from a variable
0.44.05: Tested to make sure you can subtract a variable from a constant. Works
0.45, March 26: Added a command to perform multiplication
0.46: Added a command to perform division
0.46.01, March 27: Altered the random number generator so it doesn't automatically print, you can assign to a variable and print that
0.47, March 28: Added a command to read a line from a text file previously opened with (surprise) the open command
0.48, March 30: Added a command to center a line of text, mostly because I could
0.48.01, April 2: Added the ability to use string variables in if statements
0.48.02: Added the and operator to string variables in if statements, probably needs more testing
0.49, April 7: Added another primitive conditional loop
0.49.01, April 11: Added the or operator to string variables in if statements
0.49.02: Found a bug that would cause the interpreter to hang if an and condition was not true in an if statement. Squashed, I think
0.49.03: Added limited variable to variable comparisons in if statements
0.49.04, May 2: Added the option for limited mixing of numeric and string variables in an and statement.
0.49.05: Expanded the variable type mixing when using the and operator
0.49.06, May 9: An if statement with an and operator but no print command would always evaluate as false. Fixed.
0.50, May 20: Added a system variable to hold the value returned by the find command. Still useless, but we're making progress
0.50.01, May 21: Tried to clean up the if statement routines a little. Not much progress, but maybe a little tighter
0.50.02, May 22: Tightened the code a bit, removing a redundant function
0.51, May 29: Added routines to allow parsing of a string using the find command and assigning it to a new string variable
0.51.01, May 30: Updated the "starting at" statement to allow both starting and ending points
0.51.02, June 2: Updated the find command to allow searching for strings in string variables. Assigning with "starting at" is limited
0.51.03: Rediscovered I'm an idiot, replaced overcomplicated (and wrong) line with simple (and correct) one, fixing "starting at" bug
0.51.04, June 3: A little code tightening
0.51.05: Updated the "starting at" statement so you can use a numeric variable for the ending point with the to keyword
0.51.06, June 5: If statement with and operator and a print statement including a $ character (e.g., print "$1.00") would fail. Fixed.
0.51.07: Same issue as above with the or operator. Should be fixed now.
0.52, June 6: Mostly cosmetic, changed "assign random" to "assign choice" and "print random number" to "print choice"
0.52.01: A little code tightening and some comment addening. :)
0.52.02, June 7: Added the ability to compare two string variables in an if statement
0.52.03, June 8: Squished a minor and incredibly annoying bug in the assign command. Took eight hours. Obsessed much? :)
0.52.04, June 9: An if statement with a print statement that included " or " (e.g., print "this or that") would fail. Fixed.
0.52.05: An if statement with the and operator can now handle variable-to-variable comparisons on both sides, to a limited degree
0.52.06: Updated the if statement/and operator to handle string variable to string variable comparisons on both sides
0.52.07, June 11: Updated the if statement/or operator to handle string comparisons on the left and numeric on the right
0.52.08: Updated if/or to handle numeric variable comparisons on the left and string on the right
0.52.09: Updated if/or to handle variable comparisons on both sides, first comparison false
0.53, June 12: Added the first extremely primitive inequality state to the if statement routines, numeric constants only
0.53.01: Installed and tested the inequality routines for string constants
0.53.02, June 13: Installed and tested the inequality routines for numeric variable comparisons
0.53.03: Installed and tested the inequality routines for string variable comparisons
0.53.04, June 14: Installed and tested the inequality routines with the and operator for numeric constants
0.53.05, June 15: Installed and tested the inequality routines with the and operator for string literals
0.53.06: Installed and tested the inequality routines with the and operator for numeric variables
0.53.07: Installed and tested the inequality routines with the and operator for string variables
0.53.08: Found a bug that was globbering up the variable's name and squished it (the bug)
0.53.09: Installed and tested the first version of the inequality routines with the or operator
0.53.10, June 21: A little code tightening and comment addening
0.53.11: In some instances, a variable comparison (e.g., a equals q) in an and statement would run as if true even if false. Fixed
0.53.12, June 22: More code tightening, more commenting
0.53.13: In some cases, a variable comparison (e.g., infinity$ equals finity$) in an or statement would run as true even if not. Fixed
0.53.14, June 26: And statements weren't parsing right and wouldn't work in some (odd) situations with inequalities. Fixed
0.53.15: I was "inspired" to look for parsing problems with and statements in the equality routines. Found 'em, fixed 'em
0.53.16: Found another bug in the parsing routines in the inequality section. Wasn't really harming anything, but it was messy. Fixed
0.53.17, June 29: Found a bug which would cause numerous inequality routines to always show as unequal, even if they were equal. Fixed
0.53.18: Finding a lot of bugs. This one was returning outdated values in some circumstances. Fixed
0.53.19, July 4: Finished rewriting the if routines, a little less messy and easier to maintain, so now I can add features easier
0.53.20, July 6: Added the first primitive routines to allow mixing of states (equality/inequality, at this point) in an and statement
0.53.21: At this point, I'm reasonably confident that mixing states in an and statement will work. Famous last words...
0.53.22, July 7: Mixing states in an or statement only works if the equality state is first. Working on it.
0.53.23: I'm grateful for typos today. This one led me to a bug where an and statement with mixed states would always evaluate as true. Fixed.
0.53.24, July 8: Found a bug in the if routines that hasn't caused any trouble yet, but might foul the variable's value under unusual conditions. Fixed
0.53.25: Slightly expanded the ability to mix states in an or statement where first state is equality and evaluates as false
0.53.26, July 9: Updated the or statements to allow mixing states where the first state is inequality and evaluates as true
0.53.27: I'm pretty sure I've got the coding finished for mixing states in and/or statements
0.53.28, July 10: Just some code tightening and improvements in the commenting
0.53.29, July 11: Some more code tightening and commenting
0.53.30: Found a huge bug that would cause some inequality statements to run as if true even when not. Fixed it with a mallet
0.54, July 12: Added the first simple greater than routines
0.54.01: The greater than state seems to be working in and statements, along with the mixing of all three states. Not or yet, though
0.54.02: I think I've got the or statements working with greater than, and mixing states seems to work too
0.54.03, July 14: Discovered I'd left some routines out of the and statements that could screw up mixing states. Fixed
0.55: The first simple less than routines added and tested
0.55.01, July 15: Discovered a bug that would screw up the parsing of an important string and cause the interpreter to crash. Fixed
0.55.02: The less than state should be working in and statements now, and mixing states in and statements with less than should work
0.55.03: As above, with or statements
0.55.04: Added minimally tested block if routines
0.55.05: Added indenting for the block if routines, so they're a little less messy
0.55.06, July 16: Just a little code tightening and comment addening
0.56, August 2: Added an option to turn on the bold attribute in text
0.57: Added an option to turn the bold attribute back off again :)
0.58: Added a color option, but only one color at the moment: Gray
0.59: Added black to the color options
0.60: Added dark gray. It's a freakin' rainbow! :)
0.60.01, August 5: Added another way to get bold black text using the color command (color bold black)
0.61: Added red
0.61.01: Added dark red
0.62, August 6: Added rust as a synonym for dark red
0.63, August 7: Added brown as a synonym for dark red
0.63.01, August 8: Added bold red
0.64, August 9: Added green
0.64.01, August 10: Added dark green
0.64.02, August 11: Added bold green
0.65, August 12: Added yellow
0.65.01: Added dark yellow
0.66, August 13: Added olive as a synonym for dark yellow
0.66.01: Added bold yellow
0.67, August 14: Added blue
0.67.01, August 15: Added dark blue
0.67.02: Added bold blue
0.68, August 16: Added magenta
0.69, August 17: Added bright magenta
0.69.01, August 18: Added bold magenta
0.70, August 19: Added purple as a synonym for magenta
0.70.01, August 20: Added bright purple as a synonym for bright magenta
0.70.02, August 21: Added bold purple as a synonym for bold magenta
0.71: Added cyan
0.71.01, August 22: Added dark cyan
0.71.02, August 23: Added bold cyan
0.72, August 24: Added white, actually a very light gray as nearly as I can tell
0.72.01, August 25: Added bold white, an even lighter shade of gray
0.73, August 26: Added an option for underlined text
0.74, August 27: Added an option for reverse video
0.75, August 28: Added an option for scored text
0.76, August 29: Added an option to change the background color to black.
0.76.01, August 30: Added red background
0.76.02, August 31: Added green background
0.76.03, September 1: Added yellow background
0.76.04, September 2: Added blue background
0.76.05, September 3: Added magenta background
0.76.06, September 4: Added purple background, same as magenta, just a synonym
0.76.07, September 5: Added cyan background
0.76.08, September 6: Added gray background
0.77, September 11: Added a locate command to move the cursor around on the screen
0.77.01, December 2: Found a bug that made one of my internal routines undependable. Should be fixed now
0.78: You can now use line numbers in your program, which are ignored
0.78.01: Line numbers in indented blocks, such as block if statements, wouldn't work right. Fixed
0.79: "Added" the apostrophe and the rem keyword for use as comments.