ref: 2219ea535f4a0fd0afd9000ba5c6918c6b276210 Carth/src/Pretty.hs -rw-r--r-- 4.3 KiB
Less desugaring in Parse (do in Infer instead), more concrete Parsed.

Step towards improving error messages. Among others, the function-related ones can
end up misleading due to bad SrcPos:s given to nodes generated from desugaring.
More human readable names for implicit type vars

Before: #2760, #2454
After: •ca44, •zb7
Add primitive, single pattern macros

E.g. `(defmacro (plus a b) (+ a b))`
Make parser act on token trees instead of chars
Add skeleton module Optimize between Monomorphize & Compile
when debug, write file ".dbg.gen.ll"
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

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 F16, F32, F128

Also, fix inconsistencies with "FNN" vs "FloatNN" vs "Double". Now,
always "FNN", e.g. "F64".
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

    (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.
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
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.

    (: (transmute (: 4623716258932001341 Int)) F64)
results in
    (: 13.37 F64)
Get rid of Parsed.Fun. Desugar to FunMatch already in Parse.
Rename Double to F64 in the compiler
`fun-match` -> `fmatch`. Shorter to type, which matters quite a bit.
Impl types Union, Bool using existing data-type mechanics

No more special cases in TPrim, just implement them as normal
data-types instead. They're declared in Check.hs, and we ensure
they're generated in initInsts in Monomorphize.hs. Other than that,
the compiler barely has to know they exist!