Delphi: Closing Brackets Optional? - delphi

I have noticed quite a few times that syntax errors like
Exit(push(ASBDD(asPixmap, _ScriptSavePixmap(Script, PMRGBAdjust(_ScriptGetPixmap(Script, Args[0].Index), adjparams))));
actually compiles. Notice that one closing bracket ) is missing. (Of course it also compiles if I add this missing bracket!)
Is this a documented feature?

Additional info: The statement in question is the last statement in a code block. Inserting any statement after this statement will cause the compiler to report the correct missing ")" error.
It would appear that the compiler loses track of the missing ")" error when it encounters the end of the block. This is most likely a compiler bug. It seems likely to me that this anomaly has been around for a long time. Don't rely on it.

Related

IfThen(Assigned(Widget), Widget.Description, 'No Widget') doesn't crash. Should it?

In code that I help maintain, I have found multiple examples of code that looks like this:
Description := IfThen(Assigned(Widget), Widget.Description, 'No Widget');
I expected this to crash when Widget was nil, but when I tested it, it worked perfectly.
If I recompile it with "Code inlining control" turned off in Project - Options - Compiler, I do get an Access Violation.
It seems that, because IfThen is marked as inline, the compiler is normally not evaluating Widget.Description if Widget is nil.
Is there any reason that the code should be "fixed", as it doesn't seem to be broken? They don't want the code changed unnecessarily.
Is it likely to bite them?
I have tested it with Delphi XE2 and XE6.
Personally, I hate to rely on a behavior that isn't contractual.
The inline directive is a suggestion to the compiler.
If I understand correctly what I read, your code would also crash if you build using runtime packages.
inlining never occurs across package boundaries
Like Uli Gerhardt commented, it could be considered a bug that it works in the first place. Since the behavior isn't contractual, it can change at any time.
If I was to make any recommendation, I would flag that as a low priority "fix". I'm pretty sure some would argue that if the code works, it doesn't need fixing, there is no bug. At that point, it becomes more of a philosophical question (If a tree falls in a forest and no one is around to hear it, does it make a sound?)
Is there any reason that the code should be "fixed", as it doesn't seem to be broken?
That's really a question that only you can answer. However, to answer it then you need to understand fully the implications of reliance on this behaviour. There are two main issues that I perceive:
Inlining of functions is not guaranteed. The compiler may choose not to inline, and in the case of runtime packages or DLLs, a function in another package cannot be inlined.
Skipping evaluation of an argument only occurs when the compiler is sure that there are no side effects associated with evaluation of the argument. For instance, if the argument involved a function call, the compiler will ensure that it is always evaluated.
To expand on point 2, consider the statement in your question:
Description := IfThen(Assigned(Widget), Widget.Description, 'No Widget');
Now, if Widget.Description is a field, or is a property with a getter that reads a field, then the compiler decides that evaluation has no side effects. This evaluation can safely be skipped.
On the other hand, if Widget.Description is a function, or property with a getter function, then the compiler determines that there may be side effects. And so it ensures that Widget.Description is evaluated exactly once.
So, armed with this knowledge, here are a couple of ways for your code to fail:
You move to runtime packages, or the compiler decides not to inline the function.
You change the Description property getter from a field getter to a function getter.
If it were me, I would not like to rely on this behaviour. But as I said right at the top, ultimately it is your decision.
Finally, the behaviour has been changed from XE7. All arguments to inline functions are evaluated exactly once. This is in keeping with other languages and means that observable behaviour is no longer affected by inlining decisions. I would regard the change in XE7 as a bug fix.
It already has been fixed - in XE7 and confirmed that this was supposed to be wrong behavior.
See https://quality.embarcadero.com/browse/RSP-11531

JSLint Weird assignment, required for closure compiler

I'm using the closure compiler to minify and speed up my code but I'm running into some issues with JSLint when I try to export my functions.
Basically, I have an object, foo{} with a function, foo.bar() that gets called via an external file as. In order for this function to be called externally I need to add some declarations to my script before it gets compiled:
window['foo'] = foo;
window['foo']['bar'] = foo.bar;
This works great, but—as ever—JSLint thinks I'm mental for even attempting this. I've managed to suppress the dot notation error by declaring, /*jslint sub: true */ just before these two lines but I still get the following error:
"window['foo']['bar'] = foo.bar;" - Weird assignment
It's not wrong, it is a weird assignment out of context, but I need it in there in order for my code to work.
The way I see it, I have three possible options:
Tell JSLint not to bother even looking at them two lines.
Suppress the Weird assignment error.
Find another way to make my code work with closure compiler.
The problem is, I have no idea how to go about doing any of them.
You can export names using goog.exportSymbol instead of bracket notation: https://github.com/google/closure-library/blob/master/closure/goog/base.js#L1532
The Closure Compiler understands what goog.exportSymbol is so it'll remove the explicit exportSymbol call and add foo and bar directly to the window for you.

How can you get a detailed error descriptions in Dynamics AX?

When doing many different (obviously) wrong things in A++ syntax I only get "Syntax error" in Description and some number (Err:9999) in Diagnostic ID. This does not help me at all finding out whats wrong so I can fix it. No hint, no nothing!
This is compile time syntax errors that the IDE should just hand to me.
So how can I get more detailed information about what is wrong?
When you doubleclick on a syntax error line in the compiler output window, the code editor window opens and displays the code with the syntax error. The part of the code with the error is marked with a red squiggly underline and the cursor is placed at the start of the syntax error. This should make it easy to find out what is wrong.
In addition to what j.a.estevan suggested, in my experience syntax errors also occur because
you forget the second = symbol in the where part of a select statement
you unintentionally add a second = symbol when assigning the value of a variable
you delete a variable in the classDeclaration of a class/form, but it is still used in one of the methods
a macro is changed/deleted
an object is changed/deleted and the cross references were not up to date or not checked
There is no way of showing more information that this "Syntax error" for that error type. Almost always is a missing semicolon or brackets dispaired.

Exceptions in LEX&YACC

I'm developing a lex/yacc c compiler.
In order to handle failures and parse errors, I want to deploy an exception system handler.
Actually only a "parse error" message is handled whatever the problem is.for example:
typedef struct , struct_name{...} this input will produce a parsing error because of the extra comma.
My purpose is to throw a contextual exception,giving us the possibility to focus exactly where the problem is.such as for this example :
"Invalid structure declaration "
I really need help to solve this problème.
This will go into your parser. As it runs, it gets tokens from the lexer. If the next token does not "fit" the current rule, then you have a problem. Luckily, there already exists a section for dealing with these situations! See bison error recovery for the gnu version of yacc and how to deal with this. It'll go through the concepts, and variables to deal with just the situation you have here.

Using GCMathParser for iphone development

I am trying to use GCMathParser in my iPhone application. To compile it, I changed #import <Cocoa/Cocoa.h> to #import <UIKit/UIKit.h> and replaced pi with M_PI and successfully compiled the codes.
It works basically fine, but when I input wrong syntax like 3.3.3 or 3.. , I get syntax error as I am supposed to. But the next time I parse a very simple formula such as 5 , I still get syntax error for that. I made sure to allocate new instance to make sure it starts new, but still i get it. Does anyone have the same issue?
There seems to be a bug in the GCMathParser; however there is a way around. There is a fixed pattern : when a malformed expression is fed into the parser an exception is raised. Right after that even if a well formed expression is fed, the exception is raised again. The key point is to evaluate the well formed expression twice. First check if an exception was raised; if YES simply reevaluate the same expression. Upon evaluating the well formed expression the second time, exception is not raised.Voila!

Resources