Wednesday, July 20, 2011

Leaky Shift

Sometimes it helps to bounce ideas against other people, so thanks to LtU/MattM for getting something right. I hacked together a solution once to deal with the translation of exceptions, try/catch and throw blocks. I looked a bit at shift/reset, found it too difficult to implement, and tried to implement something more trivial with two combinators.

  R f = f S (remember the current context in S)

  S x = x   (but also, whenever S evaluates it replaces the original R f term)

An example:

  1 + R (\s -> 1 + s 3) = 1 + (\s -> 1 + s 3) S = 1 + (1 + S 3) = 1 + 3 = 4

The problem, of course, is that you don't want an S combinator to leak outside an R term. I was aware of that, but -rather unconvinced- thought it may go right.
Try/catch blocks are translated to a somewhat difficult lambda term employing R. The general thought -I more hoped than convinced myself- is that either an exception is thrown (and an S is eaten), or a value is produced (and introduced S's are lost). I.e., no leaks.

A post-mortem analysis of what I did:

It works, but it also dawned to me that it may only work at the moment since I only compile straight-forward code in the bootstrap compiler. The problem occurs when translating try/catch blocks which return functions. A contrived example:

  f = try [ x -> x / 0 ] catch [ NaN -> throw "division by zero" ];
  f 3

I didn't try it yet in real code, but I am pretty sure that the result would be that the thunk which holds f would be overwritten with the thrown exception instead that an exception is thrown. Fortunately, it also looks like it is fixable.

One solution would be to remove exception handlers from curried thunks, and reinstall the right ones of the context with employed @ combinators, but it would be difficult to get all invariants right.

Another, better, solution would be a bit different compilation scheme where the curried thunk f is guaranteed not to also contain the exception handler, and  f 3 is translated to f (exception-handler) 3, which would be more straight-forward. I should check whether I didn't translate to that by accident. Ah well, back to the drawing board.

A last, best, solution would be to assign to f not the lambda abstraction, but the whole try-catch block. That should do nicely. And I may even have done that by accident? Again, I should look at the code.

Wednesday, May 25, 2011

-fno-strict-aliasing

Aliasing describes a situation in which a data location in memory can be accessed through different symbolic names in a program. I use aliasing a lot in the garbage collector, it was a wrong assumption on my part on the semantics of the C language. Turns out, aliasing is not supported by default to make some optimizations work.

The problem is that I need aliasing. Thunks are supposed to consist of memory cells which mostly hold integers or pointers, but sometimes they hold boxed character lists, floats, doubles, or whatever what one would like to store in a constant.

I am not really writing on the compiler at the moment, but -as I am dropping the dependency on libffi- I would like to drop the compiler switch which turns strict aliasing off, thereby making aliasing possible...

I am not sure there's even a compatible manner in which to support this.

Update: Strange, the standard makes an exception for char pointers, so I guess that I'ld need to support that. Can't I use this in a reverse manner using a char pointer as an intermediate?

Update: It may be impossible if I read this rant.

Update: Sometimes a question and answer isn't defined well; the guys at comp.lang.c helped me figure it out. If I want to compile with strict aliasing, I just need to make sure that pointers of different type refer to different values. (Or, stated differently, it's a rather silly idea wanting to alias stuff where strict aliasing tells one you cannot.) So, wherever I cast/alias stuff now, I'll need memcpy. Hope that is sufficient.

Saturday, April 30, 2011

Log 043011

I removed the embedding functions and introduced a native keyword into the compiler. Now, like in most other languages, external definitions are just given, for example, such: native inc: int -> int. I.e., the name and type are given but the body isn't.

I now need to build a new runtime which makes use of this.

Monday, April 25, 2011

Dropping libFFI

I don't like the dependency on libffi anymore. The prime reason being that it becomes near impossible to treat strings as character arrays. The second reason, I expect problems with it when compiling on different platforms - it drops a dependency. The last reason, despite that everything -especially the definitions of external terms- becomes more bloated, it will simplify the compiler and make native function calls a lot faster.

So long, C...

MLs Value Restriction

Don't generalize mutable type unknowns

Sunday, April 24, 2011

Hi Gambit

I am thinking of changing the back-end to Gambit...

And decided against it.

Friday, April 22, 2011

Compiler with Sources now for Grabs

Get the compiler sources from http://www.hi-language.org/ if you care. I probably should have cleaned up the source code, but then again, why bother at the moment?