_var'aq_ Specification ================================= For better flavor text please read the [Original `var'aq` spec](https://www.oocities.org/connorbd/varaq/varaqspec.html) the following is a trimmed down version of the spec with a couple of fixes and addendums to how this implementation of the language works. ## 1 Language Overview _var'aq_ is a stack-based, RPN programming language with points of similarity to Lisp, Forth, and PostScript. It is more of a functional language than an imperative (Algol-like) language; most operations are dependent on the stack and bypass the local variable store altogether. ### 1.2 Filetypes * `.vq -- application/varaq` -- a standard _var'aq_ source file * `.vqe -- application/varaq-engl` -- an English-keyword _var'aq_ source file ## 2 Language Basics This section describes the fundamental _var'aq_ language constructs and data types. ### 2.1 Stack Operations These operations directly manipulate the _var'aq_ operand stack. The operand stack can hold any of four kinds of data: numbers (real or integer), strings, functions, or arrays. It is best described as "translucent", similar to the transparent stack of Forth or PostScript but somewhat more restricted. The internal data representation of the stack is not available to the programmer. #### 2.1.1 pop/woD _obj `woD` -_ Pops and discards the top item on the stack. The literal meaning is _discard_. Errors: stackUnderflow #### 2.1.2 dup/latlh _obj `latlh` obj obj_ Duplicates the top object on the stack. Errors: stackUnderflow #### 2.1.3 exch/tam _obj1 obj2 `tam` obj2 obj1_ Inverts the order of the top two objects on the stack. Errors: stackUnderflow #### 2.1.4 clear/chImmoH _... obj `chIm` -_ Empties the stack. Errors: none #### 2.1.5 remember/qaw _\- `qaw` flag_ Puts a flag (like PostScript's `mark`) on the stack. The internal representation of the flag is not available to the programmer. Errors: none #### 2.1.6 forget/qawHa' _... flag ... `qawHa'` ..._ Clears the stack down to the flag and pops the flag. If there is no flag present, the stack is emptied completely. Errors: none #### 2.1.7 dump/Hotlh (lit. scan) _... `Hotlh` ..._ Prints the contents of the operand stack to STDOUT without changing them. _Note_: the _Hotlh_ operator is a debugging operator and is not intended for use in programs; it is merely documented here because it might be useful to a _var'aq_ developer. In particular, the output format of this operator is implementation-defined and will not be specified in this document. _Hotlh_ may be redefined to take such arguments as the implementor feels appropriate. Errors: implementation-defined. #### 2.1.8 disinter Returns the value just above the top mark on the stack without disturbing the stack above it. ### 2.2 Data/Code Operations _var'aq_, like many similar languages, does not distinguish between code and data. These operations include operators to associate names with objects and executable procedures, as well as operators to define and manage data structures. Note that variables and procedures live in a common namespace, since the act of pushing the content of a variable is essentially the same as executing the variable's name. #### 2.2.1 ~ (quote/lI'moH) _\- `~` obj obj_ The ~ operator is a special form, as it is not a postfix operator. When the interpreter encounters a ~, it pushes the next token on the stack as is regardless of whether it is a defined name. (Attempting to push an undefined name without a ~ will generate an undefinedName error.) The literal meaning of this operator's name is "make useful". Errors: none #### 2.2.2 { Begins the creation of an anonymous procedure. The process is implementation-dependent. #### 2.2.3 } _\- `}` proc_ Completes procedure construction and pushes a reference to the completed procedure on the stack. Does not execute the procedure. Errors: noDefinedProc #### 2.2.4 name/pong _obj id `pong` -_ Associates _obj_ with _id_ and places it in the system lookup space. Conventionally used to associate new operator names with procedure objects. Example: _~ add3 { boq boq cha' } pong_ Pushes the name _add3_ and a procedure object on the stack, then binds the name to the procedure. Errors: stackUnderflow, noDefinedProc #### 2.2.5 set/cher _obj id `cher` -_ Reassigns the value of a value already in the system lookup space. Used primarily for variable assignments. Errors: stackUnderflow, noSuchName #### 2.2.6 (\* ... \*) (comment) Marks a comment in a program. All such comments are treated as single tokens and ignored. #### 2.2.7 //_name_ Causes the interpreter to import a file with the name _name_.vq(e) and execute it as if it is part of the currently executing program. Essentially equivalent to `#include` in C. An example can be found at the top of the [test.vqe](./examples/test.vqe) example. `Note:` you must use either absolute paths or paths relitive to the location of the interpeter ### 2.3 Control Flow _var'aq_ supports a small but sufficient supply of conditional and iterative operators. #### 2.3.1 ifyes/HIja'chugh _bool proc `HIja'chugh` -_ Pops the proc object off the stack, then evaluates the boolean. If it's true, the proc object is evaluated; otherwise, it's thrown out. Errors: stackUnderflow, noDefinedProc #### 2.3.2 ifno/ghobe'chugh _bool proc `ghobe'chugh` -_ Similar to _HIja'chugh_ above, but executes proc only if bool is false. Errors: stackUnderFlow, noDefinedProc #### 2.3.3 choose/wIv _bool `wIv` bool bool_ Duplicates a boolean value on top of the stack. Allows paired HI'ja'chugh/ghobe'chugh clauses. `Note:` To the untrained eye, it may seem as though wIv and latlh are identical. This is true in the reference implementation, but may not be in any version that actually does some level of type checking. This bit of syntactic sugar should never be relied upon; always use wIv in this situation. #### 2.3.4 eval/chov _proc `chov` -_ Pops a proc object off the stack and executes it. Errors: stackUnderflow, noDefinedProc #### 2.3.5 escape/nargh _bool `nargh` -_ Exit the current procedure. Useful for exit conditions on loops. Will terminate the current session if used top-level. #### 2.3.6 repeat/vangqa' _val proc `vangqa'` -_ Pops val and proc off the stack and executes proc val times. ### 2.4 List Operations _var'aq_ supports a series of operators for management of lists (_ghomHom_, which seems to mean something like "cluster"). These primitives are the language's primary way of managing aggregate objects and work much like similar operators in LISP; a more sophisticated paradigm, such as OO extensions or the like, can be built with these operators. Note that "objects" as they stand in _var'aq_ are largely singletons as in JavaScript; there is no inherent concept of object-orientation or anything like it in standard _var'aq_. #### 2.4.1 ( Begins a list definition. #### 2.4.2 ) _( item1 item2 ... `)` list_ Creates a list and pushes it onto the stack. #### 2.4.3 split/SIj _list `SIj` item1 list_ Pops a list off the stack and returns the first item and the rest of the list. #### 2.4.4 cons/muv _list item1 ... `muv` list_ Takes an object and adds it to the head of a list. Equivalent to the LISP `cons` operator. #### 2.4.5 shatter/ghorqu' _list `ghorqu'` item1 item2 ..._ Reduces a list to its component elements and pushes them on the stack in order. `Note:` The precise meaning of the construction _ghorqu'_ is a bit obscure; the rendering _shatter_ is idiomatic and may derive from a nonstandard dialect. Standard Klingon would generally prefer _jor_, meaning _explode_.) #### 2.4.6 empty?/chIm'a' _list `chIm'a'` bool_ Examines a list on the stack and returns 1 if its value is null (_pagh_), a 0 if it contains anything. #### 2.4.7 consume _obj1 obj2 ... mark `consume` list_ Pops all objects on the stack down to _mark_ and returns them in a list. `Note:` some implementations also have an operator known as bite/_chop_, equivalent to the Lisp _cdr_. This is not required in any standard _var'aq_ implementation and can easily be rendered by the function ``` ~ chop { SIj woD } pong ``` ### 2.5 String Operators _tlheghjangwI'mey_ #### 2.5.1 strtie/tlheghrar _str1 str2 `tlheghrar` str3_ Concatenates the top two strings on the stack into one. #### 2.5.2 compose/naQmoH _mark str1 str2 ... strn `naQmoH` strn'_ Pops objects (executing proc objects if necessary) off the stack until a marker (placed by `qaw`) is hit and combines them into one string. #### 2.5.3 streq?/tlheghrap'a' _str1 str2 `tlheghrap'a'` bool_ Pops the top two strings on the stack, compares them, and returns 1 if identical, 0 if not. #### 2.5.4 strcut/tlheghpe' _str startval endval `tlheghpe'` substr_ Pops two values and a string and returns the section of the string between character _startval_ and character _endval_. #### 2.5.5 strmeasure/tlheghjuv _str `tlheghjuv` val_ Pops a string off the stack and returns its length in characters. #### 2.5.6 explode/jor _str `jor` list_ Separates individual "words" in a string by whitespace. ## 3 Mathematical Operators _mI'jangwI'mey_ ### 3.1 Arithmetic Operations _toghwI'mey_ Arithmetic operators usually work with real numbers unless otherwise stated. The number operators (sec 3.3) can convert them to integers if necessary. #### 3.1.1 add/boq _a b `boq` sum_ Pops the top two values on the stack and replaces them with their sum. #### 3.1.2 sub/boqHa' _a b `boqHa'` difference_ Pops the top two values on the stack and replaces them with a - b. #### 3.1.3 mul/boq'egh _a b `boq'egh` product_ Pops the top two values on the stack and replaces them with their product. #### 3.1.4 div/boqHa''egh _a b `wav` quotient_ Pops the top two values on the stack and replaces them with a/b. #### 3.1.5 idiv/HabboqHa''egh (lit. full-divide) _a b `HabboqHa''egh` quotient_ Pops the top two values on the stack and replaces them with the results of an integer division operation. #### 3.1.6 mod/chuv (lit. leftover) _a b `chuv` remainder_ Pops the top two values and returns the remainder of a mod b. #### 3.1.7 pow/boqHa'qa' (lit. remultiply) _base exp `boqHa'qa'` real_ Pops the top two values and returns base^exp. #### 3.1.8 sqrt/loS'ar (lit. fourth-howmuch) _angle `loS'ar` real_ Returns the square root of val. #### 3.1.9 add1/wa'boq _a `wa'boq` a+1_ Increments the top value on the stack by one. #### 3.1.10 sub1/wa'boqHa' _a `wa'boqHa'` a-1_ Decrements the top value on the stack by one. ### 3.2 Trigonometric and Logarithmic Operators _SIHpojjangwI'mey 'ej ghurjangwI'mey_ #### 3.2.1 sin/yu'egh (lit. wave) _angle `yu'egh` real_ Returns the sine of val. #### 3.2.2 cos/yu'eghHa' (lit. counter-wave) _angle `yu'eghHa'` cos(val)_ Returns the cosine of val. #### 3.2.3 tan/qojmI' (lit. cliffnumber) _angle `qojmI'` tan(val)_ Returns the tangent of val. #### 3.2.4 atan/qojHa' (lit. anticliff) _num den `qojHa'` angle_ Returns the arctangent of _num / den_. #### 3.2.5 ln/ghurtaH _num `ghurtaH` real_ Returns the natural log of _num_. #### 3.2.6 log/maHghurtaH _num `maHghurtaH` real_ Returns the base 10 log of _num_. #### 3.2.7 log3/wejghurtaH _num `wejghurtaH` real_ Returns the base 3 log of _num_. ### 3.3 Numerical Operators and Constants This section describes operators that operate on numbers themselves, as well as common system-level constants. #### 3.3.1 clip/poD _real `poD` int_ Removes the fractional portion of a real number (equivalent to floor(real). #### 3.3.2 smooth/Hab (lit. smooth) _real `Hab` int_ Rounds a number to the nearest integer. #### 3.3.3 howmuch/'ar _num `'ar` num2_ Returns the absolute value of _num_. #### 3.3.4 setrand/mIScher _num `mIScher` -_ Sets the random number generator seed value to _num_. Not common, since most _var'aq_ implementations have a rather arcane formula for picking a pseudo-random seed value. #### 3.3.5 rand/mIS _num `mIS` real_ Returns a random real number in the range 0 to _num_. If there is no meaningful input on the stack, #### 3.3.6 pi/HeHmI' Pushes the value pi (~3.14159...) onto the stack. The Klingon name literally means "edge-number". #### 3.3.7 e/ghurmI' Pushes the value e onto the stack. The Klingon name literally means "growth-number". #### 3.3.8 int?/HabmI''a' _val `HabmI''a'` bool_ Pops the top value on the stack and returns 1 if it is an integer, 0 if not. #### 3.3.9 number?/mI''a' _val `mI''a'` bool_ Pops the top value off the stack and returns 1 if it's a number, 0 if it's something else. #### 3.3.10 numberize/mI'moH _str `mi'moH` val_ Pops a string off the stack, converts it into a numerical value, and returns it. #### 3.4 Bitwise operators Though _var'aq_ makes no clear distinction between integers and reals, it is nevertheless useful to be able to manipulate a number on the bit level. The following operators assume that their operands will always be treated as integers; effects on floating-point values are undefined, and may be disallowed at the implementor's discretion. #### 3.4.1 isolate/mobmoH _a b `mobmoH` result_ Performs a bitwise AND on a and b. #### 3.4.2 mix/DuD _a b `DuD` result_ Performs a bitwise OR on a and b. #### 3.4.3 contradict/tlhoch _a b `tlhoch` result_ Performs a bitwise XOR on a and b. #### 3.4.4 compl/Qo'moH _val `Qo'moH` ~val_ Returns the one's-complement of val. `Note:` The literal meaning is something like "make it say no". #### 3.4.5 shiftright/nIHghoS _a b `nIHghoS` result_ Shifts a right b places, preserving the sign of the value. #### 3.4.6 shiftleft/poSghoS _a b `poSghoS` result_ Shifts a left b places. ### 4 Relational and Logical Operators #### 4.1 Relational Operators and Predicate Functions _yu'jangwI'mey_ #### 4.1.1 gt?/law''a' _a b `law''a'` bool_ Pops a and b off the stack, compares them, and returns a boolean value of true if a is larger. #### 4.1.2 lt?/puS'a' _a b `puS'a'` bool_ Pops a and b off the stack, compares them, and returns a boolean value of true if a is smaller. #### 4.1.3 eq?/rap'a' _a b `rap'a'` bool_ Pops a and b off the stack, compares them, and returns a boolean value of true if a is the same as b. #### 4.1.4 ge?/law'rap'a' _a b `law'rap'a'` bool_ Pops a and b off the stack, compares them, and returns a boolean value of true if a is greater than or equal to b. #### 4.1.5 le?/puSrap'a' _a b `puSrap'a'` bool_ Pops a and b off the stack, compares them, and returns a boolean value of true if a is less than or equal to b. #### 4.1.6 ne?/rapbe'a' _a b `rapbe'a'` bool_ Pops a and b off the stack, compares them, and returns a boolean value of true if a is not equal to b. #### 4.1.7 null?/pagh'a' _obj `pagh'a'` bool_ Examines the top object on the stack and returns a 1 if null, a 0 if not. #### 4.1.8 negative?/taH'a' _val `taH'a'` bool_ Pops the top number on the stack and returns a 1 if less than 0, a 0 if not. #### 4.2 Logical Operators _vItjangwI'mey_ Note that these are strictly logical operators, not bitwise. #### 4.2.1 and/je _a b `je` bool_ Evaluates b and a and returns a 1 if both are true, a 0 if not. #### 4.2.2 or/joq _a b `joq` bool_ Evaluates b and a and returns a 1 if one or both are true, a 0 if both are false. #### 4.2.3 xor/ghap _a b `ghap` bool_ Evaluates b and a and returns a 1 if only one is true, a 0 otherwise. #### 4.2.4 not/ghobe' _val `ghobe'` bool_ Evaluates val and returns 1 if true, 0 if not. ### 5 Input/Output and File Operators The _var'aq_ Level 0 specification essentially handles console I/O and files in a manner very similar to the UNIX model. #### 5.1 Console I/O The console I/O model at this point is very simple: write, read, error. #### 5.1.1 disp/cha' _obj `cha'` -_ Pops the top object on the stack and writes it to STDOUT. Note that certain types of objects will generate meaningless output, particularly anonymous proc objects. #### 5.1.2 listen/'Ij _\- `'Ij` str_ Reads one line of input and stores it as a string on top of the stack. #### 5.1.3 complain/bep _str `bep` -_ Pops _str_ and prints it to stderr. ### 6 System Variables _patSarwI'mey_ This section describes _var'aq_ keywords that do no more than put set values on the stack. Many of them are not precisely constants but more like environment variables. #### 6.1 I/O-related Constants #### 6.1.1 newline/chu'DonwI' _- `chu'DonwI'` '\n'_ Prints a carriage return. #### 6.1.2 tab/chu'tut _- `chu'DonwI'` '\t'_ Advances by one tab stop. #### 6.2 Environment Constants #### 6.2.1 whereami/nuqDaq\_jIH _- `nuqDaq_jIH` "string of your local ip address"_ Returns the IP address of the machine the interpreter is running on. #### 6.2.2 version/pongmI' _- `pongmI'` "string of version"_ Returns the current interpreter version number. The reference interpreter returns a date stamp. #### 6.2.3 argv/taghDe' _- `taghDe'` (arg1, arg2, ...)_ Pushes the command line arguments on the stack as a list. ## 7 New Operators The following are all new operators that are not included in the original perl implementation of _var'aq_ ### 7.1 Stack Operations These are stolen directly from _Forth_ (specifically the [_FORTH-79 Handy Reference_](http://www.forth.org/Ting/Forth-for-the-Complete-Idiot/Forth-79-Handy-Reference.pdf) from the book _Forth for the Complete Idiot_), They are very useful for doing operations without clobbering the stack #### 7.1.1 over/QI _obj1 obj2 `QI` obj1 obj2 obj1_ Make a copy of the second item on top of the stack. The direct Klingon translation for `QI` is bridge, as in a bridge over a river, which works close enough. Errors: stackUnderflow #### 7.1.2 pick/woH _N `woH` objN_ Make a copy of the Nth item on top of the stack. For example _1 `woH`_ is the same as `latlh` & _2 `woH`_ is the same as `QI` Errors: stackUnderflow, stackOverflow #### 7.1.3 rot/jIr _obj1 obj2 obj3 `jIr` obj2 obj3 obj1_ Rotate the third item to the top of the stack. Errors: stackUnderflow #### 7.1.4 depth/juv _- `juv` num_ Count the number of items on the stack and push that number to the top of the stack. Errors: stackUnderflow