Eigenstate : Myrddin News - Sept 2015

Not Dead, Just Resting

While I've been very lazy about updating the website, in the time since the last update, there have been nearly 300 changes pushed in, all of them improving or fixing some thing. And that's only in the main repository. There have been a couple of nice utilities outside of that.

I'm actualy myself writing actual code in Myrddin on a regular basis. I may have to remove the 'Delusions of Usefulness' bit from the main page some day, since it no longer seems to be a delusion.

C ABI Compatibility. Mostly.

This is going to be extremely useful, since you can now wrap up C libraries in Myrddin, and call into them. There are still lots of rough edges with this, for example:

Howl Support

Ryan Gonzalez has contributed support for the Howl editor:

https://github.com/kirbyfan64/howl-myr

Formatting

The format API has changed. The most visible change is that the value placeholder is '{}' for all types, and we figure out how to show the type at runtime, instead of counting on the user to get this right. For example, you might have done somthing like:

std.put("%s is %i\n", "foo", 123)

This has changed to:

std.put("{} is {}\n", "foo", 123)

Attributes to control how formatting works are put into the braces, in the form of either keys or key value pairs:

std.put("{x,p=0,w=4}", 123)

Will print

007b

Since we have requested a hex value, padded with 0, with width 4

To escape a '{' or '}', double it like so:

std.put("{{}}")

You can also install custom formatters for types, meaning that std.put can be used to print whatever you want.

std.fmtinstall(std.typeof(x), myformatter, [][:])

For full details, refer to the docs.

Runtime Type Information

Myrddin now generates information for types. You can get at it using std.typeof(var), and introspect it with libstd. the type introspection code could stand to be better documented, but it lives here:

http://git.eigenstate.org/ori/mc.git/tree/lib/std/introspect.myr

Threading

There's currently an exploratory libthread in the works. At the moment, it's linux only, and only has a couple of primitives, but it works. When it supports all of the platforms that Myrddin supports, it's going to be shipped with mc.

The API is still up in the air, and I'm trying to figure out exactly what I want the idioms to be.

For now, it lives at http://git.eigenstate.org/ori/libthread.git/tree

Parser Generator.

There's an experimental parser generator in the works, named hairless, since it's the result of yacc shaving.

It's at a state where it's useful, but there's a lot of work still to do, including moving from SLR to the IELR algorithm, improving error generation, and generating counterexamples for ambiguity, so that figuring out shift/reduce errors becomes tractable.

It lives in http://git.eigenstate.org/ori/hairless.git

OS Support

FreeBSD support had been contributed nearly a year ago, but had bitrotted. Support was fixed this release, and should be maintained in the future.

Plan9 support has also been updated to the most recent version. This has been tested on 9front.

Other Fixes

Theres' a ton of other work done to stabilize and improve things. For a full log, you can look at the commit history, but I'l attempt to summarize here:

mbld test

You can now create tests and run them implicitly. If you have a library consisting of

foo.myr
bar.myr

Creating the files

test/foo.myr
test/bar.myr

Will lead to them being compiled and run as tests.

Improved error messages

Instead of some random junk, we try to do some basic pretty printing of the expression. So, for example, we get errors that look like this:

example.myr:2: byte[:] needs trait numeric near <e1:byte[:]> + <e2:int>

New CLI option parser

The getopt like API has been replaced with a descriptive api that autogenerates help messages:

cmd = std.optparse(args, &[
    .argdesc = "[inputs...]",
    .opts = [
        [.opt='e', .desc="example option"],
        [.opt='a', .arg = "arg", .desc="another example"],
    ][:]
])

for opt in cmd.opts
    match opt
    | ('e', ""):    std.put("got example")
    | ('a', arg):    std.put("got example with arg {}", arg)
    | _:    std.die("unreachable")
    ;;
;;