|a
STRIL TUTORIAL
|b
|c
LICENSE
|d
|e
Stril is currently
proprietary software, written and owned by Jon-Egil Korsvold. It is available
for beta testing at your own risk. There is no warranty. Bug reports
and feedback should be sent to jonegilkorsvold@gmail.com. The license for
beta testing expires on January the first, 2020. By that time, Stril will
be made available under another, reasonably permissive license. I will
probably reserve the right to make money from it.
|f
|c
INSTALLATION
|d
|e
The Stril binary should be ready to run on any Linux system. It is not
necessary to reassemble it if your shell is /bin/sh and expects a
command string after the -c switch. If you need to change this setting,
you have to edit "arg1" and "arg2" near the end of stril.asm
and reassemble the binary. The current version of Stril will only
run on a Linux system. Copy stril to anywhere in your path:
cp stril /usr/local/bin/;chmod +x /usr/local/bin/stril. If you want to
use the scripts in the examples directory, you should follow the
same procedure. In addition, you need to edit the first line in each
script to reflect the new location of stril. Two of the scripts
(text2text.str and text2html.str) need to find resource files (txt.stl
and html.stl). The full path to these resource files should be
added to line 3 in text2text.str and text2html.str. It is not really necessary 
to install Stril. It is possible to run it where it is once you have
extracted the zip archive, but you need to make sure
that the binary and the scripts are executable. It would also be sensible
to add the location of stril and the scripts to your path whether you
install it or not.
|f
|c
STARTUP
|d
|e
To start Stril, you have to feed it a program file: stril prog.str (enter]. 
If the program file is executable, you can also do it like this: prog.str 
(enter). It will only work on a *nix system, and only if the first line in 
prog.str calls Stril properly: #!/path/to/stril. Stril has to be started from 
the command line. Some programming languages require a special startup
procedure. An Awk script has to start with BEGIN {. That is not the case with
Stril. You can start feeding it commands right away. When Stril starts, it
stores the script name in the variable |0. The rest of the command line is
stored in |1. These variables will be overwritten by the split commands. If
you are going to use the contents of |0 and |1 later, you need to save them to
variables in the range |5-|9 or |a-|z.
|f
|c
SYNTAX
|d
|e
In addition to the first line (#!/...), Stril programs consist of statements. 
Each statement is a command followed  by 
arguments. Statements are separated by comma or 
newline. Comma
can also be used as a dummy command with commands that
require an action. Less than (<) signifies a text option,
and "|'" is used as a marker for current.
All commands are single letter ones, written in lowercase. 
The same applies to variables. Variables in the range a-z and 0-9 are 
allowed, and each variable can have a length of up to 127 bytes (0-126). 
All variables have the same prefix, "|". No space is allowed between
the prefix and a variable. Some variables are more or less 
reserved. |0 holds the script name at startup, and |1 holds the rest of the
command line. |0, |1 and |2 are used by character, match, less and greater.
|3 is used to store the number of read bytes after each read-operation.
|4 is the variable that current initially points to.
|f
|e
Current
is an internal variable in Stril. It points to another
variable, a feature that is very useful in loops. 
The u-command decides which variable current points to.
It understands all the three
argument types that Stril supports. If you use the text option,
current is defined explicitly: u<a. Current now points to |a.
The two other forms of the u-command behave differently:
d|a<test,u<a,u. First we define |a as test. Then we point current
to |a. Finally, we use the u-command with nothing as a parameter.
It reads the variable that current points to, gets the first byte
and gets the name of the variable from that byte. After the final u
in the example, current points to |t (the first t in test). 
"d|a<test,u|a" would produce the same result.
|f
|e
Commands can be distinguished from 
variables since they do not  have any prefix. The syntax is fairly uniform.
Stril commands accept three types of arguments, notably nothing, a
variable or a text option. No command may have more than two arguments,
and all commands require at least one argument. There are only two
exceptions, the commands that store jump addresses (0-4) and the commands
that store bookmarks (5-9). They do not accept any arguments. These are the 
commands that require two arguments: a, c, d, f, g, l, m, n q, s, + and -. 
The first
argument has to be a variable.
|f
|e
Nothing usually means that current is to be used. The +-command adds
numbers and is a good example. Consider the following line:
"u<a,d|'<\\1,d|b<\\2,+|b,,". In plain language, we can say: Use |a as current,
define the contents of current as one, define |b as two, add current to |b. 
In the expression
"+|b", the absence of a second argument means that current is used. Instead
of "+|b", we could write "+|b|a". We just made sure that current points to |a.
Adding |a to |b is obviously the same as adding current to |b. This is the
third form of the +-command: "+|b<\\1". We just defined current as one, so the
result should be still be 3.
|f
|e
The commands +, -, c, h, n and y
(add, subtract, character, hurdle,
num2string and yawn) need
true numbers as input. \\1 means one 
while 1 means 49! The rest of the commands
interpret input as letters (1 means one)
except when backslash codes are
explicitly used, for example in a 
definition.
|f
|e
The mathematical operators (+, -, n, s) and the split
commands (m, l, g, c) double as control statements.
The same applies to attach (a),
read (r) and quantify (q). They all work the same way.
On success, they skip the next command. On failure,
they execute it.
|f
|c
ARRAYS
|d
|e
The variables a-z can be used as a very limited array. 
It is possible to loop through several variables: d|9<a,u|9,+|9<\\1,h<\\0,u|9.
First you define |9 as "a". Then you use it as current. Current now points to
the variable |a. Then you increment |9. It now contains "b". If you issue
the command "u|9", current will point to the variable |b. It is important to
make sure that the contents of a variable starts with a-z or 0-9 before you
try to use it as current.
|f
|c
PROCEDURES AND FUNCTIONS
|d
|e
In most programming languages, it is possible to define a function or a 
procedure and call it repeatedly from different locations in the program 
code. A return command or a break command will transport you back to 
a location immediately after the call to the function or procedure. This 
is not the case in Stril.
|f
|e
0, 1, 2, 3 or 4 defines the start point of a jump. The 
commands j<0-j<4 will jump to it. The command j<0 will jump to the point 
defined by 0 (or to the start of the program file if it is undefined). The 
command j<1 will jump to the point defined by 1 and so on. The return 
address is different, so jumps may be nested. You can put a 1-jump 
inside a 0-jump, but you cannot put a 0-jump inside a 0-jump. 
|f
|e
All jumps create an eternal loop, so you 
need to combine jumps with control statements: 
"d|a<\\2,u<s,1,r,h<\\0,w,+|a<\\1,h<\\0,l|a<\\3,h<\\0,j<1". 
Here |a is defined as 2, and |s is used as current, then we 
define a jump point (1), reads a line into |s (r) and prints the line with "w". 
We increment |a and jump to 1 if |a is still less than 3. It isn't, so we never
start looping. Read, add and less double as control statements. On failure,
they execute the next command, in this case h<\\0: Skip the rest of the
line if nothing was read, if the add-command failed and if |a isn't less than 3.
|f
|e
In Stril, it is not possible to define a function in a program file
and call it repeatedly from different places in the same file, but Stril
can have several open files and switch code source. It is possible to
define a function in a separate file and run it repeatedly from a different
code source. Jump points can be redefined, so it is also possible to
define the same functions several times in a program file. That is a simple
copy and paste operation in any modern text editor.
|f
|c
NUMBERS
|d
|e
Most programming languages can do a fair amount of math. Stril can 
count from 0 to 126, and that is it. No more is required to reference 
the ASCII range of characters and the positions in a 127 byte buffer. 
The add-command takes a non-empty variable as its first argument and
any of the three argument types in Stril as the second one. If the
result of the addition is greater than 126, the operation is interrupted
and the next command is executed. On success, it is skipped. The 
subtract-command (-) works the same way, but the operation is interrupted
if the result of the subtraction is less than 0. These commands
double as control statements. It is possible to use them to check
if a byte is inside the ASCII range: +|a<\\0,h<\\0,w|a. Skip the rest
of the line if the first byte of |a is greater than 126, print |a if
its value is 126 or less.
|f
|e
In addition to add and subtract, the s-command (string to number) and
the n-command (number to string), can be counted as mathematical
operators. The s-command allows you to define any number between
0 and 126 explicitly. The n-command allows you to show the numerical 
value of a letter in the ASCII range. The syntax is similar to the
add command and the subtract command. The s-command and the n-command
double as control statements and execute the next command only on
failure.
|f
|c
COMMENTS
|d
|e
You may, of course, comment your code. Stril expects the first letter
after a comma or a newline to be a command. If it isn't, Stril ignores
anything up to the next comma or newline. Any
uppercase letter can be used to start an inline comment. That is also
true for leading variables, for example |a. If you open the program 
file as an input file, you can read it and print it. The variables 
will then be replaced with their contents. This feature makes it 
possible to preprocess your code. A comment can also
span an entire line. If you want it to do so, you should start the line
with the h<\\0 command. Stril doesn't preparse your code. It is therefore
impossible to jump towards (but not to) the end of a file. Consequently, 
comments are parsed just like any other command. Excessive comments will 
slow down your scripts unless you place your comments after the exit 
command at the end of the script. If you do so, you do not have to use any 
comment initiators. Comments inside loops carry the greatest speed
penalty. Such comments should always be avoided!
|f
|c
FILES
|d
|e
Stril can act as a filter. In other words, it can read from standard 
input and write to standard output, and that is the default action, 
but Stril can also work with files.
We have already mentioned input files and program files. These terms may
be misleading. Stril knows about streams, files and slots. The standard
streams are always open and occupy the first three slots. Standard input
occupies slot 0, standard output occupies slot 1 and standard error
occupies slot 2. To open a file, you need a filename and a slot:
d|a<1.txt,f|a<3. This command will open 1.txt in slot 3. Slot 9 is the
last valid slot, but it is reserved for the main program file. If you want
to close a file, you will still use the file-command, but the first 
argument should
be empty: d|a<,f|a<3. This should close the file in slot 3, but it is not
strictly required. Open files are closed when Stril exits. If you open
a new file in an occupied slot, the old file is automatically closed
before the new file is opened. It is not possible to close the standard
streams or open files in slots 0 through 2. It is impossible to open
the standard streams in any of the slots in the range 3-9. All files are
opened in read-write and append mode. If they do not exist already,
they are created on the fly. All write operations occur at the end of the
files.
|f
|e
When a file is opened, it isn't clear whether it is an input file,
a program file or an output file. As a matter of fact, it can be
any of the above or even all of the above. If you issue the command
d|a<3,u<a,p (Store 3 in |a, use |a as current, p), you will use the
file in slot 3 as a program source. "d|a<3,p|a" will do the same. 
The third valid form of the same command is "p<3". The i-command
switches input, and the o-command switches output. They have the
same syntax as the p-command. It is quite possible to use the
same file for input and output. The technique is demonstrated in
"add-pim.str" in the examples directory. It is also possible to
use a program file as an output file since all write operations 
occur at the end of the file. You'll probably crash if you try
to use the same file as program source and input simultaneously. 
That would indeed be rather tricky.
|f
|e
Stril provides some ways to navigate files. Streams are unseekable,
so they can't be navigated. The t-command goes to the top of the
file in the chosen slot. The e-command goes to the end, and the b-command
goes backwards a single element. The definition of an element depends
on the value of the zone separator, but an element is at most a single
line. These commands have the same syntax as the p-command, the i-command
and the o-command. "e<3" jumps to the end of the file in slot 3.
|f
|e
It is possible to store a jump address in the current program file. That is
done with the commands 0-4. They do not take any arguments. The commands
5-9 work the same way, but they operate on the current input file. These
addresses are used by the jump command. It takes a single argument: d|a<3,u<a,j.
In this example, the argument is nothing, so we know that current is used.
Current points to |a, |a is defined as 3, jump to the address that was stored
when 3 was used as a command. "d|a<3,j|a" does the same as the example above.
The third form of the command is "j<3". When the argument of the jump command
contains a value between 0 and 4, we jump to a location in the current program
file. If we have switched program file since we issued the 3-command in the
examples above, we are likely to crash. If the argument of the j-command
contains a value between 5 and 9, we jump to a bookmark in the current
input file. A program file or an input file may be used for output
as well, but jumps have no effect on output. All write operations occur at
the end of the files.
|f
|c
VARIABLES
|d
|e
In Stril, variables can be populated in several ways. You can read into a variable 
with the r-command or the k-command, you can define it explicitly and you can attach
a variable or some text to it. Many commands, for example quantify,
also write directly to variables. 
|f
|e
The read-command has only two valid forms, "r" and "r|var", for example "r|a". 
The first version (r) reads into current, while the second one reads into a named
variable. The input command decides where read gets its data from: i<3,r. In this
case, the file in slot 3 is being read. Read stops when the zone separator is encountered,
at the first newline and when the buffer length is reached. It doesn't store trailing
newlines. In Stril, it is far easier to add a trailing newline than it is to remove one.
Read stores the number of bytes it has read in |3, and that includes trailing newlines.
In some cases, it is important to know if a newline has been read:
r|a,h<\\0,q|b|a,,g|3|b,h<\\0,w<\\a. This piece of code prints a newline if |3 is greater
than |b. |b contains the length of the string that was stored by read. Quantify is used
to get the length of that string (q|b|a) and store it in |b. Read doubles as a control
statement. When the end of the file is reached, it executes the next command. On success,
the next command is skipped. Read merely stores what it reads. It doesn't interpret or
convert backslash codes.
|f
|e
The k-command stores a single keypress. It has the same valid forms as the read command
(k, k|var). Like the r-command, it reads from current input, cfr. the i-command. 
The k-command doesn't echo the character it reads. A subsequent write operation
is necessary if it is to be shown: k|a,w|a. The k-command doesn't store the number
of bytes in |3 since it always reads a single byte. If it reads a newline, it is
stored like any other byte. The k-command is supposed to succeed, so it
doesn't double as a control statement either. It is meant to be used for 
user input.
|f
|e
The contents of a variable can also be defined explicitly with the d-command.
It takes two arguments. The first one has to be a variable. The second argument
can be nothing, a variable or some text. "d|a" defines |a equal to the variable
current points to. "d|'|a" copies the contents of |a and overwrites the
variable current points to. "d|a<Test" stores "Test" in |a and overwrites
any previous contents. If the second argument is empty, the contents of the first
variable are deleted. The text option of all commands interprets backslash codes,
but the define command also interprets and converts backslash sequences in variables.
If you want to avoid it, you should use the define command to delete a variable,
and then use the attach command on the empty variable. Backslash codes are 
explained in the command list. Another way to avoid interpretation of backslash 
codes is to escape them with double backslashes.
|f
|e
The a-command attaches content to a variable. It has the same syntax as the define
command. The a-command interprets backslash sequences, but only when the text option
is used: a|b<\\a. In this example, a trailing newline is attached. Since the a-command
adds to the length of an existing variable, there is a risk of buffer overflow. That
is why the a-command doubles as a control statement. On buffer overflow, the operation
is aborted and the next command is executed. On success, it is skipped.
|f
|c
MANIPULATION OF VARIABLES
|d
|e
No programming language would be complete without tools to manipulate
a variable once it has been populated. Stril doesn't contain a single
substitution command, but it contains several split commands. If
you want to delete a part of a string, you split it first. Then you 
print the parts you don't want to delete. If you want to change a part,
you use the d-command to change it.
|f
|e
Match requires two arguments, first the string and then the substring.
The first argument has to be a variable. The second argument can be any
of the three types supported by Stril. First we define the string:
d|a<abcdefgh. Then we define the substring: d|b<bc. Now we issue
a command: u<b,m|a. In this case, current is equivalent to |b and holds
the substring. We could also write "m|a|b" or "m|a<bc". All of the three
examples should produce the same result. |0 should contain "a", |1 should
contain "bc" and |2 should contain "defgh". The match always ends up in
|1. In this example, a match was found, and the split operation 
succeeded. On success, the next command is skipped. On failure it is
executed. Most errors are treated as an unsuccessful comparison:
d|a<b,d|b<cd,m|a|b,h<\\0,w<|0|1|2\\a. The substring is longer than the string,
so we know that the comparison is unsuccessful. The command "h<\\0" is
executed, and the rest of the line is discarded. The print statement is
never reached. When match is used to compare two bytes (when the first 
argument is a single byte), it doesn't try
to split the string, and the variables |0, |1 and |2 are left unchanged.
|f
|e
Greater and less are siblings of match. Greater checks if the first
argument contains a string that has the same length as the second
argument, but still is greater than the second argument. "b" has a
higher numerical value than "a", so "bc" should be greater than "ab".
Less checks if the first argument contains a string that is less than
the substring, but of the same length. "ab" should be less than "bc".
In all other respects, less and greater work the same way as match. 
The match always ends up in |1, and the match always has the same
length as the second argument. Let us try the same example as above:
d|a<abcdefgh,l|a<bc. In this case |0 should be empty. "ab" is less than "bc",
and "ab" is at the start of the string. |2 should contain the part
after the match (cdefgh). Let us try greater: d|a<abcdefgh,g|a<bc.
"cd" should be greater than "bc". |0 should contain "ab", |1 should
contain "cd" and |2 should contain "efgh". Note that these commands
always yield the first match. If |0 is empty, the match is at the
start of the string. If |2 is empty, the match is at the end of the
string.
|f
|e
The verity-command has the ability to change the behaviour of match,
less and greater. They behave as described above if the verity or 
truth level is 1. If it is 2, all comparisons are 
true: v<2,d|a<abcdefgh,d|b<def,m|a|b,h<\0,w|1. This command should
print "abc". It works as a simple split command. The string is spilt
at the length of the substring. The first part always has the same
length as the substring. The first part is stored in |1,
and the second part is stored in |2. It doesn't matter if we
write "m|a|b", "l|a|b" or "g|a|b" when the truth level is 2. The
verity-command accepts all the three argument types that Stril supports.
Instead of "v<2", we could write "d|a<2,u<a,v" or "d|a<2,v|a". The
result should be the same in all three cases. If the truth level is 0,
all matches are inverted: v<0,d|a<abcdefgh,d|b<abc,m|a|b,h<\\0,w|1.
In this example, "bcd" should be printed. It has the same length
as the substring (|b), and it is the first string of three letters
that doesn't contain the substring (|b). If we replace "m|a|b"
with "l|a|b", "abc" should be printed. After all, "abc" isn't less
than "abc". If we substitute "g|a|b" for "m|a|b", we should get
the same result since "abc" isn't greater than "abc".
The verity-command may not be very helpful as far as strings
are concerned since the
result can be hard to predict, but it is quite useful when numbers
are compared. In assembly language terms, the effects can be
described as follows: When the truth level is 1, match jumps if
equal ("je" in assembly language).When it is 0, match jumps
if not equal ("jne" in assembly language). When the truth level is
2, match simply jumps ("jmp" in assembly language). In the last case,
less and greater behave the same way as match. When the truth level
is 1, less jumps if less ("jl" in assembly language). When it is 0,
less jumps if not less ("jnl" or "jge" in assembly language). When
the truth level is 1, greater jumps if greater ("jg" in assembly
language). When it is 0, greater
jumps if not greater ("jng" or "jle" in assembly language).
|f
|e
The c-command splits strings in much the same way as the commands above,
but it chooses a character based on its place in a string. I takes
two arguments. The first one has to be a variable containing the position
of the character. 0 is the first position in the string. The q-command
can be used to get the last position in the string. As its second argument,
the c-command accepts any of the three argument types that Stril supports:
d|a<\\1,d|b<test,c|a|b. In this example, the second character in the variable
|b is chosen. |0 should contain "t", |1 should contain "e" and |2 should contain
"st". "Character" may be a misnomer in some cases. It is a byte that is chosen,
and some characters may span two bytes (the ones that are above the ASCII
range). The c-command doubles as a control statement. The next command
is executed if the first argument is less than 0 or greater than the length
of the second argument. On success, the next argument is skipped. "c|a|b"
could also be written as "c|a" if current points to |b or as "c|a<test".
|f
|c
PRINTING
|d
|e
Some programming languages contain several output commands. In Stril,
write is the only output command, but there are important differences within 
it. If you write "w" or "w|s", you hand it a single variable. It opens
that variable and expands the variables it finds within it. If you use the text
option, write reacts differently. It expands
the variables in the text, but it looks no further. If the variables in the text
contain variables of their own, those variables are left as they are. Their 
names are printed, but not their contents. The difference between the
text option and the other forms of the write-command can be exploited
to good effect. If you study "text2html.str" in the examples directory,
you will find out how this can be done. A trailing newline is only printed if it
is explicitly requested by the define command or the <text option of the 
write command. You can also get a trailing newline by adding it to a
variable with the a-command.
|f
|c
OTHER COMMANDS
|d
|e
The h-command is central to decision making in Stril. It accepts
all the three argument types that Stril understands. The h-command
hurdles n lines. N has to be a true number. "h<1" hurdles the
rest of the current line and the next 49 lines since "1" has the
ASCII value of 49. "h<\\1" hurdles the rest of the current line
and the next line. It can also be written "d|a<\\1,u<a,h" or
"d|b<\\1,h|b".
|f
|e
The q-command has only been covered in the passing.
It quantifies the second argument and stores its
length in the first argument. The second argument can
be any of the three types that Stril supports, but
the first argument has to be a variable: d|a<test,q|b|a.
|b should now contain the number 4 (\\4). The first
byte in a string occupies position 0. The output
of quantify should be reduced by one before it is used
as the first argument of the c-command to get the last
byte in a string: -|b<\\1,h<\\0,c|b|a. |1 should now contain "t"
(the last letter in the string). Quantify doubles as
a control statement. On success, the next command is
skipped. If the second argument is empty (has zero length),
the next command is executed.
|f
|e
The x-command is the system command in Stril. It allows
you to execute Linux commands. Their output cannot be
read directly into variables, but it is possible to
redirect the output to a temporary file and read the file
into variables. The x-command takes a single argument, and
it understands all the three argument types that Stril
supports. If you need variables in the command
string, you have to use define and attach to create the
argument: d|a<1.txt,d|b<2.txt,d|5<mv ,a|5|a,a|5<\\w,a|5|b,x|5.
In the example, the command string will look like this
for Stril and /bin/sh: mv 1.txt 2.txt. Variables are
normally only expanded by the write command. If you want
to execute a literal command, it is much simpler: x<ls -lh 1.txt.
|f
|e
The y-command yawns or pauses for a number of seconds.
It accepts any of the three argument types supported
by Stril: d|a<\\9,u<a,y. In this example, Stril should
pause for nine seconds. We could also write "d|a<\\9,y|a"
or "y<\\9".
|f
|e
The z-command sets the zone separator, an internal variable that
influences the behaviour of the r-command. Reading stops each 
time the zone separator is encountered. The zone separator is
stored unless it is a newline. Initially, it is. The zone
separator is a distant relative of the field separator in Awk.
The field separator splits a string, but the zone separator
terminates a read operation, making it possible to split a line
and read the parts into different variables. The zone separator
has to be a single byte, but backslash codes can be used to
produce that byte: z:<\\w. After this command, reading stops
each time a space is encountered AND each type a newline is 
encountered. The command above could also be written
"d|a<\\w,u<a,z" or "d|a<\\w,z|a".
|f
|c
EXIT
|d
|e
Stril exits when the end of the main program file is reached and if the main program
file is closed. If the main program file is closed, it will exit with exit code
-1, indicating an error: d|a<,f|a<9. If you want to force an exit indicating success,
"e<9" should do the trick. Some programming errors will cause a premature exit after 
an error message, while other programming errors are silently forgiven.
|f
|c
ERRORS
|d
|e
Stril stops at the first error it finds.
Line numbers are not given since Stril
has limited counting abilities, but the 
command where it occured is printed,
and so is the file slot it is found in. Stril
is able to catch most formal errors, but
it does not attempt to judge the quality 
of the program code. It would not be
sensible to define a jump point in the
main program file and try to jump to it
in a different file, but Stril
will not catch such an error.
|f
|e
Launch errors may occur at program
start-up. A launch error means that the
initial program file could not be opened
or that the command line argument was too 
long (more than 127 bytes). A failure by
the p-command to switch to a new main program
file, will also result in a launch error.
All files are created on the fly if they
do not exist already. If Stril fails to open
a file, the problem is likely to be caused 
by lack of privileges. If the main program file
is created on the fly, Stril will exit
immediately without an error message since
the main program file is empty.
|f
|e
A parameter error occurs when a parameter is
outside the legal bounds of a command. It
also occurs when an empty argument is 
used where content is required.
|f
|e
Syntax error is used for everything else,
mainly missing separators and illegal
variables.
|f
|c
EXAMPLES
|d
|e
The examples directory contains a lot of examples.
Many of them were originally written for previous
versions of Stril. They have been changed to work
with the current version, but in many cases, they
could benefit from a more complete rewriting. The 
examples in the directory are uncommented. I have 
therefore enclosed a few commented examples below.
|f
|e
1,r,h<\\0,w<|'\\a,j<1. In plain language: Store the address.
Read a line from standard input and store it in the
variable current points to, initially |4. Skip the
rest of the line if nothing was read. Write the line
and add a newline. Jump back to the stored address and
do it all again. This piece of code emulates cat and expects
to be fed a file through a pipe or redirection.
|f
|e
Reset is a tiny program. It resets your terminal. On
my system, it is 18 kilobytes in size. This is the source
code of reset in Stril: w<\\rc. Reset is 6 bytes in Stril.
|f
If you write the infamous "Hello, world!" program in
assembly, the source code should take some 300 bytes.
This is the source code in Stril: w<Hello\\x world!\a.
The \\x becomes a comma. A comma may not be used directly
in a text option. It would end the text option and cause
Stril to expect a new command.
|c
LIMITATIONS
|d
|e
Stril is fairly slow. In most cases, the lack of speed
won't be a problem on a modern computer, but Stril
shouldn't be used for large programs or programs
where speed is really important. Stril cannot be used
for mathematics. It handles strings and texts
well enough, but its size prevents it from performing
some text processing tasks. Sorting requires large arrays,
and they are not available in Stril.
|f
