Basic I/O
Contents
PAL Tutorial - Basic I/O
In release 0.6.x, only the PROSE Assembly Language (PAL) is available, and then only a subset of those instructions. So be aware, it's very low-level programming at this time. To learn more about the PROSE Programming Language, visit http://prose.sourceforge.net.
It is suggested you begin with the following articles before attempting this tutorial.
- Introduction to PROSE
- Quick start guide
- Running your first program
- Short tour of PAL
A full list of available tutorials for the PROSE Assembly Language can be found on the tutorials index page.
This tutorial discusses basic I/O features.
The basics
Basic input/output (I/O) can be achieved in the PROSE Assembly Language by reading and writing to a special object in the nexus called .prose.io
. This object has a number of attributes:
-
psStreamIn
to read from standard input -
psStreamOut
to write to standard output -
psStreamError
to write to standard error -
psStreamDebug
to write to standard debug -
psByteStream
to read binary data from standard input
-
The standard input stream will take user input unless a file has been redirected into the input when the PROSE engine is executed. The standard output stream will send buffered output to the display unless the output has been redirected to a file. The standard error stream will send unbuffered output to the display unless the error channel has been redirected to a file. The standard debug stream at this time is the same as the error stream, although in future releases of PROSE this will change to be a dedicated channel for debug information.
Assembling and executing the obj/dump ![.prose.io]
instruction will show the structure of the .prose.io
object. Here is a sample assembly file:
._init obj/dump ![.prose.io]
Once assembled and executed the output of the above example is:
.prose.io:objectClass=psContainer .prose.io:objectClass=top .prose.io:objectClass=psIOStream .prose.io:pn=[io] .prose.io:psStreamIn=[] .prose.io:psStreamOut=[] .prose.io:psStreamError=[] .prose.io:psStreamDebug=[] .prose.io:psByteStream=[] prose: ERROR: no main() function found, nothing to do
Here you can see that the .prose.io
object has three classes (top
, psContainer
and psIOStream
) and six attributes (pn
, psStreamIn
, psStreamOut
, psStreamError
, psStreamDebug
and psByteStream
).
To read from standard input, use the attr/copy
or attr/direct
instructions, as if copying the value of the psStreamIn
attribute. This will read one line at a time and will strip carriage returns (ASCII 12). Alternatively using the psByteStream
attribute will read all input until exhausted ignoring newlines, and will preserve carriage returns.
To write to any of the output channels, use the attr/mod
or attr/direct
instructions, as if modifying the value of the output attribute.
The following example, once assembled and executed, sends the text </code>Hello, world!</code> to the standard output. Note that, as in C, newlines must be explicitly requested using the escape code </code>\n</code>.
._init func/def [main], &[.main] local/rtn .main attr/mod ![.prose.io], [psStreamOut], [Hello, world!\n] func/rtn
Copying input to output
To write a program that copies standard input and sends it to standard output requires the use of the attr/direct
instruction. This instruction is used for copying an attribute value from one object to another. Once the input is exhausted the error .prose.error.sys.AttributeEmpty
will be generated, so it will be necessary to catch this:
% % Reads data from stdin and writes to stdout % ._init func/def [main], &[.main] local/rtn .main error/jmp &[.trap], ![.prose.error.sys.AttributeEmpty]
For efficiency, we should then pre-load registers with pointers to the .prose.io
object as well as the psStreamIn
and psStreamOut
attribute definitions before we enter a read/write loop. We don't want to lookup this information in each iteration of the loop, because it is an unnecessary overhead:
reg/load P0, ![.prose.io] attr/load P1, [psStreamIn], P2, [psStreamOut]
Now we enter a loop copying the attribute value identified by register P1
(psStreamIn
) to the attribute identified by P2
(psStreamOut
):
.loop attr/direct P0, P2, P0, P1 local/jmp &[.loop]
This would appear to be an infinite loop, but once input is exhausted the AttributeEmpty
error is thrown which triggers our error trap:
.trap error/clr func/rtn
Once assembled, try directing a file into the standard input and you should see the contents of that file sent to standard output. In the example below the source code was saved as cat.pal
, and the assembled bytecode is called cat.pro
:
$ prose cat < /etc/passwd
Resources from this tutorial
Further reading
See the other tutorials available for the PROSE Assembly Language on the tutorials index page.
PROSE is released with detailed manual pages that describe how PAL operates, and how each instruction is used. These manual pages can be read using the man
command, for example man pal_intro
or man pal_commands
, or from the project links on the main page of this wiki.