It's done!

Introduction
========

I've got a surprisingly complete parser going.  Just an example of some things you can run:

Basic maths:

    5 + 7 * 9 // Correctly gives 68.

Call a function:

    random(55)

Use strings:

    SetPlayerName(0, "String")

Concatenation and stringisation (convert variables to strings):

    "x = " .. #x

Assignment:

    a = 5
    b = a + 88
    c = d = e = 11

Arrays:

    gSomeArr[66] = gOtherArr[11]

My personal favourite:

    GetPlayerPos(0, &x, &y, &z), n = #x .. ", " .. #y .. ", " .. #z, n

That will get a player's position in to 3 variables (using your "&" syntax for refs), format a string with them all in, then return just that string.  You could miss off the last ", n" and just get the string in double quotes.  Apart from the more flexible use of "#" and the need for ".." and "&", most everything else is the same.  Even ternary operators work:

    d > c + 7 ? "yes" : "no"

Operators
=======

The following operators are supported:

```
=, ==, <=, >=, <, >, !, !=, ~, ~=, +, +=, - (infix and prefix), *, *=, /, /=, %, %=, ^, ^=, & (infix and now prefix for addresses), &=, |, |=, >>, >>=, >>>, >>>=, <<, <<=, &&, ||, (, ), [, ], ++ (prefix and suffix), -- (prefix and suffix), .., #, ", ;, (comma), ?: (ternary operator)
```

The following ones are not supported:

   : (tag override), {, }, ' (characters and number separator)

Some are identified, but aren't actually used.  Also, no keywords are supported except "false" and "true" - you can't use "if", "while" etc (unsurprising as this is expressions only), but you also can't use "sizeof", "char" etc.

Constants
=======

I'd like to add:

    ADD_CONSTANT(MAX_PLAYERS)

So you can use that directly in interpreted code with the correct value stored near compile-time, but haven't.

Known Bugs
=========

Doing:

    SomeFunction((5, 6), 7)

Will run as:

    SomeFunction(5, 6, 7)

But this ONLY applies to the first parameter, most others are fine:

    OtherFunction(5, (6, 7))

Will run as expected, eventually calling:

    OtherFunction(5, 7)

Locals
=====

As well as having access to all globals, natives, and functions in a script, this system has added per-player "local" variables.  They are:

    a - l // 12 local "integer" variables
    m, n // 2 local "string" variables (144 long)
    o - z // 12 local "float" variables

Obviously they are all lower-case letters, as is common in (lazy) code.  The integers are first so that "i", and "j" are integers, the floats are last so that "x", "y", and "z" are floats.  The strings are just in the middle.

Example
======

I also wrote a basic include to allow scripts to quickly use it:

```
#if !defined PARSER_TEXT_CHAR
	#define PARSER_TEXT_CHAR '>'
#endif

#define INTROSPECT_NATIVES
#define INTROSPECT_PLAYER_DATA

#tryinclude "introspect\exec"
#tryinclude "exec"
#tryinclude <introspect\exec>
#tryinclude <exec>

#if !defined RunExpression
	#error "introspect" is required.  Get it here: github.com/oscar-broman/samp-introspect
#endif

public OnPlayerText(playerid, text[])
{
	if (text[0] == PARSER_TEXT_CHAR)
	{
		if (IsPlayerAdmin(playerid))
		{
			printf("Running (%d): %s", playerid, text[1]);
			new
				dest[144],
				token[E_TOKEN];
			token = RunExpression(text[1], strlen(text[1]), playerid);
			RenderToken(dest, token);
			SendClientMessage(playerid, 0x66CD00FF, dest);
		}
		return 0;
	}
	#if defined Parser_OnPlayerText
		return Parser_OnPlayerText(playerid, text);
	#else
		return 1;
	#endif
}

#if defined _ALS_OnPlayerText
	#undef OnPlayerText
#else
	#define _ALS_OnPlayerText
#endif

#if defined Parser_OnPlayerText
	forward Parser_OnPlayerText(playerid, text[]);
#endif
```

Just type:

    > random(55)

Ingame and see the result.

The interpreter always prints the value of the last expression, so viewing a variable ingame is as simple as doing:

    > x

The space isn't even required.