9/02/2011

TBS alpha-2: errors?

Ominium rerum principia parva sunt.
 -Marcus Tullius Cicero

In the next version of TBS, error reporting will be improved. In addition to that, you will also be able to disable all error reporting.


You will be able to do this using a new language construct called _error. When you pass any non-zero value to this function the error reporting will be turned off. This will allow you to use a completely different syntax based on things the interpreter actually doesn't need but checks just to maintain a certain syntax. For example, we would normally output "Hello, world!" using:
!out(~"Hello, world!");
_die();

 I used red for the first thing the parser reads. This first thing is, as you can see, !out. The parser knows that ! proceeds a subroutine call and starts searching for a name. The name is found once we see a '(' because variable names can't contain '('. Now that we found a '(', I marked it green because it's the next step,we start looking for the arguments. And so, TBS starts looking for the arguments. The first thing it finds is the '~' char(marked in blue). Now TBS knows that the first argument is a string. So it knows that it needs to read a string expression. The next thing the parser finds is the first(and last) part of the string expression: a string(marked in black). So now that we have the first(and again, last) argument TBS starts looking for a second argument. Instead, it finds ')' so it knows it reached the end of the arguments list. Now comes the important part, the last char ';'(yellow) is actually not at all needed. "Then why is it there?", you may ask. Simply because I find it much more clear to end every line with a semicolon. Yes, it requires some more typing, but really: when we can just type ?name = 5.5; instead of double name = 5.5;, what does it matter?
When TBS doesn't find a semicolon at the end of the statement, an error will be shown(this will be similar to Fatal Error: expected ';' after subroutine call). However with the new _error construct this is what changes. When we do not report errors, no error will be given. Now you might think "Aha, that's nice, no more instruction separator for me!" but be careful: TBS still reads the character(actually token) but simply ignores it completely. This means that you need to replace the semicolon by another token, for example a string or a number. So we could also output "Hello, world!" using the following:

_error(1);
!out(~"Hello, world!")"This will be ignored as TBS considers a string as one single token."
_die();
As you can see, we just replaced one token with another and no errors were reported because of the first statement. Why is this all needed? This is extremely useful for obscuring/obfuscating code( ☺ ). Just a simple example:
_error(1);
?n=10
@n=5;
_die();
 Tricky question: is n 10 or 5?
Answer :

For someone who doesn't know that we can alter the syntax with _error, n will seem 10. However, if you do know we can, you will see that we just used @ as the instruction separator. But that's not just it: you would normally expect the parser to read the comment as one token(because that's what happens with strings and numbers) but comments are an exception! So in fact we do not need a semicolon on the end of the comment(Note that in a normal comment all characters are ignored until we find a semicolon). So the answer is 5.
I hope you found this interesting, please make sure to comment and share your thoughts on this interesting new feature!

2 comments:

  1. It seems intereesting... :)
    You always have been into obfuscation, however, I feel that maybe some more example programs would be better? Also, does TBS support system calls?

    ReplyDelete
  2. @ramber
    Yes, some more example programs might be better I'll make sure to write some.
    And no(I just hadn't thought of it), but I'll add it to alpha-2.

    ReplyDelete