GASOIL

GASOIL (General Application Stack Oriented Imperative Language) is a postfix notation esoteric programming language invented by User:Morex in 2009.

Description
The main idea was to test a language (and interpreter) that instead of loading the program in a fixed memory, loads the program in a "program stack". This way the program is freeing memory as it is executed (instructions are not available anymore once they are executed (except calling a subroutine more than once)). There is no need for an "Instruction Pointer", meaning recursion is the only way to implement loops.

Inspiration for creating GASOIL was taken from the HP-41C and HP-28S (RPL) languages.

The GASOIL programming language is:
 * Imperative
 * Structured
 * Recursive without a call stack or return stack (Infinite recursive loops do not overflow)
 * Stack oriented (with a data stack and a program stack)
 * Full postfix (for operators, functions, and control structures too)
 * Reflection oriented (code can create code to be run on the fly)

GASOIL has a lot of features: One Program Stack (PS), one Data Stack (DS), one directionable memory area for variable data storing, arithmetic functions, a lot of stack functions, control structures, comments, logic operators, subroutine calls, recursion and a rich instruction set.

Both stacks and the memory area can handle diferent data types in each memory cell. These data types are:
 * Floating point numbers
 * Strings, enclosed in ""
 * Program Instructions
 * Program Blocks, enclosed in with elements delimited by ;

The interpreter environment should let the user interact with the Data Stack, Showing output values, and letting users enter Input values. Standar I/O functions READ and WRITE are available too.

When running, in each step, the interpreter pops an element from the PS and takes the following actions depending on the data type: The execution stops when the program stack is empty.
 * If the element is a valid Instruction then it is executed.
 * If the element is a Number, a String or a Program block, it is pushed to DS.

The PARSE instruction pops a program block from the DS (or a string containing a program block), and after parsing, push the resultant elements backwards on the Program Stack.

Literals

 * Numbers: 2, -4, 3.1416
 * Strings: "Hello"
 * Program Blocks: (1; 2; +; NOP Add 1 plus 2)

Flow Control

 * PARSE: Pop a program block from the DS (or a string containing a program block), and after parsing, push the resultant elements backwards on the Program Stack.
 * CALL: Load a named subroutine pushing it to the PS
 * CCALL: Conditional Call - Load a named subroutine pushing it to the PS if condition is true.
 * STOP: Stop execution. User can resume.
 * NOP:	Do Nothing. Ignore rest of element. Could be used to code comment: (1; NOP This is a comment; 2; +; NOP Another comment)

Extended Flow Control
These instructions could be implemented or not in lightweight interpreters. It is possible to write them as GASOIL subroutines based in CCALL.
 * ITE (If Then Else): Pop three DS elements: Cond.Value; (then block); (else block); ITE
 * WHILE: Pop two DS elements: (Condition expresion); (Block); WHILE
 * UNTIL: Pop two DS elements: (Block); (Condition expresion); UNTIL
 * FOR: Pop four DS elements: Memory_address; InitialValue; FinalValue; (Block); FOR

Arithmetic

 * MOD
 * SQRT
 * RND: Returns a pseudo-random number less than 1 but greater than or equal to 0
 * INT: Truncate a number to integer
 * MOD
 * SQRT
 * RND: Returns a pseudo-random number less than 1 but greater than or equal to 0
 * INT: Truncate a number to integer

Stack

 * DROP: Drop the #1 DS element
 * DROP2: Drop the #2 DS element
 * DROP3: Drop the #3 DS element
 * DROP4: Drop the #4 DS element
 * DUP: Duplicate the #1 DS element
 * DUP2: Duplicate the #1 and #2 DS elements
 * DUP3: Duplicate the #1, #2 and #3 DS elements
 * DUP4: Duplicate the #1, #2, #3 and #4 DS elements
 * SWAP12: Swap DS elements #1 and #2
 * SWAP13: Swap DS elements #1 and #3
 * SWAP23: Swap DS elements #2 and #3
 * SWAP14: Swap DS elements #1 and #4
 * SWAP24: Swap DS elements #2 and #4
 * SWAP34: Swap DS elements #3 and #4

Logic & comparison

 * =: Pop two DS elements: If #1 = #2 then push 1 (true) else push 0 (false)
 * NOT
 * AND
 * OR
 * XOR
 * NOT
 * AND
 * OR
 * XOR
 * XOR

Memory access

 * STO: Pop two DS elements. Store #2 DS value onto memory address pointed by #1 DS value
 * RCL: Pop one DS element. Push to DS the value from memory address pointed by #1 DS value

