quasi
=> index.html code your own language
=> dictionary-of-programming-concepts.html dictionary-of-programming-concepts
=> build-your-own-freedom-lab.html build-your-own-freedom-lab
-> quasi
=> which-language-should-i-use.html which-language-should-i-use
list of entries
introduction
intro
i am working on a new programming language, named quasi, and i thought it would be a good idea to document it from the beginning. when i was first developing fig, it was on the back of another experimental language i had created, so it was ready for more action from the beginning.
now i have some experience, but i dont love javascript as much as python. its cool that quasi will run in the browser-- it is basically an "app" without external libraries. but apart from the fact that the wiki this website is created on already parses text, quasi is a pretty new effort in more ways than one.
like figplus, quasi is a compiler (code translator) implemented in an interpreted language, which compiles code-- then runs its own output immediately (figplus does this optionally, but by default it simply compiles to an output file like fig does.)
the idea for quasi is to be able to import (load) code from the import window to the editor, tinker with the code, and run it. similar to fig and figplus, you can add "demo" code to the import window so that you can host quasi with an example program already "loaded."
im not even working on the editor yet, while i add the first features to the compiler and parser. as of this intros writing you can create variables, set a variable with the date command, use cls and end, print and prints. the language isnt exciting, in terms of features. if you want to add more features to a new language quickly, i must recommend python over javascript.
back to list
quasi 0.1
early on, this will not be better than a changelog with commentary-- but ill try to explain a few things about each version.
0.1 has three commands: cls, end, print:
hello cls
there print end
hello print
end of course, should stop the program from running-- after the first print command. print has no way of getting a parameter, so it gets a 0 by default. "there" ought to be set to 0, then sent to the print command, but that doesnt really happen.
it took a while to figure out how to create an end command. i dont know a lot about variable scope in javascript, except that variables created in functions are typically local (thats what i want) and the i know that gui elements (and innerHTML) are pretty much global.
i decided to have span tags with nothing for "run" and <!-- --> for "dont run." the spans innerHTML is set to "" on run and each function call checks the contents-- i dont know how costly that is yet.
cls clears the screen before the program runs. it simply sets the innerHTML of the display window to "".
this version was more about getting started. i played with the interface a lot-- originally there were two separate windows for import [lit]/[lit] export, one on either side of the editor window. i combined them and doubled the width. there is little or no need to import and export at the same time.
the parser in 0.1 is a joke-- it isnt aware of quotes or comments, just keywords. when it finds an existing keyword, it adds the output to the compiled version.
i decided to make this project gpl3 licensed, since free software is doing so badly. i normally use permissive licensing, like ive used for this page. i was pretty happy when 0.1 was online. it doesnt do much, yet it works. you click the program editor window, it compiles the code on the left, it runs in the top "window" and clears the screen and "prints" 0. try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi01.html[url]
back to list
quasi 0.2
0.2 has three commands, unless you count # which is the syntax for a comment, and a slightly better parser:
hello # cls
there print end
hello print
cls is commented so it doesnt clear the screen when you run the code, but i decided to make it clear the display screen (regardless of cls) when it runs the program.
the parser is aware of comments as well as double quotes: when a # is encountered, it stops parsing the code on that line as anything but a comment. a # in quotes doesnt count.
0.2 still ignores variables, but it has some of the code needed to parse them.
one of the things 0.2 does is (before running the program) it displays the code that calls the native functions. it also shows the comments.
it displays the program, or most of the program that actually runs when you click the editor window, but the program it runs isnt enough to be a standalone javascript program. for now, it only runs in the context of this editor [lit]/[lit] translator application.
the code is compiled, but it needs a "runtime" that includes things like definitions of native functions. the goal is to have the capability of exporting-- depending on what the user wants-- either the output of the editor (so you can copy and paste the program to a file) or the compiled output for a standalone javascript program.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi02.html[url]
back to list
quasi 0.3
0.3 adds variable creation:
hello # cls
there print end
hello print there
users running 0.3 wont notice much difference between 0.2 and 0.3, except the program output is longer. when variables are encountered, they are actually set to 0 now; this is not reflected in the output yet; weve actually gotten farther from a standalone program in this version.
called functions that return a value, return a value; while called functions that dont return a value, return /undefined/. quasi knows this, and (as with fig and figplus) set a backup variable ("bu") to the value of the main variable before calling a function.
if the function sets the value, the main variable is affected-- this is by design. otherwise it returns undefined, signalling the need to reset the function to the backup value. basically, this leaves the main variable unaffected when the called function acts like a procedure (no return value) instead of a function.
the displayed output reflects the backup feature, even though it doesnt include the code that sets the variables initially. you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi03.html[url]
back to list
quasi 0.4
0.4 adds prints and date:
hello # cls
there date date prints
there print end
hello print there
we still dont have standalone javascript output but more work was added for that purpose; plus, the output now initialises variables. still missing from the output are the native functions.
the prints command is exactly like print except it stays on the same line, while the regular print command adds <br> to the line. the date command actually sets the main variable, so when print or prints is run, it actually prints the date.
the "date" command actually returns three items: the date, the time, the day of the week. the date gives Jan instead of 01, but the intended design is for it to be 01 instead.
starting a line with a variable sets it to 0, but only the first time it is used. unlike fig and figplus, after it has a value, it retains the value in subsequent lines (this is how fig and figplus treat arrays, but not single values.)
because it includes the date command, which includes seconds, this is the first version of quasi where you can click the editor window more than once and be able to tell that it is running the program repeatedly, once-per-click.
in anticipation of longer output, the display window now displays the compiled output after the program runs, rather than before. this does mean that if the program fails, the output wont display.
perhaps it would be a good idea to output directly to the export window as the program is compiled. it is a textarea window, so even if the program fails the export window could save the text in many instances.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi04.html[url]
back to list
quasi 0.5
0.5 adds get and title:
hello # cls
there date
ok get there print title end
hello print there
we are closer yet to standalone javascript output, the native functions are now included. the date command now works as intended, with numeric months from 01 to 12.
the title command sets the title to the contents of the main variable.
0.5 is the first version of quasi to accept and parse a parameter for a command. the method it uses is similar to figs, and this changes the way commands are added to the cmds dictionary.
the first command to use a parameter is *get*. it is used like this:
get variablename
where /variablename/ is the name of the variable you want to copy to the main variable. in the demo, *ok get there* copies the value of /there/ to the variable /ok/.
the design of quasi should allow for more than one parameter, but as it is coded, it will probably only allow one so far. it knows if it has zero parameters, it knows if it has 1, but if it has 2 or more the code probably wont work as-is yet.
fig commands have a fixed number of parameters (per command) and quasi likely will as well.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi05.html[url]
back to list
quasi 0.6
left is added:
hello # cls
there date left hello
ok get there print title end
hello print there
you can now change the program in the import [lit]/[lit] export window, and the changes will actually change what code runs.
the left command is probably only partly implemented, and since numeric constants arent yet, the only value left can accept is 0.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi06.html[url]
back to list
quasi 0.7
left now works like the design intends:
hello # cls
there date left 1 str left 5
ok get there print title end
hello print there
you can now add numeric values as parameters.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi07.html[url]
back to list
quasi 0.8
0.8 is the first version where commands can have more than 1 parameter:
hello date mid 1 1 str right 4 print
# cls
there get hello title end
hello print there
right works exactly like the left command, except it gets items or characters from the right of a string or array, instead of the left.
mid works like left and right except that it takes two parameters-- where to start and how many items or characters to get.
one of the greatest joys in coding is when you set out to do a task you expect to be tedious, only to find that you have it working sooner than expected. this version was that kind of joy.
i copied the conditional for parsing a parameter when the count is 1, set it to more than 1, and removed all the code except the part that appends mainvarplus (the variable that holds multiparameter code on its way to codeout.)
and it just worked-- i think this is because i tried to get this right in the previous two versions, but i was expecting it to need further tweaks before mid worked with two parameters. it worked well enough that i expect to need to fix something later on, which is possible, but it outputs the code that it compiles and runs-- it looks alright to me.
one thing that it doesnt do that id like to do is have a check in the parser for the validity of each token:
[lit]*[lit] valid variable names
[lit]*[lit] valid numeric constants
[lit]*[lit] valid command names
[lit]*[lit] valid string constants
if at least one of those checks is valid then the token is valid, and whether its position is valid can be checked later (if at all. it would help.)
quasi doesnt have this yet, since it works (but not quite as reliably) without it. you simply have to give it valid tokens.
now that we arent limited to 1 parameter, we can add a for loop.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi08.html[url]
back to list
quasi 0.9
0.9 is the first version with command pairs:
m = get -1 ; str ; left 1
p ; for 1 5 1
hello = date ;
now = get p ; prints ; get m ; prints
now = get hello ; mid 2 1 ; print
next
now ; title
the semicolons are entirely optional, as 0.9 lets you use = : ; for your convenience and clarity-- the parser will ignore them and treat them as spaces when they are outside of quotes and comments.
the main new features are for and next; these really go together into a single feature, but "next" will be used to close other multi-line commands also; for... next is simply the first.
i decided to keep the convention of "variable first" for the for loop, rather than make an exception for some commands. this is a fairly unconventional way of doing the for loop, syntactically speaking.
/for/ takes three parameters; /start/, /stop/ and /step/. the first is the number to start at, the second is the number to stop at, and the /step/ is how much to add each time. i would like to allow a negative step but that isnt implemented yet. decimal steps work if you put a 0 or other number before the decimal point and fractional value.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi09.html[url]
back to list
quasi 1.0
is the first version that allows indentation, but the parser ignores it:
m = get -1 ; str ; left 1
p ; for 1 5 1
hello = date ; mid 2 1
now = get "u tc" ; split now " "
now = join now "" ; prints
m ; prints
now = get hello ; print
next
now ; title
*it is also the first version that includes string constants*, and it adds the /split/ and /join/ commands.
the *split /v/ /bystring/* command splits a string, /v/, into an array by looking for instances of /bystring/ and using that as a separator.
the *join /v/ /bystring/* command does the opposite, joining array /v/ into a string with /bystring/ between each item.
you can use both to do "search and replace" like this:
p = get "do you like waffles? we like waffles."
p ; print
p = split p "waffles" ; join p "pancakes"
p ; print
this will output the following:
do you like waffles? we like waffles.
do you like pancakes? we like pancakes.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi10.html[url]
back to list
quasi 1.1
this version lets you define a function, but due to a bug it requires at least one parameter:
m = get -1 ; str ; left 1
p ; for 1 5 1
hello = date ; mid 2 1
now = get "u tc" ; split now " "
now = join now "" ; prints
m ; prints
now ; len ; print
next
now ; title
it also processes what quasi refers to as "misquotes", which are those unicode double quotes that arent the same character (unicode 8220 and 8221 instead of 34.) this allows quasi to parse strings when you have an ill-suited virtual keyboard, or are pasting code from some website that "helpfully" changes your quotes for you.
the *len* command returns the length of a string or array, in characters or items.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi11.html[url]
back to list
quasi 1.2
this version fixes the bug that requires parameters to have at least one parameter:
p ; for 1 5 1
hello = date ; mid 2 1
now = get "u tc" ; split now " "
now = join now "" ; prints
m get 45 chr prints
now ; get hello ; print
next
it is also the first version that lets you call user defined functions (defining them isnt that useful until you can call them) although they do not work properly in 1.2 and they are only partly fixed in 1.3.
like python functions, quasi functions are intended to have local scope. but other scope-related issues aside, quasi stores its variables and values in a dictionary (javascript object) called vars. vars is still readable (and seems writable) from within functions, which again is not the intended design. this particular issue with vars is fixed in 1.3.
another limitation in 1.2 fixed in 1.3 is that "special"ly parsed commands like for loops do not accept variables as parameters-- only constants.
basically, the complicated-to-implement features that are added in 1.2 do not work as they should, only in the most limited ways is it possible to demo those features. so i added one (hopefully) fully-functional command, *chr*, to make it possible to convert ascii or unicode codes to characters.
1.2 is the first version that features the return command, which helped expose these problems as it doesnt work as intended either. but versions 1.3 and 1.4 take the time to fix these.
though some new features dont work as intended, you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi12.html[url]
back to list
quasi 1.3
1.3 fixes most of the problems found in 1.2, and leaves a minor problem that is easy to work around-- that problem is fixed in version 1.4:
func function a b c
st get 2
p ; for 1 st 1
thisone get -50 prints
next
he get "" print
next
st get 10
p ; for 1 st 1
thisone get 55
ep func 1 2 3
ep get "hello" print
thisone print
hello = date ; mid 2 1
now = get "u tc" ; split now " "
now = join now "" ; prints
m get 45 chr prints
now ; get hello ; print
next
lets first draw your attention to these two lines:
ep func 1 2 3
ep get "hello" print
it should be possible to combine those lines, but we cant because calling func (while effort is made to preserve the value of the main variable) will disrupt the value of ep.
thats exactly what we want if func has a return value, but it doesnt, and thats the bug in this version. it gets fixed in 1.4.
1.3 doesnt add commands, it only fixes (a lot) of things wrong with 1.2, so lets talk about how it does that. it will also give us a hint how the fix in 1.4 works.
in 1.2, "special" (non-standardly-parsed) commands like *for* and *return* do not accept variables as parameters, only constants. this is not a desirable limitation. 1.3 fixes it by adding *petcvar(petc)* instead of just *petc* (a variable we use for adding parameters during parsing) and *petcvar()* performs similar processing used in other parts of the parser.
its worth noting that the parser is getting a bit silly and we would do well to refactor a bit. but that can be slow-going when you feel comfortable (lazy) with the fact that it works.
it is also discovered that our global variables in vars are accessible in the function scope. we want functions to have local scope like in python, so thats a problem worth fixing.
originally i created a stack for the parser that keeps track of whether we are in a function or not. any command that pairs with *next* (our command that is the equivalent of *}* in javascript or unindenting in python) such as for or function gets added to the stack.
when *next* is parsed, it removes the most recent item from the stack. thus, we know whether code being parsed is "in a function" or "not in a function."
the first thing that i did with that (for fun) was copy vars to bvars when a function is is first defined, then have the *return* command (which exits the function) copy bvars back to vars, as well as the *next* command do this based on whether it is a next command that completes the function definition or one that say, marks the boundary of a for loop or conditional.
copying vars to bvars for functions, setting vars to { } and then copying back on exist does work. apart from seeming a bit like a crazy way of doing it, it copies /every variable/ *twice* whenever a function is called. ordinarily i would implement this the easy way and fix it when i felt it became important, but i was feeling good about a better solution.
vars is processed as the string "vars." and i thought i would just create a conditional prefix "func" and have two dictionaries-- vars and funcvars. the *prefvars(parstack)* function creates the "func" prefix when it parsing a function, but returns "" when it is not. it took some work but its better than copying all the variables. funcvars is set to { } at the beginning of each function definition.
it also copies parameter values from the definition to the funcvars dictionary so that they are available to the function. thus func c d will set funcvars.c to the value of c and funcvars.d to the value of d when the function is defined.
user-defined functions behave as intended when they return a variable, the minor problem is when they arent meant to return a variable. you can try 1.3 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi13.html[url]
back to list
quasi 1.4
1.4 fixes the minor problem in 1.3 that affects only user-defined function calls that arent meant to return a value:
func function
st get 2
p ; for 1 st 1
thisone get -50 prints
next
he get "" print
next
st get 10
p ; for 1 st 1
thisone get 55
now = get "hello" func print
thisone print
hello = date ; mid 2 1
now = get "u tc" ; split now " "
now = join now "" ; prints
m get 45 chr prints
now ; get hello ; print
next
this line shows how far quasi has come:
now = get "hello" func print
that calls func and still prints "hello", due to the fact that func has no return command and is meant to run as a procedure-- not to affect the value of the main variable.
the backup variable bu, which preserves the main variable for the situations when a native function returns *undefined* was getting used by the functions. i thought bu would have local scope but it doesnt, so the fix was to create a variable called funcbu and have the parser handle it the same way it handles vars vs. funcvars.
as of 1.4, functions seem to be implemented per their intended design.
since 1.2 was the most recent version that added a command not related to functions, (chr) i thought id get around to making it so its possible to go back to the quasi website (and this one) from the "editor" window.
i had intended to create a run button, rather than simply have the user click the editor window. there is now a "**run program**" link-- as well as links to the websites. you can try 1.4 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi14.html[url]
back to list
quasi 1.5
1.5 features the same code example as the previous version; current modifications to quasi are to the interface, not the language, which isnt to say that quasi should have only 19 commands. the interface is simply what draws my attention right now.
the run program link is now replaced with a run program button, a show compiled javascript button-- now a separate feature-- as well as buttons for listing the available commands and license info (which displays on start.)
a cursor (unicode 9604) is placed in the import window. the "real" text cursor for the textarea is a blinking vertical bar and controlled by the keyboard or mobile device virtual keyboard. this unicode cursor is for the special program editor virtual keyboard, implemented as part of quasi.
when the program runs, or simply compiles, the cursor character is removed from the program so that it doesnt get parsed. this does not affect the contents of the import window.
you can try 1.5 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi15.html[url]
back to list
quasi 1.6
this features the same code example as the previous version; current modifications to quasi are to the interface.
there are two new buttons that dont belong in the design, get cursor and set cursor. their purpose was to test those functions while they were being written. getcursor() now returns values instead of outputting them to the top window, while the cursor position is set with the u, l, r, d buttons-- which ought to be labelled with arrows.
the run and show javascript buttons work as much as they did before... however, using the new buttons may cause these to stop working until the script is reloaded. some bug causes the regular features and the new features that move the cursor to step on each others toes; naturally a new goal is to fix that.
the new features are of course, useless by themselves. they are part of the effort to create a smart virtual keyboard for the import window. the buttons for the arrow keys are too large if we want to add qwerty keys.
you can try 1.6 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi16.html[url]
back to list
quasi 1.7
this features the same code example as the previous version; current modifications to quasi are to the interface.
there were two new buttons that didnt belong in the design, get cursor and set cursor, which 1.7 removes. the cursor position is set with the up, left, right, down buttons-- which now are labelled with arrows.
the run and show javascript buttons work as they did before the arrow keys were introduced; setcursor() was dropping the bottommost line of text.
as of 1.7, quasi features the ability to add letters and spaces. a goal is to be able to press a button to add commands, hence the keyboard.
you can try 1.7 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi17.html[url]
back to list
quasi 1.8
this features the same code example as the previous version; current modifications to quasi are to the interface.
although the arrow keys worked in 1.7, 1.8 is the first version where the left and right keys will also wrap to the previous or next line.
enter and del keys are added. skip up[lit]/[lit]skip down keys to skip paragraphs are added but the feature is not implemented; they map to regular up and down arrows. skip left[lit]/[lit]skip right keys to skip tokens are added but map to regular left and right.
now that left[lit]/[lit]right cursor wrap is implemented, along with del, implementing backspace could be as easy as calling cursorleft() and then checking that either getcursor()[0] is more than 1 or getcursor()[1] is more than one, and if so calling del. other than that, implementing backspace would possibly be a lot more tedious.
you can try 1.8 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi18.html[url]
back to list
quasi 1.9
this features the same code example as the previous version; current modifications to quasi are to the interface.
1.9 adds a backspace key and implements the code for the skip keys. it also fixes a bug where cursorleft() cycles on the first character of the first line, and where cursorright() skips the last character in each line.
backspace was implemented by calling cursorleft() and then checking that either getcursor()[0] is more than 1 or getcursor()[1] is more than one, and if so calling delkey().
you can try 1.9 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi19.html[url]
back to list
quasi 2.0
this features the same code example as the previous version; **but 2.0 has 5 new features.**
2.0 adds *asc*, *color* /v/, *colour* /v/, *instr* /v/ /s/, *mod* /v/ commands.
[lit]*[lit] asc - returns the unicode value from first character of main variable.
[lit]*[lit] color -1 to 15 - sets colour to cga 0 - cga 15; -1 is unspecified.
[lit]*[lit] colour -1 to 15 - works exactly like *color*.
[lit]*[lit] instr /variable/ - finds location of string /variable/ in main variable.
[lit]*[lit] mod /p/ - returns main variable /modulus p/.
functions are fun to implement. you can call native functions from udfs, but udfs called from udfs result in clobbering the funcvars namespace. there are two ways that might fix this, both involving higher-resolution information from (but not added to) the stack. the stack should have enough data to make this work. probably.
you can try 2.0 here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi20.html[url]
back to list
quasi 2.1
this features the same code example as the previous version; 2.1 tries to tweak a serious limitation from previous versions.
2.1 adds no commands or features. in 2.0 it was discovered that while you can call native functions from udfs, udfs called from udfs result in clobbering the funcvars namespace. an effort was made to create additional namespaces during parsing, but that would only help for functions that were defined within other functions, which wasnt ever intended to work (and that didnt work either.)
instead, 2.1 takes one step forward from not being able to call udfs from udfs, to only being able to call udfs from udfs within the same scope. this means that any values you alter from a udf called from a udf, will also change in the function that called it. **any scope functionality that worked in previous versions should still work in 2.1.**
single udf calls (rather than udfs from udfs or "nested udf calls") will still leave the main variable undisturbed. however, udfs called from udfs will return 0 unless another value is explicitly returned (with the **return** command.)
this is a disappointment, and its worth considering going back and implementing scope with a better understanding of javascript. at the very least, 2.1 should improve substantially on 2.0 and previous versions.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi21.html[url]
back to list
quasi 2.2
2.2 adds **try** and **except**. they can be used like this:
try
now get "hello" asc print
except
now get "hello" get 0
next
the **asc** feature calls **String.charCodeAt()**, which is not available in all browsers. calling it on a browser where it is unsupported will stop the program from running. quasi was going to add try... except, but it was added in this version due to this issue.
you can use try... except... next in other contexts, it is a general-purpose error catch feature.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi22.html[url]
back to list
quasi 2.3
2.3 adds plus v, minus v, divby v, times v:
text = get "hello from quasi"
textlen = get text len
count = for 1 textlen 1
now = get text mid count 1 asc mod 5
now ; plus 1 colour now
now = get text mid count 1 prints
next
the **asc** feature is not available in all browsers. **prior to version 2.3**, calling it on a browser where it is unsupported will stop the program from running. 2.2 adds try... except to quasi for general error catching. 2.3 adds this feature built-in to the asc command, so it will return **-1** when not supported (or when encountering any other error with the command.)
this should not change the way **asc** works on browsers where it already worked, unless they already hooked it with try... except in a program sometime the day before this 2.3 release (when 2.2 became the latest.)
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi23.html[url]
back to list
quasi 2.4
NOTE: catching up; this is not for 2.4, which you CAN try at the link to 2.4. adds **try** and **except**. they can be used like this:
text = get "hello from quasi"
textlen = get text | len
p = get "." asc plus 1
now ; iftrue p
now ; else
now = get "" | print
now = get " asc unavailable"
now ; print
next
now = get "" | print
now = get " " | prints
count = for(1, textlen, 1)
now = get text | mid count 1 | asc
now ; mod 5 | plus 1 | colour now
now = get text | mid count 1 | prints
next
the **asc** feature calls **String.charCodeAt()**, which is not available in all browsers. calling it on a browser where it is unsupported will stop the program from running. quasi was going to add try... except, but it was added in this version due to this issue.
you can use try... except... next in other contexts, it is a general-purpose error catch feature.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi24.html[url]
back to list
quasi 2.5
NOTE: catching up; this is not for 2.5, which you CAN try at the link to 2.5. adds **try** and **except**. they can be used like this:
text = get "hello from quasi"
textlen = get text | len
p = get "." asc
now ; ifequal p 46
now ; else
now = get "" | print
now = get " asc unavailable"
now ; print
next
now = get "" | print
now = get " " | prints
count = for(1, textlen, 1)
now = get text | mid count 1 | asc
now ; mod 5 | plus 1 | colour now
now = get text | mid count 1 | prints
next
the **asc** feature calls **String.charCodeAt()**, which is not available in all browsers. calling it on a browser where it is unsupported will stop the program from running. quasi was going to add try... except, but it was added in this version due to this issue.
you can use try... except... next in other contexts, it is a general-purpose error catch feature.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi25.html[url]
back to list
quasi 2.6
NOTE: catching up; this is not complete for 2.6, which you CAN try at the link to 2.6.
text = get "hello from quasi"
textlen = get text | len
p = get "." asc
now ; ifequal p 46
now ; else
now = get "" | print
now = get " asc unavailable"
now ; print
next
now = get "" | print
now = get " " | prints
count = for(1, textlen, 1)
now = get text | mid count 1 | asc
now ; mod 5 | plus 1 | colour now
now = get text | mid count 1 | prints
next
the **asc** feature was not available in all browsers. calling it on a browser where it is unsupported will stop the program from running. quasi was going to add try... except, but it was added in this version due to this issue.
you can use try... except... next in other contexts, it is a general-purpose error catch feature.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi26.html[url]
back to list
quasi 2.7
NOTE: catching up; this is not complete for 2.7, which you CAN try at the link to 2.7.
text = get "hello from quasi"
textlen = get text | len
p = get "." asc
now ; ifequal p 46
now ; else
now = get "" | print
now = get " asc unavailable"
now ; print
next
now = get "" | print
now = get " " | prints
count = for(1, textlen, 1)
now = get text | mid count 1 | asc
now ; mod 5 | plus 1 | colour now
now = get text | mid count 1 | prints
next
the **asc** feature was not available in all browsers. calling it on a browser where it is unsupported will stop the program from running. quasi was going to add try... except, but it was added in this version due to this issue.
you can use try... except... next in other contexts, it is a general-purpose error catch feature.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi27.html[url]
back to list
quasi 2.8
2.8 adds forin, break and sqr:
text = get "hello from quasi"
textlen = get text | len
p = get "." asc
now ; ifequal p 46
now ; else
now = get "" | print
now = get " asc unavailable"
now ; print
next
now = get "" | print
now = get " " | prints
count = for(1, textlen, 1)
now = get text | mid count 1 | asc
now ; mod 5 | plus 1 | colour now
now = get text | mid count 1 | prints
next
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi28.html[url]
back to list
quasi 2.9
2.9 moves homepage information to the info, adds keys for each command, as well as a routine that tries to ensure commands are not inserted in the middle of other text; if you are in the middle of a command and use a command key, it will skip to the next place outside that text and insert the command there.
print and prints now convert spaces in strings to ...this probably means we will want a **write** command for outputting raw html or something.
p = get "." asc
now ; ifequal p 46
now ; else
now = get "" | print
now = get " asc unavailable"
now ; print
next
now = get "" | print
text = forin " hello from quasi"
now = get text | asc
now ; mod 5 | plus 1 | colour now
now = get text | prints
next
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi29.html[url]
back to list
quasi 3.0
3.0 fixes the longstanding bug with asc; a weird syntax of the function it calls works with only firefox; it should work across most web browsers now.
*sgn is added*, [lit]**[lit] is replaced with Math.sqrt() to fix a major compatibility problem with 2.8 and 2.9, the help feature is extended, shh key stops live command help from bothering you if you dont like it:
now = get "" | print
text = forin " hello from quasi"
now = get text | asc | mod 5 | plus 1
now ; colour now
now = get text | prints
next
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi30.html[url]
back to list
quasi 3.1
3.1 adds *highlight* and *arrsort*.
now = get "" | print
text = forin " hello from quasi "
now = get text | asc | mod 5 | plus 1
now ; colour now | highlight 14
now = get text | prints
next
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi31.html[url]
back to list
quasi 3.2
NOTE: catching up; this is not complete for 3.2, which you CAN try at the link to 3.2.
now = get " " | print | prints
t = get "hello for quasi" | split t " "
t ; arrset 2 "from"
text = forin t
now = get text | asc | mod 5 | plus 1
now ; colour 15 | highlight now
now = get text | plus " " | prints
next
the **asc** feature was not available in all browsers. calling it on a browser where it is unsupported will stop the program from running. quasi was going to add try... except, but it was added in this version due to this issue.
you can use try... except... next in other contexts, it is a general-purpose error catch feature.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi32.html[url]
back to list
valentines card
this is the most complex program written in quasi so far. it creates a text array and prints a 2d design to it, which it then outputs:
#### license: creative commons cc0 1.0 (public domain)
#### http://creativecommons.org/publicdomain/zero/1.0/
arrprint function h y p s
mlen = arrget p y | len
# left, middle of line
le = get h | minus 1
proc = arrget p y | left le
modified = get "" | plus proc plus s
# right of line
sle = get s | len | minus 1 | plus h
le = arrget p y | len minus | sle
proc = arrget p y | right le
modified ; plus proc | left mlen
# change line and return array
p = arrset y modified
now ; return p
next
# create array
h get "."
add for 1 99 1
h plus "."
next
f split "p p" " "
# js arrays can be added to outside size
load for 1 10 1
f arrset load h
next
hprint function h y f t
sp randint 0 2 ifmore sp 0
text = get ".=" plus t plus "=."
now = arrprint h y f "..==.==.."
y ; plus 1
now = arrprint h y f "== = =="
y ; plus 1
now = arrprint h y f text
y ; plus 1
now = arrprint h y f "..= =.."
y ; plus 1
now = arrprint h y f "...= =..."
y ; plus 1
now = arrprint h y f "....=...."
sp else
text = get ".+" plus t plus "+."
now = arrprint h y f "..++.++.."
y ; plus 1
now = arrprint h y f "++ + ++"
y ; plus 1
now = arrprint h y f text
y ; plus 1
now = arrprint h y f "..+ +.."
y ; plus 1
now = arrprint h y f "...+ +..."
y ; plus 1
now = arrprint h y f "....+...."
next
next
colourprint function now
now str
eacht forin now
do = colour 15 ; highlight 13
eacht ifequal eacht "."
eacht get " "
do = highlight 15
next
eacht ifequal eacht "="
eacht get " "
do = highlight 12
next
eacht ifequal eacht "+"
eacht get " "
do = highlight 4
next
eacht prints
next
now get "" print
next
prepend function t p
now = get p | plus t | return now
next
heart get 9829 chr prepend heart "love"
vert randint 1 4
horiz randint 2 39
p hprint horiz vert f "happy"
vert plus 2
horiz plus 13
p hprint horiz vert f heart
vert minus 1
horiz plus 14
p hprint horiz vert f " day "
# output array
each forin f
now get each colourprint now
next
[img]vc.png[img]
back to list
quasi 3.3
the valentine demo can take about 5 seconds on a fast computer, 3.3 enables making it much faster:
now = get " " | print | prints
t = get "hello for quasi" | split t " "
t ; arrset 2 "from"
text = forin t
now = get text | asc | mod 5 | plus 1
now ; colour 15 | highlight now
now = get text | plus " " | prints
next
3.3 adds *arr*, *bufprint* and *bufprints*.
changing a single line in the valentine demo:
eacht prints
to:
eacht bufprints
lets the colourprint udf write to a variable instead of directly; then the normal print command updates it. if you change nothing it will work the same as before; this option lets you print much more efficiently.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi33.html[url]
back to list
quasi 3.4
adds *command*, *ltrim* and *rtrim*:
now = get " " | print | prints
t = get "hello for quasi" | split t " "
t ; arrset 2 "from"
text = forin t
now = get text | asc | mod 5 | plus 1
now ; colour 15 | highlight now
now = get text | plus " " | prints
next
it also fixes the help item for *forin*.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi34.html[url]
back to list
quasi 3.5
adds *reverse* and *not*:
now = get " " | print | prints
t = get "hello for quasi" | split t " "
t ; arrset 2 "from"
text = forin t
now = get text | asc | mod 5 | plus 1
now ; colour 15 | highlight now
now = get text | plus " " | prints
next
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi35.html[url]
back to list
quasi 3.6
adds *atn*, *hex* and *oct*.
now = get " " | print | prints
t = get " hello from quasi "
text = forin t
now = get text | asc | mod 5 | plus 1
now ; colour 15 | highlight now
now = get text | prints
next
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi36.html[url]
back to list
quasi 3.7
adds *topwr*:
now = get " " | print | prints
now = get " hello from quasi "
text = forin now
p = get text | asc | topwr 9 | mod 5
p ; plus 1 | colour 15 | highlight p
p = get text | prints
next
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi37.html[url]
back to list
quasi 3.8
makes *for* work with negative step, and fixes a bug with decimal step.:
now = get "" | print
now = get " hello from quasi "
rp for 6 4 -1
text = forin now
p = get text | asc | topwr rp | mod 5
p ; plus 1 | colour 15 | highlight p
p = get text | prints
next
p = get "" | print
next
python for loops allow negative step but not decimal, so fig solves this with a while loop. javascript allows decimal step but negative step requires changing the loop syntax, so quasi solves this by comparing instead to a function of the loop variable, stop value and step value:
for(vars.rp = 6; 0 < q_for_help(vars.rp, 4, -1); vars.rp += -1)
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi38.html[url]
back to list
quasi 3.9
adds *write* and *swap*:
now = get "" | print
now = get " hello from quasi "
rp for 6 4 -1
text = forin now
p = get text | asc | topwr rp | mod 5
p ; plus 1 | colour 15 | highlight p
p = get text | prints
next
p = get "" | print
next
default is still to clear screen on run, but you can now toggle that with the acls button.
print scrolls.
you can try it here: [url]https://freesoftwareresistance.neocities.org/quasi/quasi39.html[url]
back to list
[lit]happy coding![lit]