Archive for the ‘Scripting’ Category.

Introducing DFMJSON, the DFM parser and scriptable bulk editor

Yesterday at work, while tracking down a graphical glitch, I found that TPanel objects on many, many dialog boxes in our system (over 300 of them) had a certain property set incorrectly.  There are basically three ways to fix something like that: Continue reading ‘Introducing DFMJSON, the DFM parser and scriptable bulk editor’ »

DWS Externals progress

I’ve been working on the stub-building JIT for external routines in DWS lately, and I just checked in a bunch of updates.  The JIT will currently handle parameters of most basic types, and return values of integer, enumerated, or object types.  (Still working on the rest.)  So it’s not complete yet, but it’s getting there. Continue reading ‘DWS Externals progress’ »

Expression Trees: abusing operator overloading for fun and profit

Quick, what should this routine produce?

[code lang="delphi"]
procedure Test;
var
   expr: TExpression;
   result: string;
begin
   expr := 'Value';
   expr := expr = 5;
   result := expr;
   writeln(result);
end;
[/code]

There are three basic answers here:

  1. Wait, you’re assigning a string to it, and then a boolean comparison against an integer… does that even compile?
  2. Well, first you’re assigning a string, then a boolean comparison against an integer, then turning it into a string… well, TExpression must be some sort of thing like a Variant.  So the output should be “False”.
  3. If TExpression is a record, the output could be just about anything.

If you answered 3), you’re probably Stefan Glienke, or someone like him who already knows the trick.  When I do this, the output is “(Value = 5)”.  If you want to know how that’s possible in ordinary Delphi code, read on. Continue reading ‘Expression Trees: abusing operator overloading for fun and profit’ »

External routines in DWS

I’ve been working with Eric Grange on adding a new feature to the DWS compiler recently: external routines.  The goal of this feature is to allow DWS code to call into native routines like Delphi code can call into routines in a DLL by writing a function signature and marking it external, without having to use a TdwsUnit component and create a bunch of heavy-overhead binding code. Continue reading ‘External routines in DWS’ »

Delphi and Productivity

If you haven’t seen Gabr’s latest post about Delphi language features, it’s worth looking at. I don’t agree with everything he posted, but he’s got some good points.

But he’s also got some annoying problems in the comments department.  Some obnoxious troll is spamming up almost half of the (extremely large) set of comments under the post with a bunch of preaching about how Python is soooo much better than Delphi because it’s less verbose.  His thesis seems to be that since you can write equivalent functionality with (as he claims) one-tenth the lines of code, that Python is ten times more productive than Delphi. Continue reading ‘Delphi and Productivity’ »

More dwsLinq improvements: query sources and JSON

When I started writing dwsLinq, I never intended it to just be an integrated SQL query builder.  I did that first because it was both useful and easy to implement, but that was never the end goal.

Over the last few days I’ve taken a big step towards the real goal: developing a general-purpose data querying system.  I factored out all of the SQL-specific stuff into its own unit and created an interface called IQueryBuilder that responds to the various query operators to build an expression tree that can be evaluated by DWS.  You create a recognizer and register it with dwsLinq, that checks the value of your FROM expression and returns an IQueryBuilder if it can create an expression for it.  And once I had that working, I created a second unit with a new implementation of IQueryBuilder, for querying JSON data. Continue reading ‘More dwsLinq improvements: query sources and JSON’ »

dwsLinq update: INTO

I just checked in an update to dwsLinq that covers a big step in its progress: the INTO clause.

This is not quite the same thing as INTO in C#’s version of LINQ.  INTO there basically acts as a naming operator, taking a query expression and giving it a name so that you can use it as a sub-expression in further query work.

I did something different with this.  INTO in dwsLinq takes a function pointer as its argument.  The function has to have a single parameter of type Dataset, and return some value, and the INTO clause changes the output of the entire query expression. Continue reading ‘dwsLinq update: INTO’ »

Work in progress: dwsLinq extension for DWS

I’ve always enjoyed the concept behind LINQ: write SQL-esque queries directly in your code, with the compiler able to provide syntactical and type checks, and automatically generate the correct code to do what you wanted.

Unfortunately, there’s nothing like that available for Delphi.  There could be, if the team would shift their focus to augmenting the language with actual useful features borrowed from managed languages, such as a proper extension method implementation, rather that burdening it with useless, counterproductive crap like pseudo-garbage collection and new String models.  But for the time being, we’re out of luck.

It could be done in DWS, but LINQ is a really complex system that makes heavy use of lambdas (aka anonymous methods,) which Eric Grange hasn’t gotten around to supporting yet outside of the JavaScript cross-compilation.  Apparently it’ll take a complete re-architecting of the execution model to make anonymous methods available.

But a while ago, an idea struck me.  In .NET, LINQ uses anonymous methods to support expression class evaluation at runtime.  But DWS is already an interpreted scripting system that operates on an expression tree!  And since DWS has a language extension mechanism in place, I decided to poke around and see what was possible. Continue reading ‘Work in progress: dwsLinq extension for DWS’ »

You can’t remove open-source code from public use

I commented a couple days ago on Smart Mobile Studio’s release and how happy I was that they’d found a payment processor that minimizes the hassle for users. Well, I’m a bit less pleased at the stunt they tried to pull this morning.

There’s a post over on the Smart Mobile Studio dev blog explaining that, due to an arrangement between them and the company that Eric Grange works for, they’ve obtained the exclusive rights to DWS’s Javascript code generator, and it’s

hereby withdrawn from public use. Any company currently deploying this technology, or a derivative of it, is bound by international law to abandon it.

Well, there’s just one problem with that: they can’t do it.  The JS codegen units, like the rest of DWS, were published under the Mozilla Public License, with an MPL header at the top and everything, and the MPL grants those who download the code

a world-wide, royalty-free, non-exclusive license under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work.

The only ways that a license grant under the MPL can be terminated are specified in section 8: if the licensee fails to comply with the terms of the MPL, or if the licensee tries to sue the developer.  It very conspicuously does not say that the developer can revoke the license.

Even Borland understood this.  They never tried to strip InterBase (which they published under the MPL at one point) of its open-source status when they decided they wanted to keep working on it as a proprietary project.  They just stopped contributing to Firebird, started pretending like it didn’t exist instead, and kept working on InterBase and trying to differentiate it with new and better features.  And they certainly didn’t assert that people using or developing Firebird were in violation of international law.

This would be the best course of action for Optimale Systemer AS to take as well.  They’re free to continue further, proprietary work on it, and now they’ll need to if they want to differentiate it from what’s already out there.  Anyone else is still free to use, or even to fork and continue working on, the existing code.  (Which, by the way, has been deleted from SVN in the Google Code repository’s head, but is still available if you check out to revision #1462.)  Their current position is legally untenable, claims of “international law” notwithstanding.  It would never hold up in court, and I certainly hope they don’t waste any resources proving that.  They’d be much better spent continuing to improve their product.

I wonder if any other developers will be willing to take up the mantle and continue work on the open-source JS codegen, the way Eric did for DWS itself after Matthias Ackermann stopped working on it?

RTTI Script alpha release

Way back at the start of this year, I wrote about how I’d been working on a new Object Pascal-based script engine built around Delphi’s extended RTTI system.  And then it got real quiet, because more immediate concerns took priority for me.  But I’ve gotten to the point in my game engine development where I really need to put in the scripting system, so I spent the last couple weeks finishing up the implementation and tuning the performance a little, and now I’ve got an alpha version ready.  If anyone would like to try it out, they can find it on Google Code.

Continue reading ‘RTTI Script alpha release’ »