February 11, 2010
dennis luehring:
> but how should the plugin-system work?

I am ignorant still about type systems. But see something about pluggable type systems: http://lambda-the-ultimate.org/node/1311


>what do the LLVM-guys think about plugin like that<

Chris Lattner, the boss of the LLVM project, has told me that he is not interested in a plug-in system for LLVM similar to the new GCC one, because LLVM has adopted kind of the opposite design strategy: it's made of loosely connected components that you can recombine and reuse to do what you want.

Bye,
bearophile
February 11, 2010
Thu, 11 Feb 2010 16:20:55 -0500, bearophile wrote:

> dennis luehring:
>> but how should the plugin-system work?
> 
> I am ignorant still about type systems. But see something about pluggable type systems: http://lambda-the-ultimate.org/node/1311

In some educational Compiler Done Right (tm) projects the various parts of the compiler might be loosely coupled clean modules, but experience shows that in real life when you take e.g. efficiency into consideration, compilers tend to get nasty. Both parser and type system are two of the subsystems that almost everything else on a compiler depends on.
> 
> 
>>what do the LLVM-guys think about plugin like that<
> 
> Chris Lattner, the boss of the LLVM project, has told me that he is not interested in a plug-in system for LLVM similar to the new GCC one, because LLVM has adopted kind of the opposite design strategy: it's made of loosely connected components that you can recombine and reuse to do what you want.
> 
> Bye,
> bearophile

February 12, 2010
I've just found a nice article about this topic, "LCA: Static analysis with GCC plugins", by Jonathan Corbet: http://lwn.net/Articles/370717/

Beside allowing plug-ins, they have done something else to GCC:
>The ability to attach attributes to objects in the compiled code makes it easy to pass hints through to later processing steps. The new pass manager brings a relatively modern structure to a compiler which did not originally have one. And the GIMPLE intermediate representation provides much of the rest of what's needed for code which needs to inspect other code.<

So now they are essentially extending the C++ type system using small JavaScript programs:
>Various other tools have been written. The final.js script (a dozen lines of code which can be seen on this page) looks for C++ methods tagged with the "final" attribute; any attempt to override those methods will result in a compilation error. It is, in other words, a port of the Java final keyword to C++. A checker which might be interesting in other environments - including the kernel - is flow.js, which can add a constraint that all exits from a function must flow through a specific label.<

The final.js code: https://developer.mozilla.org/En/Dehydra/Using_Dehydra

/**
 * Helper function: returns true if a class is marked with the "final" attribute.
 */
function isFinal(c) {
  if (!c.attributes)
    return false;
  for each (let a in c.attributes)
    if (a.name == 'user' && a.value == 'final')
      return true;
  return false;
}
function process_type(t) {
  if (t.bases)
    for each (let base in t.bases)
      if (isFinal(base.type))
        error("class " + t.name + " extends final class " + base.type.name, t.loc);
}


Then in C++ the syntax of final class is not nice:
class __attribute__((user("final"))) MyClass {

In D you can probably write the same thing as (D already has final, so this is just to compare): @final class MyClass {

I think you can implement nonnullable references too (but you can't use the nice "?" syntax for nullables).

Now please give me five minutes to dream about doing something similar using Python for D :-) It can be even possible to use D to write those scripts, especially once types become more first class values in D.

Bye,
bearophile
February 12, 2010
Fri, 12 Feb 2010 12:07:16 -0500, bearophile wrote:

> /**
>  * Helper function: returns true if a class is marked with the "final"
>  attribute. */
> function isFinal(c) {
>   if (!c.attributes)
>     return false;
>   for each (let a in c.attributes)
>     if (a.name == 'user' && a.value == 'final')
>       return true;
>   return false;
> }
> function process_type(t) {
>   if (t.bases)
>     for each (let base in t.bases)
>       if (isFinal(base.type))
>         error("class " + t.name + " extends final class " +
>         base.type.name, t.loc);
> }

That kind of code is rather clumsy. Having written couple of toy languages, I really enjoy expressing the rules as immutable declarative axioms, e.g.:

final_class_rule: node.metatype == class && node.hasBases ==> !
node.bases.exists(n => n.attributes.contains("final"))

By using declarative notion, the ambiguity of rules can be tested and rules can be verified more easily.
February 12, 2010
retard Wrote:
> That kind of code is rather clumsy.

That code is probably not the best possible way to express those constraints. But they have a good enough JavaScript JIT compiler, they know JavaScript well, so using JS for that purpose can be good enough [TM] and it can be better than not being able to do that.

Bye,
bearophile
February 12, 2010
bearophile wrote:
> Then in C++ the syntax of final class is not nice:
> class __attribute__((user("final"))) MyClass {

To be pedantic, C++ does not have final classes. That's a compiler extension.

Ali
1 2 3 4 5
Next ›   Last »