~jojo/Carth

ref: ae1d242d7d48292779dcbd953e5864bb4211e1ca Carth/src/Inferred.hs -rw-r--r-- 5.1 KiB
Update stackage release & use default-extensions in cabal file

Also, fix some minor breakages caused by ghc update, fix the
literate.org example, fix some new warnings, and get rid of the need
for a bunch of Data implementations by using basic parsing functions
in SystemSpec.hs.
Include macro expansion trace in SrcPos. Better err msgs!

    POS1: Error:
      CODE
    MESSAGE

    POS2: Note:
      CODE
    In expansion of macro.
Make GC_malloc take NatSize instead of IntSize

I mean, how the heck do you allocate a negative amount of memory, right?
Make (i8*) the generic ptr type instead of ({}*)

I just think it will play nicer with LLVM. Everything gets messy when
zero-sized types are involved.
Extract tests from CheckSpec to individual files in test/tests/bad

SystemSpec now runs those and verifies the type errors match what's expected
Define carth type literals only once in TypeAst

Like mainType, tUnit, etc. Use the class TypeAst to allow them to
construct any Type, e.g. Parsed.Type.
Add builtin virtual `ashift-r` arithmetic shift right

Which for signed integers mean keeping the topmost bit -- the sign --
intact, only shifting the remaining ones to the right.
TNat8, TNat16, ... -> (TNat 8), (TNat 16), ... & add TNatSize

Instead of having hard-coded sized variants for integer types, just
have a bit-width field. Fewer variants => better, also this will allow
for arbitrary bit-width integers if we want that (I think it could be
nice).

Also add the T{Nat,Int}Size variants, which look like {Nat,Int} in
carth source. They are like {u,i}size in Rust and size_t in C -- an
integer of the same size as a pointer. 32 bits on 32-bit platforms,
and 64 bits on 64-bit platforms. Won't actually work for 32-bit right
now, as a bunch of stuff is still hard-coded to 64, but that can be
changed in the future.
Add builtin virtual `cast` to cast between all primitive num types

So between integers of different sizes, from float to int, and from
int to float. Also almost accidentally includes casting to and from
enums, as they are seen as integers at the time the types are fully
checked in genCast.
Make deref and store builtin virtual functions as well
Make transmute a builtin virtual instead of a whole AST variant
Implement binops as "builtin virtual functions"

This way, they only need to be declared for the typechecker and
handled in the codegen, but they don't need to exist as variants in
the AST for the intermediate compilation steps. Some existing variants
could maybe be handled this way too, like transmute.
Split let into let1, let, letrec

let1: Bind one variable to one value in body. Can shadow.

    (let1 x 3
      (* x x))

let: Sugar for nester let1:s, which means it's not like the old let,
in that it shadows, requires bindings to be in order, and cannot be
recursive.

    (let1 x 3
      (let ((x x)
            (y x)
            (x 5)
            (z x))
        (cons y z)))
    ;; Ok: (Cons 3 5)

letrec: Pretty much exactly like the old let. Bindings exist in the
scope of their own bodies, so functions can be recursive and shadowing
is not possible. If a non-function variable is found to be recursive,
the type checker throws an error. Bindings are automatically ordered
in topological order.

    (let1 x 3 (letrec ((x x)) x))
    ;; Error

    (letrec ((x y)
             (y 3)
             (fact (fmatch (case 0 1) (case n (* n (fact (dec n))))))
             (foo (fun (x) (bar (dec x))))
             (bar (fmatch (case 0 1337) (case x (foo x)))))
      (cons* x (fact 5) (foo 100)))
    ;; Ok: (Cons* 3 120 1337
Change formatting: 90 cols, IndentPolicyFree, etc. Add brittany.yaml

Most people have pretty wide and high res screens at this point. I
can't fit two windows with 100 line length next to eachother with my
font size, but 90 works and most people have smaller font size than me
I think.

Also, change brittanys indentation policy to Free. This almost always
looks better. I just had to disable formatting of imports -- I don't
want to align those, but IndentationPolicyFree insists.

Finally, actually add a project-local brittany config file, so that
anyone (or me in the future / on another computer) can use the same
formatting rules.
Refactor global & let definitions

Instead of jumbling together function and var defs and just checking
which is which at the end in Codegen, treat them very separately and
remember the grouping for recursive defs.

For now, just moves around complexity really. I don't remember how
exactly, but I thought this would be necessary for the next feature,
which is allowing patterns in left hand side of var defs.
Replace `box` special form with `sizeof`

The special forms `sizeof` + `store` can be used together with a call
to the function `GC_malloc` to implement `box` as a standard library
function.
Use Inferred.builtinExterns to expose builtins both to user and Gen

Gen.builtinsHidden - Builtins only usable with Gen.callBuiltin

Inferred.builtinExterns - Available both to the user and
Gen.callBuiltin. Passed through the stages to end up as
Gen.withBuiltins.builtinExterns.
Move checkExterns from Infer to Check
Add `store` special form to write to `Box` pointer
Add `transmute` special form

Use to change the type of an expression without modifying the bits in
any way -- just interpret them as if they represented the new type.

Example:
    (: (transmute (: 4623716258932001341 Int)) F64)
results in
    (: 13.37 F64)
Next