|
|
(142 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
| === Hello World ===
| |
|
| |
| After installing Exodus, you can develop Exodus programs from any operating system command line.
| |
|
| |
| This introduction concentrates on simple development from the command line because it is common to all platforms.
| |
|
| |
| ==== 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.
| |
|
| |
| <pre>
| |
| #include <exodus/program.h>
| |
|
| |
| programinit()
| |
|
| |
| function main() {
| |
| printl("hello1 says 'Hello World!'");
| |
| return 0;
| |
| }
| |
|
| |
| programexit()
| |
| </pre>
| |
|
| |
| ==== Save and compile ====
| |
|
| |
| Make any changes you fancy to the skeleton and save it.
| |
|
| |
| NB Even if you just want to try out the skeleton program exactly as it is without any changes, you must still explicitly save it - otherwise, if you just exit without saving, edic will assume you didn't want a hello1 program, and will cancel. For the default editor (nano), explicit save is usually Ctrl+O.
| |
|
| |
| Upon 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!'
| |
|
| |
| === Deployment of Compiled Programs ===
| |
|
| |
| All programs you develop with Exodus's edic or compile commands are stored in the same directory as their source code. They are also copied to a folder in your home directory. This folder is called "Exodus" on Windows and bin or lib on other operating systems.
| |
|
| |
| On Windows, the user who installs Exodus can run any program they develop in Exodus by typing its name at any command prompt. It does not matter what the current working directory is because the Exodus installer permanently adds the Exodus home program directory to the PATH of the user who installs it.
| |
|
| |
| Users other than the user who installed Exodus on Windows, and all users on Linux, Mac or other operating systems, must type "exodus" at a command prompt (or open an Exodus console from an application menu) before they can run any program they develop in Exodus. Once they have done that, it does not matter what the current working directory is because the "exodus" program temporarily adds the Exodus home program directory to the users PATH.
| |
|
| |
| On all operating systems, if there is a similarly named program earlier on in your path (e.g. operating system commands) then you will not be able to run your program because in all cases Exodus adds its path (to your home program directory) to the end of your existing path - not the beginning.
| |
|
| |
| To make any developed Exodus programs available to other users you must arrange for them to be copied to some directory on their path.
| |
|
| |
| === Local subroutines ===
| |
|
| |
| To simulate classic multivalue basic's "gosub/return" in Exodus, you can add additional subroutines and functions between the programinit() and programexit() lines.
| |
|
| |
| You can add them either above or below the "main" function. There is no rule that functions must appear before or above the code that calls them.
| |
|
| |
| Subroutines and functions cannot be nested otherwise compilation will fail. In other words, no function or subroutine can be contain within the body of another.
| |
|
| |
| ==== 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.
| |
|
| |
| <pre>
| |
| #include <exodus/program.h>
| |
|
| |
| programinit()
| |
|
| |
| function main() {
| |
| printl("hello1 says 'Hello World!'");
| |
|
| |
| gosub subr1();
| |
|
| |
| return 0;
| |
| }
| |
|
| |
| subroutine subr1() {
| |
| printl("subr1 says 'Hello'");
| |
| }
| |
|
| |
| programexit()
| |
| </pre>
| |
|
| |
| output:
| |
|
| |
| hello1 says 'Hello World!'
| |
| subr1 says 'Hello'
| |
|
| |
| === 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") indicate to the programmer using the function how it works. However, outbound parameters do not actually prevent them being used to provide data to the subroutine or function and are therefore no different from in/outbound parameters. There is no simple way to enforce "write only" parameters using the underlying C++ language.
| |
|
| |
| For special cases, or where performance is critical, the usual C++ parameters are also allowed for example "int arg1" or "const char* arg2" etc.
| |
|
| |
| === 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 eg "subroutine main(in instr1, out outstr2)".
| |
|
| |
| External functions and subroutines are implemented as dll or so files and are only loaded into memory the first time that they are used. A missing function or subroutine so or dll file will not cause any failure unless and until it is first used.
| |
|
| |
| ==== Example func1 ====
| |
|
| |
| edic func1
| |
|
| |
| <pre>
| |
| #include <exodus/library.h>
| |
|
| |
| libraryinit()
| |
|
| |
| function main(in arg1, out arg2) {
| |
| printl("func1 says 'Hello World!'");
| |
| arg2="arg1 was "^arg1;
| |
| return 999;
| |
| }
| |
|
| |
| libraryexit()
| |
| </pre>
| |
|
| |
| ==== Example prog1 using func1 ====
| |
|
| |
| Compiling func1 created a func1.h file that is required to "glue" func1 into any program that wants to use func1.
| |
|
| |
| To use func1 in any program or external subroutine or function, you need to insert an #include "func1.h" somewhere between "programinit()" and "programexit()" - and not within the body of any function or subroutine.
| |
|
| |
| edic prog1
| |
|
| |
| <pre>
| |
| #include <exodus/program.h>
| |
|
| |
| programinit()
| |
|
| |
| //you must "declare" that we want to use func1
| |
| #include "func1.h"
| |
|
| |
| function main() {
| |
| printl("prog1 says 'Hello World!'");
| |
|
| |
| //we print what func1 returns, and also what func1 returns in arg2
| |
| var arg2;
| |
| printl( func1("myarg1",arg2) );
| |
| printl(arg2);
| |
|
| |
| return 0;
| |
| }
| |
|
| |
| programexit()
| |
| </pre>
| |
|
| |
| run prog1
| |
|
| |
| prog1
| |
|
| |
| output:
| |
|
| |
| prog1 says 'Hello World!'
| |
| func1 says 'Hello World!'
| |
| 999
| |
| arg1 was myarg1
| |
|
| |
| === 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, the value it returns 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
| |
|
| |
| === Differences between Exodus's Internal Subroutines and Functions and those of classic multivalue basic ===
| |
|
| |
| Exodus's internal subroutines and functions are very different from and arguably much better than classic multivalue internal subroutines. They are very similar to external subroutines and functions except they also have access to the global variables of the main program.
| |
|
| |
| Exodus Internal Subroutines and Functions:
| |
|
| |
| #can be called with parameters e.g. gosub funcx(xx,yy,zz)
| |
| #only have access to the main programs global variables - this eliminates a major category of multivalue bugs
| |
| #functions (not subroutines) can return a result e.g. abc=funcx(xx,yy,zz)
| |
|
| |
| They only have one entry point whereas in classic multivalue basic you can jump into the middle of any internal subroutine. To simulate this type of coding in in Exodus you must create nested subroutines or functions.
| |
|
| |
| The old RETURN TO XYZ syntax is not supported at all and such code must be redesigned to eliminate it.
| |
|
| |
| ==== Moving external subroutines and functions to internal ====
| |
|
| |
| Exodus allows many classic multivalue basic external subroutines and functions to be reimplemented as internal subroutines and functions. This means that you can now, where appropriate, keep all source code related to one and only one program in a single file. This is a major improvement in source code management.
| |
|
| |
| In classic multivalue basic, if you wanted to implement some function to be used in expressions you were forced to implement it as an external function requiring a separate source code file.
| |
|
| |
| In classic multivalue basic if you wanted to call a subroutine with parameters, or you wanted to be sure that a subroutine would not accidentally overwrite main program variables, you were forced to implement it as an external subroutine or function.
| |
|
| |
| In Exodus the above situations no longer force you to have separate compilation and source files. However you can still make subroutines and functions external exactly as before where that is the best strategy, for example:
| |
|
| |
| #to provide some common feature to more than one program
| |
| #to avoid having to recompile the whole of a large program when you just change part of it
| |
| #where there is some benefit in not loading all the parts of a program into memory immediately on start-up.
| |
|
| |
| NB Exodus internal subroutines and functions have access to the global variables of the main program so you might want them to make them external to make sure that there is no risk that they touch any global variable.
| |
|
| |
| === Operators ===
| |
|
| |
|
| |
| ==== Operator Precedence ====
| |
|
| |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| !priority!!operators!!associativity
| |
| |-
| |
| |1||X++ X-- () . || right
| |
| |-
| |
| |2|| ++X --X + - not|| left
| |
| |-
| |
| |3||* / % || right
| |
| |-
| |
| |4|| + - || right
| |
| |-
| |
| |5|| lt le ge gt || right
| |
| |-
| |
| |6||eq ne || right
| |
| |-
| |
| |7||^ (concatenate) || right
| |
| |-
| |
| |8||and || right
| |
| |-
| |
| |9||or || right
| |
| |-
| |
| |10||= += -= *= /= %= ^= || left
| |
| |}
| |
|
| |
| ==== Logical and comparative operators ====
| |
|
| |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| !word!!symbolic<br>alternative||example
| |
| |-
| |
| |and||&&||if (aa and bb)
| |
| |-
| |
| |or||||||if (aa or bb)
| |
| |-
| |
| |not||!||if (not aa)
| |
| |-
| |
| |eq||==||if (aa eq bb)
| |
| |-
| |
| |ne||!=||if (aa ne bb)
| |
| |-
| |
| |gt||>||if (aa gt bb)
| |
| |-
| |
| |lt||<||if (aa lt bb)
| |
| |-
| |
| |le||<=||if (aa le bb)
| |
| |-
| |
| |ge||>=||if (aa ge bb)
| |
| |}
| |
|
| |
| ==== and/or short circuiting ====
| |
|
| |
| If the left hand side of an "or" operator is true then the right hand side is not even evaluated. Likewise if the left hand side of an "and" operator is false then the right hand side is not even evaluated.
| |
|
| |
| This provides a major programming convenience/performance advantage over classic multivalue basic.
| |
|
| |
| if (aa eq 1 and bb eq 1) // if aa is not 1 then bb is not checked and could even be unassigned.
| |
| if (aa eq 1 or bb eq 1) // if aa is 1 then bb is not checked and could even be unassigned.
| |
|
| |
| === ICONV/OCONV PATTERNS === | | === ICONV/OCONV PATTERNS === |
|
| |
|
| |
|
| ==== Decimal (MD/MC) ==== | | ==== Decimal (MD/MC) ==== |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| !input!!conversion!!output | | !input!!conversion (string)!!output |
| |- | | |- |
| |1234||MD2||12.34 | | |1234||MD2||12.34 |
Line 336: |
Line 28: |
| |-1234||MD20-||1234.00- | | |-1234||MD20-||1234.00- |
| |} | | |} |
|
| |
|
| |
|
| ==== Date (D) ==== | | ==== Date (D) ==== |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| !input!!conversion!!output | | !input!!conversion (string)!!output |
| |- | | |- |
| |12345||D||18 OCT 2001 | | |12345||D||18 OCT 2001 |
Line 377: |
Line 68: |
| |12345||DL||31 | | |12345||DL||31 |
| |} | | |} |
|
| |
|
| |
|
| ==== Time (MT) ==== | | ==== Time (MT) ==== |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| !input!!conversion!!output | | !input!!conversion (string)!!output |
| |- | | |- |
| |234800||MT||17:13 | | |234800||MT||17:13 |
Line 403: |
Line 93: |
| ==== Hex (HEX/MX) ==== | | ==== Hex (HEX/MX) ==== |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| !input!!conversion!!output | | !input!!conversion (string)!!output |
| |- | | |- |
| |ab||HEX||(same as HEX8 or HEX4 depending on platform) | | |ab||HEX||(same as HEX8 or HEX4 depending on platform) |
Line 427: |
Line 117: |
| ==== Text (L/R/T) ==== | | ==== Text (L/R/T) ==== |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| !input!!conversion!!output | | !input!!conversion!! (string)output |
| |- | | |- |
| |abcd||L#3||abc | | |abcd||L#3||abc |
Line 471: |
Line 161: |
| |4 ||SM || S or M or Mnn : "Single Value" or "Multivalue" or "Multivalue Group nn" | | |4 ||SM || S or M or Mnn : "Single Value" or "Multivalue" or "Multivalue Group nn" |
| |- | | |- |
| |5 ||MAIN || 1 indicates main field no for documentation etc | | |5 ||KEYPARTNO || Multipart keys are separated by * characters. |
| |- | | |- |
| |6 || | | |6 || |
Line 477: |
Line 167: |
| |7 || CONVERSION ||Conversion (MD/MT/D etc.) | | |7 || CONVERSION ||Conversion (MD/MT/D etc.) |
| |- | | |- |
| |8 || SOURCE || Source Code (of a function to calculate the field) | | |8 || SOURCE || Source Code of a subroutine to calculate the field. Multivalues are lines and the result must be placed in a variable "ANS". |
| |- | | |- |
| |9 || JUST || "L" or "R" or "T" requesting left, right or text justification | | |9 || JUST || "L" or "R" or "T" requesting left, right or text justification |
Line 524: |
Line 214: |
| </pre> | | </pre> |
|
| |
|
| (where "value" is any string quoted with " or ' or numbers)
| | === Functions and Commands === |
| | |
| === Traditional Multivalue Functions and Statements (non-OO) === | |
| | |
| Exodus clones traditional multivalue function and statement behaviour and retains their syntax as far as possible.
| |
| | |
| * Traditional functions are rendered as Exodus functions.
| |
| * Traditional statements are rendered as Exodus subroutines.
| |
| | |
| PRINT OCONV(DATE(),'D')
| |
| | |
| in Exodus becomes:
| |
| | |
| printl(oconv(date(),"D"));
| |
|
| |
|
| ==== String Commands ==== | | ==== String Commands ==== |
|
| |
|
| The use of most of Exodus's functions will be fairly obvious to traditional multivalue programmers.
| | Most string functions like trim() that return a new modified string have a corresponding modify in place command like function like trimmer() that is is usually much faster. |
| | So we have convert and converter, replace and replacer, insert and inserter and so on. |
|
| |
|
| Ηοwever it is not so obvious that all the functions ending in "-er" correspond to the old string commands.
| | Therefore by preference use |
|
| |
|
| For example, the classic multivalue "modify in-place" character conversion command:
| | trimmer(v1); |
| | // or |
| | v1.trimmer() |
|
| |
|
| CONVERT 'ab' TO 'cd' IN ZZ
| | instead of |
|
| |
|
| is now represented in Exodus by:
| | v1 = trim(v1); |
| | | // or |
| converter(zz,"ab","cd"); | | v1 = v1.trim(); |
| | |
| Exodus provides a complete set of string modification commands even where there was no specific command in classic mv basic.
| |
| | |
| To guarantee fast performance (regardless of compiler optimisation) you should always use the command instead of the old "self assign" idiom.
| |
| | |
| For example:
| |
| | |
| XX=TRIM(ZZ) | |
| | |
| should appear in Exodus as:
| |
| | |
| trimmer(zz); | |
| | |
| and not:
| |
| | |
| zz=trim(zz);
| |
|
| |
|
| ==== Function Types ==== | | ==== Function Types ==== |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| !TYPE !!FUNCTION TYPE|| | | !TYPE !!FUNCTION TYPE|| |
| |- | | |- |
| |var= ||traditional functions that return values and can be used in expressions and be on the right hand side of assignments|| | | |var= ||traditional functions that return values and can be used in expressions and be on the right hand side of assignments|| |
| |- | | |- |
| |if ||traditional conditional statements that started with if or ended with then or else (or could have)|| | | |if ||traditional conditional statements that started with "if" or ended with "then/else" (or could have)|| |
| |- | | |- |
| |cmd ||traditional commands with no outputs|| | | |cmd ||traditional commands with no outputs|| |
| |- | | |- |
| |cmd2 ||traditional commands that had parameters on the left hand side of the = assigments (or -er functions)|| | | |expr ||traditional commands that now have outputs and can be used in expressions|| |
| |} | | |} |
|
| |
|
| ==== Parameters Types ==== | | ==== Parameters/Argument Types ==== |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| |in<br>or blank|| Parameters that provide data to the function. Can be variables or raw data like 1 or "X"|| | | |in|| Parameters that provide data to the function. Can be variables or raw data like 1 or "X"|| |
| | |- |
| | |unspecified||Same as "in". Omission of the most common type de-clutters the documentation. NB When defining your own subroutines and functions "in" cannot be omitted from the source code.|| |
| |- | | |- |
| |io|| Parameters that may provide and/or return data. Must be variables. Cannot be raw data like 1 or "X"|| | | |io|| Parameters that may provide and/or return data. Must be variables. Cannot be raw data like 1 or "X"|| |
Line 596: |
Line 262: |
| Optional Parameters | | Optional Parameters |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0" | | {|class="wikitable" |
| !Key !!Default|| | | !Key !!Default|| |
| |- | | |- |
| |="" ||""|| | | |= "" ||""|| |
| |- | | |- |
| |=" " ||" "|| | | |= " " ||" "|| |
| |- | | |- |
| |="." ||"."|| | | |= "." ||"."|| |
| |- | | |- |
| |=1 ||1 || | | |= 1 ||1 || |
| |- | | |- |
| |=0 ||0|| | | |= 0 ||0|| |
| |- | | |- |
| |=true ||true|| | | |= true ||true|| |
| |- | | |- |
| |=false ||false|| | | |= false ||false|| |
| |} | | |} |
|
| |
|
| ==== Complete List of Functions ==== | | ==== Field mark characters ==== |
|
| |
|
| | Exodus implements a PICK OS data structure called a "dynamic array". This is simply any string which uses six specific unprintable ASCII delimiter characters (\x1A to \x1F) to separate its various parts. The parts are referred to as records, fields, values, subvalues, text, and subtext and fall within each other. |
|
| |
|
| ===== Environment =====
| | Dynamic arrays therefore implement sparse six dimensional arrays. |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0"
| | Typical CPU caching architecture favours similar values being adjacent in memory therefore implementing them as strings of values separated by delimiter characters can have performance advantages over more complex structures. |
| |-
| |
| |var= ||osgetenv(envname)||
| |
| |-
| |
| |if ||osgetenv(envname, out value)||
| |
| |-
| |
| |if ||ossetenv(envname, newvalue)||
| |
| |}
| |
|
| |
|
| ===== Time/Date/Sleep =====
| | In practice the vast majority of dynamic arrays consist of "fields" separated by the FM character (\x1E) but it is very common for fields to have values separated by the VM character (\x1D) and values to have subvalues using SM (\x1D). |
|
| |
|
| {|border="1" cellpadding="10" cellspacing="0"
| | Since the six delimiter characters fall in the unprintable character range certain other characters have been designated as usable for coding and printing. For example the FM character is represented as ^ and can be entered in source code appended with _var to indicate that the string must be converted to internal format. |
| |var= ||date()||
| |
| |-
| |
| |var= ||time()||
| |
| |-
| |
| |var= ||datetime()||
| |
| |-
| |
| |cmd ||ossleep(milliseconds)||
| |
| |-
| |
| |var= ||ostime()||
| |
| |}
| |
|
| |
|
| | var v1 = "f1^f2^f3"_var; // Three fields |
|
| |
|
| ===== System File =====
| | var v2 = "f1^v1]v2]v3^f3"_var; // Three fields, 2nd field has 3 values. It is "multivalued". |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |if ||osopen(filename, out filehandle)||
| |
| |-
| |
| |cmd ||osclose(filehandle)||
| |
| |-
| |
| |var= ||osbread(filehandle, startoffset, length)||
| |
| |-
| |
| |cmd ||osbread(out data, filehandle, startoffset, length)||
| |
| |-
| |
| |cmd ||osbwrite(data, filehandle, startoffset)||
| |
| |-
| |
| |if ||osread(out data, osfilename)||
| |
| |-
| |
| |var= ||osread(osfilename)||
| |
| |-
| |
| |if ||oswrite(data, osfilename)||
| |
| |-
| |
| |if ||osdelete(osfilename)||
| |
| |-
| |
| |if ||osrename(oldosfilename, newosfilename)||
| |
| |-
| |
| |if ||oscopy(fromosdir_or_filename, newosdir_or_filename)||
| |
| |-
| |
| |cmd ||osflush()||
| |
| |}
| |
|
| |
|
| | Anything which contains a collection of fields can be considered as a "record" and records can be stored in files with a unique primary key. The fields might represent different columns of a traditional database table. So anonymous field number 1 might be a contact name, field 2 the contact address, field 3 a multivalued list of contact points. etc. |
|
| |
|
| ===== System Directory =====
| | {|class="wikitable" |
| | | !Delimiter<br>name!!var||Hex!!Display!!cstr " "||char ' ' |
| {|border="1" cellpadding="10" cellspacing="0" | |
| |var= ||oslist(path=".", wildcard="", mode=0)||
| |
| |-
| |
| |var= ||oslistf(path=".", wildcard="")||
| |
| |-
| |
| |var= ||oslistd(path=".", wildcard="")||
| |
| |- | | |- |
| |var= ||osfile(filename)|| | | |Record Mark ||RM||\x1F|| ` || _RM || RM_ |
| |- | | |- |
| |var= ||osdir(filename)|| | | |Field Mark ||FM||\x1E|| ^ || _FM || FM_ |
| |- | | |- |
| |if ||osmkdir(newdirname)|| | | |Value Mark ||VM||\x1D|| ] || _VM || VM_ |
| |- | | |- |
| |if ||osrmdir(dirname, evenifnotempty=false)|| | | |Subvalue Mark ||SM||\x1C|| } || _SM || SM_ |
| |- | | |- |
| |var= ||oscwd()|| | | |Text Mark||TM ||\x1B|| | || _TM || TM_ |
| |- | | |- |
| |var= ||oscwd(newdirname)|| | | |Subtext Mark ||STM||\x1A|| ~ || _STM || STM_ |
| |} | | |} |
|
| |
|
| ===== Program Control =====
| | {|class="wikitable" style="text-align: center;" |
| | |
| {|border="1" cellpadding="10" cellspacing="0" | |
| |var= ||suspend(command)||
| |
| |-
| |
| |var= ||osshell(command)||
| |
| |-
| |
| |var= ||osshellread(command)||
| |
| |-
| |
| |cmd ||osshellread(out commandoutput, command)||
| |
| |-
| |
| |cmd ||osshellwrite(commandinput, command)||
| |
| |-
| |
| |cmd ||stop(text="")||
| |
| |- | | |- |
| |cmd ||abort(text)|| | | |align=right|<b> Delimiter Name :</b> ||Record Mark||Field Mark||Value Mark||Subvalue Mark||Text Mark||Subtext Mark |
| |- | | |- |
| |var= ||perform(command)|| | | |align=right|<b>var :</b> || RM ||FM ||VM ||SM ||TM ||STM |
| |- | | |- |
| |var= ||execute(command)|| | | |align=right|<b>Display :</b>||` ||^ || ] || } || | || ~ |
| |- | | |- |
| |var= ||chain(command)|| | | |align=right|<b>Hex :</b> ||\x1F||\x1E||\x1D||\x1C||\x1B||\x1A |
| |- | | |- |
| |var= ||logoff()|| | | |align=right|<b>cstr " " :</b> ||_RM ||_FM ||_VM ||_SM ||_TM ||_STM |
| |- | | |- |
| |cmd ||debug()|| | | |align=right|<b>char ' ' :</b> ||RM_ ||FM_ ||VM_ ||SM_ ||TM_ ||STM_ |
| |} | | |} |
|
| |
|
| | ==== Complete List of Functions ==== |
|
| |
|
| ===== Status =====
| | [[Functions|Complete List of Functions]] |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |if ||assigned(anyvar)||
| |
| |-
| |
| |if ||unassigned(anyvar)||
| |
| |}
| |
| | |
| ===== Console Output =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |cmd ||print(instring)||
| |
| |-
| |
| |cmd ||printl(instring="")||
| |
| |-
| |
| |cmd ||printt(instring="")||
| |
| |}
| |
| | |
| ===== Cursor =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |var= ||at(column0orcode)||
| |
| |-
| |
| |var= ||at(column0, row0)||
| |
| |-
| |
| |var= ||getcursor()||
| |
| |-
| |
| |cmd ||setcursor(cursorstr)||
| |
| |-
| |
| |var= ||getprompt()||
| |
| |-
| |
| |cmd ||setprompt(promptchar)||
| |
| |}
| |
| | |
| ===== Console Input =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |-
| |
| |var= ||input()||
| |
| |-
| |
| |var= ||input(out inputstr)||
| |
| |-
| |
| |var= ||input(prompt, out inputstr)||
| |
| |-
| |
| |var= ||inputn(n)||
| |
| |}
| |
| | |
| ===== Math =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |var= ||rnd(number)||
| |
| |-
| |
| |cmd ||initrnd(seednumber)||
| |
| |-
| |
| |var= ||mod(dividend, divisor)||
| |
| |-
| |
| |var= ||abs(number)||
| |
| |-
| |
| |var= ||pwr(base, exponent)||
| |
| |-
| |
| |var= ||exp(power)||
| |
| |-
| |
| |var= ||sqrt(number)||
| |
| |-
| |
| |var= ||sin(degrees)||
| |
| |-
| |
| |var= ||cos(degrees)||
| |
| |-
| |
| |var= ||tan(degrees)||
| |
| |-
| |
| |var= ||atan(degrees)||
| |
| |-
| |
| |var= ||loge(number)||
| |
| |-
| |
| |var= ||integer(number)||
| |
| |-
| |
| |var= ||floor(number)||
| |
| |-
| |
| |var= ||round(number, ndecimals=0)||
| |
| |}
| |
| | |
| ===== String Creation =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |var= ||chr(integer)||
| |
| |-
| |
| |var= ||str(instring, number)||
| |
| |-
| |
| |var= ||space(number)||
| |
| |}
| |
| | |
| | |
| ===== String Info/Search =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |-
| |
| |var= ||count(instring, substr)||
| |
| |-
| |
| |var= ||dcount(instring, substr)||
| |
| |-
| |
| |var= ||index(instring, substr, startcharno=1)||
| |
| |-
| |
| |var= ||len(instring)||
| |
| |-
| |
| |var= ||length(instring)||
| |
| |-
| |
| |if ||match(instring, matchstr, options="")||
| |
| |-
| |
| |var= ||seq(inchar)||
| |
| |}
| |
| | |
| ===== String Functions =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |var= ||convert(instring, oldchars, newchars)||
| |
| |-
| |
| |var= ||crop(instring)||
| |
| |-
| |
| |var= ||field(instring, sepchar, fieldno, nfields=1)||
| |
| |-
| |
| |var= ||field2(instring, sepchar, fieldno, nfields=1)||
| |
| |-
| |
| |var= ||fieldstore(instring, sepchar, fieldno, nfields, replacementstr)||
| |
| |-
| |
| |var= ||lcase(instring)||
| |
| |-
| |
| |var= ||ucase(instring)||
| |
| |-
| |
| |var= ||lower(instring)||
| |
| |-
| |
| |var= ||raise(instring)||
| |
| |-
| |
| |cmd2 ||quote(instring)||
| |
| |-
| |
| |cmd2 ||unquote(instring)||
| |
| |-
| |
| |var= ||splice(instring, fromcharno, nchars, insertionstr)||
| |
| |-
| |
| |var= ||substr(instring, fromcharno)||
| |
| |-
| |
| |var= ||substr(instring, fromcharno, nchars)||
| |
| |-
| |
| |var= ||swap(instring, oldstr, newstr, options="")||
| |
| |-
| |
| |var= ||trim(instring, trimchars=" ")||
| |
| |-
| |
| |var= ||trimb(instring, trimchars=" ")||
| |
| |-
| |
| |var= ||trimf(instring, trimchars=" ")||
| |
| |}
| |
| | |
| ===== String Commands =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |-
| |
| |cmd2 ||converter(io instring, oldchars, newchars)||
| |
| |-
| |
| |var= ||cropper(io instring)||
| |
| |-
| |
| |cmd2 ||fieldstorer(io instring, sepchar, fieldno, nfields, replacementstr)||
| |
| |-
| |
| |cmd2 ||lcaser(io instring)||
| |
| |-
| |
| |var= ||ucaser(io instring)||
| |
| |-
| |
| |cmd2 ||lowerer(io instring)||
| |
| |-
| |
| |cmd2 ||raiser(io instring)||
| |
| |-
| |
| |cmd2 ||quoter(io instring)||
| |
| |-
| |
| |cmd2 ||unquoter(io instring)||
| |
| |-
| |
| |cmd2 ||splicer(io instring, fromcharno, nchars, insertion)||
| |
| |-
| |
| |var= ||substrer(io instring, fromcharno)||
| |
| |-
| |
| |var= ||substrer(io instring, fromcharno, nchars)||
| |
| |-
| |
| |cmd2 ||swapper(io instring, oldstr, newstr, options="")||
| |
| |-
| |
| |cmd2 ||trimmer(io instring, trimchars=" ")||
| |
| |-
| |
| |cmd2 ||trimmerb(io instring, trimchars=" ")||
| |
| |-
| |
| |cmd2 ||trimmerf(io instring, trimchars=" ")||
| |
| |}
| |
| | |
| ===== iconv/oconv =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |var= ||oconv(instring, conversion)||
| |
| |-
| |
| |var= ||oconv(instring, conversion)||
| |
| |-
| |
| |var= ||iconv(instring, conversion)||
| |
| |-
| |
| |var= ||iconv(instring, conversion)||
| |
| |}
| |
| | |
| | |
| ===== Database =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |if ||connect(connectionstring="")||
| |
| |-
| |
| |if ||disconnect()||
| |
| |-
| |
| |if ||createfile(filename, options="")||
| |
| |-
| |
| |if ||deletefile(filename)||
| |
| |-
| |
| |if ||clearfile(filename)||
| |
| |-
| |
| |var= ||listfiles()||
| |
| |-
| |
| |if ||createindex(filename, fieldname, dictfilename="")||
| |
| |-
| |
| |if ||deleteindex(filename, fieldname)||
| |
| |-
| |
| |var= ||listindexes(filename)||
| |
| |-
| |
| |if ||begin()||
| |
| |-
| |
| |if ||rollback()||
| |
| |-
| |
| |if ||end()||
| |
| |}
| |
| | |
| | |
| ===== Database Files and Records =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |if ||open(filename, out filehandle)||
| |
| |-
| |
| |if ||read(out record, filehandle, key)||
| |
| |-
| |
| |if ||readv(out record, filehandle, key, fieldnumber)||
| |
| |-
| |
| |if ||write(record, filehandle, key)||
| |
| |-
| |
| |if ||writev(record, filehandle, key, fieldn)||
| |
| |-
| |
| |if ||deleterecord(filehandle, key)||
| |
| |-
| |
| |if ||updaterecord(record, filehandle, key)||
| |
| |-
| |
| |if ||insertrecord(record, filehandle, key)||
| |
| |-
| |
| |if ||lock(filehandle, key)||
| |
| |-
| |
| |cmd ||unlock(filehandle, key)||
| |
| |-
| |
| |cmd ||unlockall()||
| |
| |}
| |
| | |
| ===== Record Selection =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |if ||select(sortselectclause="")||
| |
| |-
| |
| |cmd ||clearselect()||
| |
| |-
| |
| |if ||readnext(out key)||
| |
| |-
| |
| |if ||readnext(out key, out valueno)||
| |
| |-
| |
| |if ||selectrecord(sortselectclause="")||
| |
| |-
| |
| |if ||readnextrecord(out key, out record)||
| |
| |}
| |
| | |
| | |
| ===== Dictionary =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |var= ||calculate(fieldname)||
| |
| |-
| |
| |var= ||xlate(filename, key, fieldno, mode)||
| |
| |}
| |
| | |
| | |
| ===== Dynamic Array Functions =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |var= ||replace(instring, fieldno, replacement)||
| |
| |-
| |
| |var= ||replace(instring, fieldno, valueno, replacement)||
| |
| |-
| |
| |var= ||replace(instring, fieldno, valueno, subvalueno, replacement)||
| |
| |-
| |
| |var= ||extract(instring, fieldno=0, valueno=0, subvalueno=0)||
| |
| |-
| |
| |var= ||erase(instring, fieldno, valueno=0, subvalueno=0)||
| |
| |-
| |
| |var= ||insert(instring, fieldno, insertion)||
| |
| |-
| |
| |var= ||insert(instring, fieldno, valueno, insertion)||
| |
| |-
| |
| |var= ||insert(instring, fieldno, valueno, subvalueno, insertion)||
| |
| |-
| |
| |if ||locate(instring, target, out setting, fieldn=0, valuen=0)||
| |
| |-
| |
| |if ||locateby(instring, target, ordercode, out setting, fieldn=0, valuen=0)||
| |
| |-
| |
| |if ||locateusing(instring, target, usingchar, out setting, fieldn=0, valuen=0, subvaluen=0)||
| |
| |-
| |
| |if ||locateusing(instring, target, usingchar)||
| |
| |-
| |
| |var= ||remove(fromstr, io startx, out delimiterno)||
| |
| |-
| |
| |var= ||sum(instring, sepchar=VM_)||
| |
| |}
| |
| | |
| ===== Dynamic Array Commands =====
| |
| | |
| {|border="1" cellpadding="10" cellspacing="0"
| |
| |cmd2 ||replacer(io instring, fieldno, replacement)||
| |
| |-
| |
| |cmd2 ||replacer(io instring, fieldno, valueno, replacement)||
| |
| |-
| |
| |cmd2 ||replacer(io instring, fieldno, valueno, subvalueno, replacement)||
| |
| |-
| |
| |cmd2 ||inserter(io instring, fieldno, insertion)||
| |
| |-
| |
| |cmd2 ||inserter(io instring, fieldno, valueno, insertion)||
| |
| |-
| |
| |cmd2 ||inserter(io instring, fieldno, valueno, subvalueno, insertion)||
| |
| |-
| |
| |cmd2 ||eraser(io instring, fieldno, valueno=0, subvalueno=0)||
| |
| |}
| |