for(%i = 0; %i < getWordCount(%string); %i++)

%len = getWordCount(%string); for(%i = 0; %i < %len; %i++)

%pos = VectorAdd([1, 2, 3], [4, %y, %z]); // Which compiles to %pos = VectorAdd("1 2 3", "4" SPC %y SPC %z);

%greeting = "Hello, @{%name}!"; // Which compiles to %greeting = "Hello, " @ %name @ "!";

%data = ContainerRayCast(...); %hitObj = getWord(%data, 0); if(%hitObj) { %hitPos = getWords(%data, 1, 3); %hitNormal = getWords(%data, 4, 6); }

[%hitObj, %hitPos, %hitNormal] = ContainerRayCast(...);

[%hitObj, %hx, %hy, %hz, %nx, %ny, %nz] = ContainerRayCast(...);

[%hitObj, %hitPos 3, %hitNormal 3] = ...

function giveMeData() { return "word word" TAB "tab" NL "newline"; // Or, return ["word", "word": "tab"; "newline"]; } [$a, $b: $c; $d] = giveMeData();

schedule(1000, function() { echo("Hi."); });

VectorAdd(VectorAdd(%a, %b), %c); // becomes %a ^vectorAdd %b ^vectorAdd %c;

I've been thinking about this for some time, and it's been bugging me enough that I figured I'd step out and gauge interest. What I want to do is implement a preprocessor for TorqueScript. Not like the C preprocessor, but nearly a full-on compiler that parses your scripts, does any useful steps in the middle, and outputs the actual TorqueScript that your game runs.Some 'preprocessing' steps I would want to implement are:For example, detecting when a local variable is constant (i.e. it's assigned a value only once) and replacing further occurrences of it with its value. Should save some name lookups. Or another example - pulling complex expressions out of for loops and such. This is a bit of a tricky one, but consider this:getWordCount is called every time the condition is checked. It's more performant to write this:But why do that when it should be the compiler's job? Of course, it can't always be like this, particularly if %string can change length over the course of the loop. Which the compiler would have to check. It also doesn't work if the function called (in this case getWordCount) isn't pure, and may return a different result given the same input. But 90% of the time this holds. You could go all sorts of directions with this, replacing constants doesn't even scratch the surface of the possibilities.For example, plain-language operators like 'and' and 'or' instead of '&&' and '||'. Also, maybe, removing the % prefix for local variables to make code that little bit more modern/readable. Maybe removing the requirement for semicolons. It's all up for grabs.Since strings are so important in TS, I'd love to implement new ways of putting them together. One way to do this is vector notation:Another way is string interpolation:This is a huge one that I'd love to try. Before I explain, here's a code example:I haven't even had to write that snippet many times, but it gets boring. And returning multiple results as words in a string is a common pattern in TorqueScript. So it'd be much nicer to write something like:using the vector notation above to pull groups out of the word-delimited string. Note that this doesn't work entirely as given, because the second two parameters take 3 words each. So in a basic implementation you'd be looking atWhich isn't awful, but could definitely be improved. Maybe like this:providing word lengths for sequences that are > 1 word. There should also be syntax for destructuring records (newlines) and fields (tabs):Like:This is a pretty easy transformation to make naively - just pull the function out into the global namespace and replace its use with an auto-generated name - but there are tricky things to implement like how it handles scope and binding. On the other hand, it'd be very easy to not even try to match other languages on that, since TorqueScript doesn't do that anyway.So, who's interested in the possibilities? I'd love to try this just from the point of view of implementing my own language/compiler, and because I think TorqueScript lacks some usability.EDIT: Two more ideas I forgotVector maths is a bit painful, thanks to the way we need to use global functions for everything. But what if there's another way:I'd propose using a backslash (it got eaten by the code block, so I used a caret instead) or something to allow functions of two arguments to be called as infix operators to make code read more nicely.You know, where names aren't available to you unless you've imported the appropriate model. The compiler would then need to do some wizardry to determine which files need to exec which others, but hey, with modern science I'm sure we can come up with something.