- Primitives can now signal an error.
- An error prints a callstack and ends the current (and right
now only) fiber.
- Arithmetic operators error if the operand is not a number.
- Real error for method not found.
- Associate source file name, and method names with functions.
- Debug line number info for functions.
Unfortunately, this regresses perf on fib about 15%, mostly
because of the better checking in arithmetic ops.
There's still a bunch of clean up to do, but this is a big step
in the right direction.
Currently, they have a hardcoded number of constants and
bytecodes. That wastes memory in most cases and fails
catastrophically when there is too much bytecode.
To fix this, we should use growable buffers for both during
compilation and then only create the FnObj when done compiling.
This moves a bunch of stuff around and gets it to the point
where functions are created at the end of compilation. It
doesn't yet size functions appropriately, but all tests are
passing, so this is a good checkpoint.
There's no point in packing it in a Value since it will always
be an ObjFn or ObjClosure. Leaving it an Obj* is a bit faster.
Also fixed a bug where it was freeing the closure's flexible
array of upvalues.
Added ".." and "..." infix operators. Num implements them to
return Range objects. Those in turn implement the iterator
protocol, so now numeric for loops are easy:
for (i in 1..10) { ... }
I also cleaned up the Wren benchmarks to use this.
In the process, I discovered the method_call benchmark really
just showed loop peformance, so I unrolled the loops in all of
the languages to stress method calls.
They are now invoked like "new Foo".
Also, superclass constructors are now much less semantically
and syntactically weird. Since the instance is created before
any constructor is called, there's no point in time where the
instance isn't there.
This also fixes a bug where constructors weren't being bound
correctly, and eliminates some unneeded instructions when
compiling ifs.
I also tweaked the other method_call languages to match Wren's.
Since Wren needs to do a super call to get to the parent _count,
the other languages do now too.
This is nice too because it means we're benchmarking super
calls.