I was able to compile and run the following code
x = 10
x = x + 1
Yeah, stupid, innit? You may look closer and realise that
- 'x' is an undeclared variable
- 'x' type is thus not defined
- 'x''s type is inferred based on operations of attribution that follows the first appearance
So x goes to a SymbolTable. Every assign expression that uses it is registered as a candidate on the SymbolTable entry. During the type resolval step it's easy to resolve the type of the first assign:
x = 10 # this is a int32 constant, nothing to compute here
Now the second is trickier:
x = x + 1
We're now trying to infer the type of a variable based on an expression that uses it.
Anyway, this is something I need to research more. My naive implementation is shameful.
The IL code generated is:
.method public hidebysig static void xpto() cil managed
{
.entrypoint
// Code Size: 15 byte(s)
.maxstack 2
.locals init (
int32 num1)
L_0000: ldc.i4 10
L_0005: stloc.0
L_0006: ldloc.0
L_0007: ldc.i4 1
L_000c: add
L_000d: stloc.0
L_000e: ret
}
Which as you can see doesn't have even the minimum of optimization, which should produce
.method public hidebysig static void xpto() cil managed
{
.entrypoint
// Code Size: 15 byte(s)
.maxstack 2
.locals init (
int32 num1)
L_0000: ldc.i4_s 10 # within a byte range, use the short form
L_0005: stloc.0
L_0006: ldloc.0
L_0007: ldc.i4_1 # same thing
L_000c: add
L_000d: stloc.0
L_000e: ret
}
But still better than the version produced by IronPython :-P
I'm still not convinced about construction a 100% dynamic language. A hybrid would be best, but I'd like to hear opinions.