1
0
forked from alex-eg/sex
Commit Graph

14 Commits

Author SHA1 Message Date
1f445f0f9b implement type inference
Two things out of one mechanism. `_' as a type means "work it out from
the initializer", so (var n _ (strlen s)) stops needing size-t spelled
out; `type-of' hands a macro the type of an expression, so a macro can
dispatch on what it was handed rather than on what was declared. Both
read the same answers from two sides.

Algorithm W's core, intra-procedural, with the extensions C forces:

  - an unknown type, since (include stdio.h) brings in names we never
    parsed. Unification is consistency rather than equality, so
    anything touching an unparsed declaration stops constraining
    instead of rejecting a program that compiled yesterday;
  - the usual arithmetic conversions, since `+' is not a function of
    one type;
  - checking mode for initializers, since #(0 0) has no type of its own
    and takes one from its context. #(T : ...) is the way out of that.

What it wanted on the way:

  - what type a *name* has, which neither the typedef nor the tag
    database recorded. One table serves functions and variables, since
    a function type already has a surface spelling;
  - a scope chain, so a (var c int 9) inside a do ends with the block;
  - form-type, keyed by cons cell, so one form has one type;
  - macros expanded during the walk rather than before it, so type-of
    is answered in the scope the macro was written in.

Closures take the same machinery: a receiver whose type comes from a
call, captures written (name expr) and typed from the expression, and
conversion from a bare function wherever a closure is expected.

type-match grew `_' on the pattern side, since (closure ((int)) int)
and (closure ((float)) int) were separate clauses for one case.
2026-09-30 00:09:32 +03:00
53f92727a5 mark multi-form macro expansions with $
A bare list was read as several forms, so a macro returning
`((make-adder 10) 5)' -- a call of what make-adder returns -- was
spliced into two. Add a new $ char to denote splicing, so ($ form ...)
splices.
2026-09-30 00:08:33 +03:00
cd3016b6b8 fix (¤ int N) expanding to int N a[]
Now only C type keywords will stay as a part of type, i.e.
(¤ unsigned int) -> unsigned int a[] was and is okay
2026-09-29 22:25:07 +03:00
d3f05cecae fix (. (* p) x) expanding to *(p).x
Was an fmt-c-writer bug: unary-op must parenthize itself, and not it's
arg
2026-09-29 22:25:07 +03:00
8a3f51e833 implement closures 2026-09-29 21:07:16 +03:00
1084b7d266 add static-assert to sex
Expands to C11 _Static_assert keyword
2026-09-29 21:05:52 +03:00
Pavel Kulyov
434086ade8 tests: add docstring cases 2026-09-21 22:24:47 +03:00
847bb14340 accept pub enum, and enums used as types
Implement pub support for enums, and also anonymous enums declared
in-place.

Also give the cdr of a `pub' form the form's own location, so a
error about what follows `pub' can say where it was written
2026-09-16 17:02:45 +03:00
0b2b97a0c6 add type database and compile-time reflection 2026-09-15 21:28:41 +03:00
28ad33ca38 add sex-error reporting 2026-09-15 21:28:41 +03:00
5f9f90ef37 support || | |= operators, since we now have our own parser 2026-09-15 20:18:20 +03:00
7e6e32488b fix stray commas and add comment packing 2026-09-15 16:32:55 +03:00
fa4ad5acee fix comments inside statements shifting their meaning 2026-09-15 16:32:55 +03:00
36932fb480 add codegen and args tests, fix couple of bugs in C generation 2026-09-15 16:32:55 +03:00