Manual: Difference between revisions
Line 53: | Line 53: | ||
To simulate classic multivalue basic's "gosub/return" in Exodus, you can add additional subroutines and functions above or below your "main" function. | To simulate classic multivalue basic's "gosub/return" in Exodus, you can add additional subroutines and functions above or below your "main" function. | ||
==== Simple Example ==== | ==== Simple Example ==== |
Revision as of 16:55, 25 October 2010
Hello World
After installing Exodus, you can develop Exodus programs from any operating system command line.
Any programs you develop are stored in the same directory as their source code. They are also copied to an folder in your home directory - Exodus on Windows and bin or lib on other operating systems. These folders are added to the end of your path by the Exodus installer. This means that, as long as you are logged in as the developing user, and there is no similarly named program early on in your path (e.g. operating system commands) you can use any developed program from any command line. To make any programs available to other users you must arrange for the programs to be copied to some directory on their path.
Edit
Use Exodus's all-in-one editor+compiler+cataloger 'edic'
edic hello1
edic will give you a skeleton Exodus program which you can develop as you wish.
There must be one and only one "function main()" statement and this is run when the program is started.
By convention, main() must return an integer value. If desired, this can be used to indicate "success" with zero or "failure" with some error number.
The programinit() and programexit() lines are required and provide all the standard multivalue system variables using a simple C++ class macro.
#include <exodus/program.h> programinit() function main() { printl("hello1 says 'Hello World!'"); return 0; } programexit()
Save and compile
Make any changes you want in to the skeleton and save it.
NB If you just want to try out the skeleton program as is then you must still explicitly save it otherwise if you just exit without saving, edic will assume you have changed your mind and that no longer want the hello1 program, and will cancel. For the default editor (nano), explicit save is usually Ctrl+O.
On saving hello1, edic will compile and catalog it.
Run
To run/open/execute your new hello1 program just type its name.
hello1
and the output is ...
hello1 says 'Hello World!'
Local subroutines
To simulate classic multivalue basic's "gosub/return" in Exodus, you can add additional subroutines and functions above or below your "main" function.
Simple Example
Here is hello1 modified to call a subroutine that says something.
The word "gosub" is just there for classical clarity. It could be omitted. It could also be replaced by "call" which is also a throwaway word. While gosub and call are interchangeable, if you are going to use them at all, it is probably a good idea to use "gosub funcx()" to indicate internal subroutines and "call funcx()" to indicate external subroutines.
All functions/subroutines must fall between the programinit() and programexit() lines, and cannot be nested otherwise compilation will fail.
#include <exodus/program.h> programinit() function main() { printl("hello1 says 'Hello World!'"); gosub subr1(); return 0; } subroutine subr1() { printl("subr1 says 'Hello'"); } programexit()
output:
hello1 says 'Hello World!' subr1 says 'Hello'
Functions versus Subroutines
Functions can be used anywhere an expression would be used whereas subroutines can only be used as statements.
The same principle applies to both internal and external subroutines/functions.
Both subroutines and functions can return information in any of their "out" or "io" arguments.
The word "call" or "gosub" before the use of a function or subroutine is optional and can be omitted.
Functions
Functions return a value so the calling program can use a function anywhere an expression is required, for example on the right hand side of an assignment.
var yy=funcx(xx);
Even though a function returns a value, it can be ignored.
call funcx(xx); gosub funcx(xx); funcx(xx);
Subroutines
Subroutines do not return a value so they can only be used as statements.
call subrx(xx); gosub subrx(xx); subrx(xx); var yy=subrx(xx); //will not compile
Subroutine and Function Parameters (Arguments)
Parameter names must be prefixed by "in", "out" or "io" to indicate if they are inbound, outbound or both.
Inbound parameters (prefixed with "in") cannot be amended within the function and the compiler will enforce this. This provides a guarantee to the programmer calling the subroutine or functions that their inbound parameters will not be modified by calling the function. Inbound parameters may be provided by the calling program either as a variable or as raw data like "xyz" or 123 etc.
In/Outbound parameters ("io") must be provided by the calling program in the form of a variable and not raw data. The function can both read and write into these parameters.
Outbound parameters ("out") are indicate to the programmer using the function how it works. Outbound parameters are actually no different from in/outbound parameters. There is no simple way to enforce "write only" parameters using the underlying C++ language.
All the usual C++ parameters are also allowed for example "int arg1" or "const char* arg1" etc. This might be useful in special cases or where performance is critical.
External functions and subroutines
Editing and compiling external subroutines and functions in Exodus is identical to normal programs except:
- the word "program" becomes "library" so we have "library.h", "libraryinit()" and "libraryexit()".
- function main can have any parameters you like, for example: "function main(in arg1, in arg2, out arg3)
NB The name of the function internally must be main and NOT the name of the function so we still have "function main(...)" but this time it can have parameter names.
Example
edic func1
#include <exodus/library.h> libraryinit() function main(in arg1, in arg2, out arg3) { printl("func1 says 'Hello World!'"); return 0; } libraryexit()
Example Using External
You just need to insert an #include "func1"
edic prog1
#include <exodus/program.h> programinit() #include "func1.h" function main() { printl("prog1 says 'Hello World!'"); return 0; } programexit()