I/O

 * READ
 * WRITE

String manipulation

 * &: Concatenate two strings
 * STRLEN: Find the length of a string
 * INSTR: Return a number specifying the start position of the first occurrence of one string within another
 * SUBSTR: Return a string containing a specified number of characters from a string
 * REPLACE: Return a string in which a specified substring has been replaced with another substring
 * ASCII: Return a number representing the character code corresponding to a character
 * CHR: Return the character associated with the specified character code
 * STR2NUM: Return the number contained in a string as a numeric value
 * NUM2STR: Return a string representation of a number

Examples
Hello, world! main ("Hello World!"; WRITE)

Endless loop main (NOP This is a endless loop; "main"; CALL) Fibonacci numbers up to 100 main (1;1;"suma";CALL) suma (DUP2; +; DUP; 100; < ; "suma"; CCALL)

Add integers up to 20 using CCALL main (0; 1; 0; STO; "r"; CALL) r (0; RCL; +; 0; RCL; 1; +; DUP; 0; STO; 20; <=; "r"; CCALL)

Add integers up to 20 using WHILE main (0;1;0;STO;(0;RCL;20;<=);(0;RCL;+;0;RCL;1;+;0;STO);WHILE)

Add integers up to 20 using UNTIL main (0;0;0;STO;(0;RCL;1;+;0;STO;0;RCL;+);(0;RCL;20;=);UNTIL)

Add integers up to 20 using FOR main (0;0;1;20;(0;RCL;+);FOR)

Prime number generator up to 50 (     0;                                                 NOP Reg 0 for outer loop;        2;                                                 NOP from 2;        50;                                                NOP to 50;        ( 1; 1; STO;                                    NOP Flag as prime; 2;                                        NOP Reg 2 for inner loop; 2;                                        NOP from 2; 0; RCL; SQRT; INT;                        NOP to Int(sqrt(Reg 0)); (                       0; RCL; 2; RCL; /; DUP; INT; =;    NOP eval (Reg 0 / Reg 2 = int(Reg 0 / Reg 2) ?);                        (0; 1; STO);                       NOP Then Flag as No prime;                        (NOP);                     ITE                ); FOR; 1; RCL; 1; =;                             NOP Is Prime Flag set?; (0; RCL; " es primo."; &);                NOP Push info if Prime; (NOP); ITE );   FOR )

99 Bottles of Beer main (99; 0; STO; ""; ("e1"; CALL; 0;RCL; 1; -; 0; STO; "e2"; CALL); (0; RCL; 1;<=);UNTIL; "e1"; CALL; "n"; &; "f2"; CALL; &; "f1"; CALL; &; "."; &; 10; CHR; &; "N"; &; "f2"; CALL; &; "f1"; CALL; &; ", n";&;"f2";CALL;&;". Go to the store and buy some more, "; &; 99; 0;  STO; "bo"; CALL; &; "f1"; CALL; &; "."; &) e1 ("bo"; CALL; &; "f1"; CALL; &;", "; &; "bo"; CALL; &; ". Take one down and pass it around, ";&) e2 ("bo"; CALL ;&; "f1"; CALL; &; "."; & ;10;CHR;&) bo (0; RCL; " bottle"; &; 0; RCL; 1; =; (""); ("s"); ITE; &; " of beer"; &) f1 (" on the wall") f2 ("o more bottles of beer")

Brainfuck interpreter main ("Input Brainfuck code"; READ; ""; &; 0; STO; DROP; 1; 1; STO; 2; 3; 100; (0; 2; RCL; STO); FOR; 3; 2; STO; (0; RCL; STRLEN; 1; RCL; >=); (0; RCL; 1; RCL; 1; SUBSTR; CALL; 1; RCL; 1; +; 1; STO); WHILE) > (2; RCL; 1; +; 2; STO) < (2; RCL; 1; -; 2; STO) + (2; RCL; DUP; RCL; 1; +; SWAP12; STO) - (2; RCL; DUP; RCL; 1; -; SWAP12; STO) . (2; RCL;RCL; CHR; WRITE) , (READ; 2; RCL; STO) [ (2; RCL; RCL; 0; =; ((0; RCL; 1; RCL; 1; SUBSTR; "]"; !=); (1; RCL; 1; +; 1;STO); WHILE); (NOP); ITE) ] ((0; RCL; 1; RCL; 1; SUBSTR; "["; !=); (1; RCL; 1; -; 1; STO); WHILE; 1; RCL; 1; -; 1; STO)

External resources

 * GASOIL 0.83 - a GASOIL interpreter in Excel.