~jojo/Carth

change syntax from defvar to def

Now defun reads as a contraction of def and fun.

    (def   twice (fun [f x] (f (f x))))

    (defun twice      [f x] (f (f x)))
Print backtrace on panic if --debug is set

Compile the following with "--debug" and run

    (import std)
    (defvar main (io/wrap (foo Unit)))
    (defun foo [Unit] (bar Unit))
    (defun bar [Unit] (panic "oops"))

You will get an output like

    *** Panic: oops

    *** BACKTRACE
    3: panic :of (Fun [Str] Unit)
    2: bar :of (Fun [Unit] Unit)
    1: foo :of (Fun [Unit] Unit)
    0: main

Nice -- way more convenient than having nothing!
It is still quite limited though.

- You only get the function name and type, not source position.
- Only named carth functions show up. Generated ones & externs don't.
- It probably costs quite a bit of performance. Each push to the
  backtrace requires a heap allocation.
std: fix parse/lift2 & add str=
error msg on unexpected de Bruijn index
Add syntax sugar for lambdas, De Bruijn notation

    \(+ # 5)
is now equivalent to
    (fun [x] (+ x 5))
and same goes for
    \[# #]
and
    (fun [x] [x x])
Change syntax of Fun type to match changes to fun expr

Now they all match

```
(defun add [a   b  ] (+ a b))
(fun       [a   b  ] (+ a b))
(Fun       [Int Int]     Int)
```
Update TODO
Change syntax of defs & funs. Make it more like clojure

```
(defvar x 123)

(defvar x :of Int
  123)

(defun add [a b] (+ a b))

(defun add [a b] :of (Fun Int Int Int)
  (+ a b))

(defvar add
  (fun [a b] (+ a b)))

(defun or-0
  (case [(Some x)] x)
  (case [None] 0))

(defun or-0 :of (Fun (Maybe Int) Int)
  (case [(Some x)] x)
  (case [None] 0))

(defvar or-0
  (fun
    (case [(Some x)] x)
    (case [None] 0)))
```
std: have iter/cartesian return const list instead of pair

Better synergy with other APIs I think. E.g. array/lookup2d.
Align expected/found in errors
fix parser behaviour & errors on partial match
Add C codegen backend

Now you can run `carth compile` with either `--backend=llvm` or
`--backend=c`.

The generated C code looks fairly similar to the generated LLVM IR. In
some ways, `Low` is a bit *too* low for translating to nice looking C,
so the output is fairly verbose. There are a bunch of redundant
intermediary variables used, and most everything is in three-address
code. But it works!

----------------------

Notable changes include:

- New Link step, separate from Compile. Use `mold` (via
  `cc-fuse-ld=mold`) by default.

- Alternative, primitive test-runner: `run-tests.sh`. No more
  "collecting from another thread nagging.

- What I've been calling "pass by reference" in the context of C ABI
  isn't actually passing by arbitrary reference, but passing on the
  stack specifically! So just passing an argument behind a pointer is
  not at all necessarily compatible with a function expection the type
  passed on the stack. The `Pass` type in `Low` is at the centre of the
  fix for this.

- Add name mangling, common for all backends. In short, all global
  symbols in generated code now begin with "_C<LEN>H<NAME>", where LEN
  is the number representing the length of the NAME. For example,
  "_C4Hfold" (which after resolving conflicts might become
  e.g. "_C4Hfold_3"). This is to prevent collision with symbols from
  linked libraries.

- Pass Loop arguments in "register". Sharing a single stack allocation
  for an argument between iterations was just begging for trouble.
Handle enums in Lower.asVariant

It was already partly implemented, but full support was only there for
tagged unions. Trivial to fix though.
Use GlobalId for enum variant names. Share namespace w types

In C, enum variants and typedefs share namespace, so we might as
well. No good reason not to. Saves us some pain in CompileC.
std: make array/iter safe by panicing on out-of-bounds

Note that it shouldn't ever be able to even reach this, unless there's
a compiler bug or a bug in xrange in stdlib, but the fact is that
there well may be! This way, at least I get a slightly useful error
message from my tests when I've goofed up something in the compiler.
std: better error msgs fr array/{mutate,lookup!}
Pass fun args on stack correctly & always pass loop args by val

It turns out that big structs in C aren't actually (necessarily?)
passed by reference, but rather passed on the stack specifically. It
may thus be incorrect to treat what I called a "pass by reference"
argument just the same as a pointer value argument, and give it a heap
pointer. I checked it out on godbolt, and unless my mind tricked me,
that was the situation.

The other thing is that Loop arguments must be copies on each
iteration, just like a stack frame has to be copied in
recursion. Otherwise we reuse allocations in a bad way.
Mangle names of globals / functions

To play better with the C backend mostly. I had the issue that my own
`abs` shadowed / redeclared the builtin `abs`, and with a different
type signature as well.

Now, all globals are prefixed with "_C<LEN>H". Identifiers beginning
with underscore followed by uppercase letter is reserved in C, so that
means there ought not to be any conflicts with user written functions
when we link against external symbols.
Allow referring to struct members by name in Low

and do this for `closure` & tagged unions. It just clears up the
generated C code a bit.
Fix breaking loop from within nested switch in C backend
Next