Pseudocode is a way of describing algorithms in a high-level language that computers didn't use to understand. Until now that is. This is an implementation that does just that. It understands some high level commands and translates them into GAS assembly(supports only linux syscalls).
IMPORTANT: A program ALWAYS finishes execution with an exit instruction. If it does not then it is automatically appended and the compiler assumes the exit code is 0. Note: in the syntax that follows:
[x] means x is optional
<x> means x is mandatory
- Parts that are not enclosed mean that they must be left just as they are
- This is case sensitive and so the token
if
will be treated differently thaniF
Syntax:
<type> <var_name>[= <value>], where type is one of the following:
int
for integer typesfile_stream
for file descriptorspointer
for arrays
The value can only be assigned to integer types.
This method only accepts one variable declared / line, see declare
The syntax for calling a function is:
<name> [arg1[,arg2[,arg3[,...]]]]
Every function call instruction ends with a new line character ('\n', '0xA')
Functions from the standard library can be found here.
Block instructions are blocks of code that are treated as a single instruction.
They begin with either {
(as they do in some programming languages) or with begin
.
They end with either }
or with end
.
Since both {
and begin
result in the same token at tokenization, they can be used interchangeably.The same can be said about }
and end
The decisions structures have the following syntax:
if(<condition>) then <instructions_true> [else <instructions_false>]
Here, instructions_true and/or instructions_false can be either one instruction or one block of instructions
Syntax:
while(<condition>) do <instructions>
The syntax for for
loops is as follows:
for <var> <- <initial_value>, <final_value>[,step] do <instructions>
Completely equivalent with:
<var><-<initial_value> while(<var><=<final_value>) do begin <instructions> <var> <- <var> + step end
Step has a default value of 1
.
Finishes execution with the code of the first argument Syntax:
exit [arg1]
arg1 defaults to 0 when not present.
The method of declaring multiple variables in a single line is as follows:
declare <var_1>[ = <value1>][, var2[ = <value2>][, var_3 [ = <value3>] [, ...]]] of type <type>
It is equivalent to declaring each variable (with or without the initial value) on its own line, but it is also considered a function by the compiler for the most part.
Syntax:
write <arg1>[,arg2[,arg3[,...]]]
Writes to the console the values of the arguments in order
Syntax:
read <identifier1>[,identifier2[,...]]
Reads from the console and puts the values in the variables with those identifiers
Syntax:
open (<file_name>, <file_access>[, file_permissions]) as file <file_descriptor>
The file descriptor is a variable of type file_stream which can be read from or written to.
The file name is the name of the file that should be opened.
The file access is one of the following:
- read only(short "ro") for files that should only be read from.
- write only(short "wo") for files that should only be written to.
The file permissions parameter is required only if the file access is write only, else it is ignored
The file permissions is a base-8 number (from 3 digits): 4 for read, 2 for write and 1 for execute. Do an or operation on these digits for to get the desired value for the permission.
More on file permissions here
Syntax:
close file <file_descriptor>
The file descriptor is the file_stream that was opened.
Syntax is the same as writing to the console, but has at the end to file <file_descriptor>
:
write <arg1>[,arg2[,arg3[,...]]] to file <file_descriptor>
Same as writing to a file, has at the end from file <file_descriptor>
read <identifier1>[,identifier2[,...]] from file <file_descriptor>
Syntax:
prime x, p
After the execution of this, p will have the value 1
if x is prime or 0
else.
p must be a variable.
Syntax:
perfect x, p
After the execution of this, p will have the value 1
if x is perfect or 0
else.
p must be a variable.
The declaration of an arrays is done like this:
declare <name> of type array[<element_type>]
An example:
declare A of type array\[int]
Syntax:
allocate <name>, <size>
or
static_allocate <name>, <size>
The parameter name is the name of the array. The parameter size is a constant number(expressions not allowed here).
Syntax:
dynamic_allocate <name>, <size>
The parameter name is the name of the array. The parameter size is a constant number(expressions not allowed here).
The array MUST be allocated before it is used.
Syntax:
dynamic_deallocate <name>
Deallocates previously allocated memory for the array.
Syntax
<name>[<ind>]
Where name is the name of the array and the ind represents the index of the element that is going to be used. ind can be either a constant number, a variable or an expression.
If it is in increasing order, just call the sort function:
sort <first>, <length>.
The parameters are:
- the parameter first represents the first byte of the array to be sorted: an example here is array+1 -> translates to the address of the element array[1].
- the parameter length represents the length of the array to be sorted - the count of elements.
reverse <m1>, <count>
This reverses the memory between m1 and m1+count*8.
Example: if we have an array A = (1, 2, 3, 7, 8, 9) and n is the size of the array(in this case 6), calling reverse A, n
will transform A into (9, 8, 7, 3, 2, 1)
This can be accomplished either by sorting and calling reverse on it or in the following way:
reverse_sort <first>, <length>
The parameters are the same as on normal sorting, but the elements end up in decreasing order.
Note that this method is faster than sorting normally and reversing.