Neurosis

Neurosis
Neurosis is a symbolic data structure based scripting language. It uses pattern matching and functional style programming (although it is possible to write in a procedural manner) and behaves like an expert system.

It also features a command to cause a segmentation fault (#EXPLODE), although this is not guaranteed to succeed.

Symbols are generally represented by white space separated strings. Most symbols are uniquely identified by their string. If a string does not represent any known symbol, Neurosis will automatically create a new symbol with that representation.

Syntax
The syntax is: command arguments;

Or for functions which take several different groups of arguments, command args1, args2, args3 ... (The ... is not part of the syntax)

Multiple statements should be seperated with a semicolon : command1; command2;

Unless:

1. The user is controlling neurosis through the terminal, in which case statements are entered line by line (semicolons are optional)

2. The statement is the last statement in a group of statements, in which case the semicolon is optional.

The symbols which are pre-defined are called system defined or system symbols. Generally, the string representation of system defined symbols will begin with either a "#" or "?" depending on the nature of the symbol.

Output of Statements
The output of a statement (which is in itself a list of symbols) is a list of symbols.

The output of a block of statements is always that of the last statement executed. One can feed the output of a statement to another statement by using expressions with a C like syntax: command2 (command1 arguments1); Will parse: command2 arguments2 Where arguments2 are the output of: command1 arguments1

If Neurosis is instructed to parse statements from the terminal, it will print the results of the last statement parsed to its current output stream (default standard output).

The "Hello World" Program
There are a few different ways of writing "Hello World":

#out "hello world" #n, cout;

The above method is the only guaranteed way of printing hello world to standard output.

#out "hello world";

The second method will print to standard output by default, but since Neurosis' output stream can be changed at runtime, the first method is preferred. Note: The second method will automatically print a new line (#n), but only if Neurosis' output is standard output.

?echo "hello world";

The third method is the worst, as it suffers from the same problem as the second method, and in addition an ?echo statement which is preceded by any other statement will have no effect; so the output of:

?echo "hello world"; ?echo "something else";

Will be:

"something else"

Rather than:

"hello world" "something else"

?echo should be used to set the result of a parse, or result of a function, without writing to a stream; #out should be used to specifically write to a stream. The reason ?echo in the third example will work is that Neurosis will always output the result of its final parse to its default output.

Phrased Symbols
In the above, "hello world" is a phrased symbol; ie: it is composed of multiple other symbols (in this case hello and world; but Neurosis never needs to determine what these symbols are and so they never actually physically exist in memory).

In the example: #out hello world #n, cout

Two symbols, hello and world are printed (three symbols if the newline (#n) is also counted).

In the example: #out (?at "hello world", 0, true) #n, cout The output will be: hello world

Here, Neurosis has been instructed by the ?at command to determine (creating if necessary) the symbols which make up the phrased symbol "hello world". These symbols are then printed (with a newline) to standard output.

Functions
Functions can be declared with #link function arguments -> {command/s} Or: #link function arguments -> arguments2 function2

In the above, arguments should be either specific symbols, or a pattern.

Patterns
The basic pattern symbols are:

To match any symbol: _ To match one or more symbols __ To match zero or more symbols ___ To match a string using regular expressions: @ string

For the purpose of "doing something" with a pattern or parts of a pattern, aliases can be attached to patterns using phrased symbols: "pattern, alias, condition" Is used to represent a match for pattern, which will be "aliased" with alias. The condition is optional, and if supplied will be parsed by Neurosis. The pattern is only valid if a parse of the condition (with the alias in place) yields the symbol true. (Or if the condition does not exist).

For example: "_, a" Will match any single symbol, and alias it with the symbol a.

Replacements
Neurosis will automatically replace aliases with the relevant patterns.

For example: #link foo "_, a" -> {?echo a is cool}; foo neurosis; Will result in: neurosis is cool

In some cases one might not want a symbol to be used as an alias. In this case, precede the symbol with a $ sign as in the following syntax: #link foo "_, a" -> {?echo a is $a scripting language}; foo neurosis; Will result in: neurosis is a scripting language

Manual Aliasing and Unaliasing
One can create a manual alias with the following command: #alias $alias, pattern;

From this point on within the current scope (scoping is similar to C like languages), all occurances of the symbol alias will be replaced with pattern. Note the use of the $ sign to avoid situations where the alias already had an associated pattern - in these cases, the older pattern will be overwritten.

One can remove any alias with the following command: #unalias $alias;

Example: #alias $x, 6; #alias $x, (#add x, 1); Will result in x being aliased to 7. The result of these two lines will be 7 (#alias and #unalias will output whatever the pattern set or removed was)

Other Stuff
Neurosis also has list manipulation functions. A list containing hello and world would be entered as {hello world}. Unlike phrased symbols (where "hello world" always refers to the same symbol), lists are not uniquely identified by their string representation (entering {hello world} a million times will create a million new lists, each containing the two symbols hello and world).

Expressions (stuff in brackets) are actually treated in the same way as lists, but are expanded as soon as they occur, with the internal symbols being parsed to replace the original expression.

Morphing expressions should be put inside lists or phrased symbols. They will be expanded only once, and be permanently replaced with the result of parsing the internal symbols.