- fix a refcounting bug where things were getting freed too early. the cause of this bug is when we transitioned to the lvalue system, around
24addf2
, when we added arguments to the refcounting stack; we forgot to include a corresponding increment in the call argument codegen, which has since been rectified.
- allow
::
to refer to the topmost scope, like in C++ - allow
^
at any location in the scope path to refer to the parent scope -- eg.::qux::^::foo::^::bar
(naturally will fail at the root scope!) - for some reason, added a more verbose error message when you try to use a value as a type -- it searches up the tree for an actual type with the name, and tells you how to refer to it -- using the parent-scope specifier mentioned above.
- add location info to
pts
types -- which will soon need to be carried over tofir
-- probably some kind ofTypeLocator
struct that I have in mind. - abstract away which
hash_map
we use -- preliminary tests showska::flat_hash_map
gives us a ~9% perf improvement across-the-board -- using themassive.flx
and associated test framework.
- add a flag to call
abort()
on error -- now the default behaviour is toexit(-1)
.
- fixed our
std::map
implementation a bit - calls to
malloc
should go through our new malloc wrapper which checks fornull
returns - hoist
make_lval
similar toalloca
-- was causing stack overflow issues! - apply type transforms (
poly/transforms.cpp
) in reverse, duh! surprised we didn't run into this sooner. - fix an oversight where we allowed variables to be 'used' in nested functions (due to the scoping rules implicitly), and let it slip to llvm-land (!)
- fixed a bug where we failed to infer union types -- was just checking the wrong thing.
- add a check for unwrapping (with
as
) union values to variants with no values (eg.opt::none
) - fixed a bug where we were not checking for duplicates when adding unresolved generic defns and operator overloads.
- fix omission of floating-point comparison ops (oops)
- further patches to merge-block-elision
- fix ir-block error when doing multiple logical operators (
&&
and||
) is
check parses its rhs-operand the same way asas
now (aka properly!)- add the concept of
realScope
, which is the original scope of a definition -- aka where it got defined. we need this idea because we can callast::typecheck()
from any scope, usually when instantiating generics - clean up string output to use
::
for scopes instead of.
- change the criteria of finding an existing definition (for generic things) to only match the last N items of the current state with the stored state -- instead of the previous vice-versa situation. (ie. the current state can be smaller than the stored state)
- add a distance penalty for resolving a generic function, also add a check where we don't re-add a function twice (eg. when recursively calling a generic function)
ast::Block
s now push an anonymous scope -- no idea why they didn't. fixes a pretty massive bug where bodies of an if statement shared the same scope- probably some other misc fixes i forgot
- fix a using bug (
d1a0efe
) - clean up the generated IR blocks, and implement 'merge-block-elision' properly (
76481a2
) - fix implicit method calls (that i forgot to fix after refactoring the self-handling previously)
- allow
export
-ing a path, eg.std::limits
. this is different from namespacing the entire file (unlike C++), because we would then getlimits::std::...
instead - allow
import
-ing a path as well, so we can doimport std::limits as foo::bar::qux
. import
s of string paths (eg.import "foo/bar"
) no longer append an.flx
extension automatically!
- flip the declaration of
ffi-as
so the external name is afteras
-- and now as a string literal (because your external names might have flax-illegal characters inside)
- declare foreign functions
as
something -- useful for OpenGL especially, (1) to deduplicate thegl
prefix, and (2) to allow overloading of all the differentglVertex<N><T>
whereN = 2, 3, 4
,T = i, f, d
or something.
public
andprivate
imports, where the former re-exports things and the latter is the default behaviour.
- static access now uses
::
instead of.
, along the veins of C++ and Rust. - polymorph instantiations now take the form of
Foo!<...>
(the exclamation mark) -- making it less likely to be ambiguous. - polymorph arguments can now be positional, meaning
Foo!<int>
instead ofFoo!<T: int>
. The rules are similar to that of funtion calls -- no positional arguments after named arguments.
- add chained comparison operators, eg.
10 < x < 30
would succinctly check forx
between 10 and 30. - consequently, changed the precedence for all six comparison operators (
==
,!=
,<
,<=
,>
, and>=
) to be the same (500)
- using unions -- including both generic and instantiated unions
- vastly improved (i'd say) inference for variants of unions (when accessing them implicitly)
- infer polymorphs with union variants (except singleton variants)
- clean up some of the
TypecheckState
god object - fixed a number of related bugs regarding namespaced generics
- give polymorphic types a
TypeParamMap_t
if there was atype_infer
- major revamp of the generic solver -- the algorithm is mostly unchanged, but the interface and stuff is reworked.
- finally implemented the iterative solver
- variadic generics work
- took out tuple splatting for now.
- generic unions, but they're quite verbose.
- add tagged union types, including support for
is
andas
to check and unwrap respectively - infer type parameters for a type from a constructor call
- fix the recursive instantiation of generic functions.
- no longer stack allocate for arguments
- new lvalue/rvalue system in the IRBuilder, to make our lives slightly easier; we no longer need to pass a value/pointer pair, and we handle the thing in the translator -- not very complicated.
- add
$
as an alias for.length
when in a subscript or slicing context, similar to how D does it. - we currently have a bug where we cannot recursively instantiate a generic function.
- factor the any-making/getting stuff into functions for less IR mess.
- fix a massive bug in
alloc
where we never called the user-code, or set the length. - add stack-allocs for arguments so we can take their address. might be in poor taste, we'll see.
- enable more tests in
tester.flx
.
- fix string-literal-backslash bug.
- clean up some of the old cruft lying around.
- we can just make our own function called
char
that takes a slice and returns the first character. no compile-time guarantees, but until we figure out something better it's better than nothing.
- fix the bug where we were dealing incorrectly with non-generic types nested inside generic types.
- fix calling variadic functions with no variadic args (by inserting an empty thing varslice in the generated arg list)
- fix 0-cost casting between signed/unsigned ints causing overload failure.
- add
is
to streamline checking thetypeid
ofany
types.
- fix a bug wrt. scopes; refcount decrementing now happens at every block scope (not just loops) -- added a new
BlockPoint
thing to convey this. - fix a massive bug where
else-if
cases were never even being evaluated. stdio.flx
!
- replace the individual IR stuff for strings and dynamic arrays with their SAA equivalents.
- add an
any
type -- kinda works like pre-rewrite. contains 32-byte internal buffer to store SAA types without additional heap allocations, types larger than 32-bytes get heap-allocated. - add
typeid()
to deal with theany
types.
- finally add the check for accessing
refcount
when the pointer isnull
; now we return0
instead of crashing.
- fix a bug where we added generic versions for operators twice. (this caused an assertion to fire)
- fixed a bug wrt. passing generic stuff to generic functions -- now we check only for a subset of the generic stack instead of the whole thing when checking for existing stuff.
- remove mpfr from our code
- actually fix the bug. we were previously moving out of arrays in a destructuring binding, which is definitely not what we want. now we increment the refcount before passing it off to the binding, so we don't prematurely free.
- fix a massive design flaw wrt. arrays -- they now no longer modify the refcount of their elements. only when they are completely freed, then we run a decrement loop (once!) over the elements.
- this should fix the linux crash as well. note: classes test fails, so we've turned that off for now.
- fix a recursion bug with checking for placeholders
- fix a bug where we would try to do implicit field access on non-field stuff -- set a flag during typechecking so we know.
- add more tests.
- fix a parsing bug involving closing braces and namespaces.
- still no iterative solver, but made the error output slightly better.
- also, if we're assigning the result to something with a concrete type, allow the inference thing to work with that information as well.
- pretty much complete implementation of the generic type solver for arbitrary levels of nesting.
- one final detail is the lack of the iterative solver; that's trivial though and i'll do that on the weekend.
- fix a couple of bugs relating to SAA types and their refouncting pointers
- fix a thing where single-expr functions weren't handling
doBlockEndThings
properly. - start drilling holes for the generic inference stuff
- eliminate
exitless_error
, and made everything that used to use it use our new error system.
- overhaul the error output system for non-trivial cases (it's awesome), remove
HighlightOptions
because we now haveSpanError
. - make osx travis use
tester.flx
so we stop having the CI say failed.
- sort the candidates by line number, and don't print too many of the fake margin/gutter things.
- change typecache (thanks adrian) to be better.
- magnificently beautiful and informative errors for function call overload failure.
- fix a couple of unrelated bugs
- varidic arrays are now slice-based instead of dynarray-based
- variadic functions work, mostly. not thoroughly tested (nothing ever is)
- parse the variadic type as
[T: ...]
- allow
[as T: x, y, ... z]
syntax for specifying explicitly that the element type should beT
.
- remove
char
type; everything is nowi8
, andisCharType()
just checks if its ani8
- constructor syntax for builtin types, and strings from slices and/or ptr+data
- fix a couple of mutability bugs here and there with the new gluecode.
- actually add the instructions and stuff, fix a couple of bugs
fir::ConstantString
is now actually a slice.- move as many of the dynamic array stuff to the new
SAA
functions as possible. - increase length when appending
- strings now behave like dynamic arrays
- new concept of
SAA
, string-array-analogues (for now just strings and arrays lol) that have the{ ptr, len, cap, refptr }
pattern.
- check generic things when looking for duplicate definitions (to the best of our abilities)
- actually make generic constructors work properly instead of by random chance
- generic functions work
- made error reporting slightly better, though now it becames a little messy.
- actually make generic types work, because we never tested them properly last time.
- fixed a bug in
pts::NamedType
that didn't take the generic mapping into account -- also fixed related issue in the parser
- move to a
TCResult
thing for typechecking returns, cleans up generic types a bunch - fix a bug where we couldn't define generic types inside of a scope (eg. in a function)
- make init methods always mutable, for obvious reasons. Also, virtual stuff still works and didn't break, which is a plus.
- remove all code with side effects (mostly
eat()
stuff in the parser) from within asserts.
- fix type-printing for the new array syntax (finally)
- string literals now have a type of
[char:]
, with the appropriate implicit casts in place fromstring
and to&i8
- add implicit casting for tuple types if their elements can also be implicitly casted (trivial)
- fix an issue re: constant slices in the llvm translator backend (everything was null)
- distinguish appending and construct-from-two-ing for strings in the runtime-glue-code; will probably use
realloc
to implement mutating via append for strings once we get the shitty refcount madness sorted out.
- add
[mut T:]
syntax for specifying mutable slices; otherwise they will be immutable. If using type inference, then they'll be inferred depending on what is sliced.
- overhaul the mutability system to be similar to Rust; now, pointers can indicate whether the memory they point to is mutable, and
let
vsvar
only determines whether the variable itself can be modified. Use&mut T
for the new thing. - allow
mut
to be used with methods; if it is present, then a mutableself
is passed in, otherwise an immutableself
is passed. - add casting to
mut
:foo as mut
orfoo as !mut
to cast an immutable pointer/slice to a mutable one, and vice versa. - distinguish mutable and non-mutable slices, some rules about which things become mutable when sliced and which don't.
- add generic types for structs -- presumably works for classes and stuff as well.
- fix bug where we couldn't do methods in structs.
- fix bug where we treated variable declarations inside method bodies as field declarations
- fix bug where we were infinite-looping on method/field stuff on structs
- change type syntax to be
[T]
for dynamic arrays,[T:]
for slices, and[T: N]
for fixed arrays - change strings to return
[char:]
instead of making a copy of the string. This allows mutation... at your own risk (for literal strings??) - add
str
as an alias for the aforementioned[char:]
- change
alloc
syntax to be like this:alloc TYPE (ARGS...) [N, M, ...] { BODY }
, where, importantly,BODY
is code that will be run on each element in the allocated array, with bindingsit
(mutable, for obvious reasons), andi
(immutable, again obviously) representing the current element and the index respectively. - unfortunately what we said about how
&T[]
parses was completely wrong; it parses as&(T[])
instead.
- fix how we did refcounts for arrays; instead of being 8 bytes behind the data pointer like we were doing for strings, they're now just stored in a separate pointer in the dynamic array struct itself. added code in appropriate places to detect null-ness of this pointer, as well as allocating + freeing it appropriately.
- add for loops with tuple destructuring (in theory arbitrary destructuring, since we use the existing framework for such things).
- add iteration count binding for for-loops;
for (a, b), it in foo { it == 1, 2, ... }
- fix the completely uncaught disaster of mismatched comparison ops in binary arithmetic
- fix bug where we were double-offsetting the indices in insertvalue and extractvalue (for classes)
- fix certain cases in codegen where our
TypeDefn
wasn't code-generated yet, leading to a whole host of failures. // ! STILL NOT ROBUST - fix typo in operator for division, causing it not to work properly (typoed
-
instead of/
) - change pointer syntax to use
&T
vsT*
. fyi,&T[]
parses intuitively as(&T)[]
; use&(T[])
to getT[]*
of old - change syntax of
alloc
(some time ago actually) to allow passing arguments to constructors; new syntax isalloc(T, arg1, arg2, ...) [N1, N2, ...]
- fix the behaviour of foreach loops such that they don't unnecessarily make values (and in the case of classes, call the constructor) for the loop variable
- add dynamic dispatch for virtual methods (WOO)
- probably fix some low-key bugs somewhere
- enforce calling superclass constructor (via
init(...) : super(...)
) in class constructor definitions - fix semantics, by calling superclass inline-init function in derived-class inline-init function
- refactor code internally to pull stuff out more.
- re-worked method detection (whether we're in a method or a normal function) to handle the edge case of nested function defs (specifically in a method)
- make base-class declarations visible in derived classes, including via implicit-self
- method hiding detection -- it is illegal to have a method in a derived class with the same signature as a method in the base class (without virtual)
- fix regression wrt. scoping and telporting in dot-ops (ref
rants.md
dated 30/11/17)
- add
using ENUM as X
, whereX
can also be_
.
- add
using X as _
that works like import -- it copies the entities inX
to the current scope.
- add
using X as Y
(but whereY
currently cannot be_
, andX
must be a namespace of some kind)
- fix edge cases in dot operator, where
Some_Namespace.1234
would just typecheck 'correctly' and return1234
as the value; we now report an error.
- add barebones inheritance on classes. Barebones-ness is explained in
rants.md
- fix variable decompositions
- enable the decomposition test we had.
- disable searching beyond the current scope when resolving definitions, if we already found at least one thing here. Previous behaviour was wrong, and screwed up shadowing things (would complain about ambiguous references, since we searched further up than we should've)
- fix emitting
bool
in IR that was never caught because we never had a function takingbool
args, thus we never mangled it. - add class constructors; all arguments must be named, and can only call declared init functions.
- add order-independent type usage, a-la functions. This allows
A
to refer toB
andA
to simultaneously refer toB
. - fix detection (rather add it) of recursive definitions, eg.
struct A { var x: A }
, orstruct A { var x: B }; struct B { var x: A }
- add
sizeof
operator
- add static fields in classes, with working initialisers
- add error backtrace, but at a great cost...
- add splatting for single values, to fill up single-level tuple destructures, eg.
let (a, b) = ...10; a == b == 10
- add array and tuple decomposition, and allow them to nest to arbitrarily ridiculous levels.
- allow assignment to tuples containing lvalues, to enable the tuple-swap idiom eg.
(a, b) = (b, a)
- add splatting of tuples in function calls; can have multiple tuples
- improve robustness by making range literals
(X...Y)
parse as binary operators instead of hacky postfix unary ops.
- fix a bug that prevented parsing of function types taking 0 parameters, ie.
() -> T
- fix custom unary operators for certain cases (
@
was not being done properly, amongst other things)
- add named arguments for all function calls, including methods, but excluding fn-pointer calls
- fix some bugs re: the previous commit.
- add constructor syntax for types (as previously discussed), where you can do some fields with names, or all fields positionally.
- fix false assertion (assert index > 0) for InsertValue by index in FIR. Index can obviously be 0 for the first element.
- fix implicit casting arguments to overloaded operators
- add ability to overload unicode symbols as operators
- add ability to overload prefix operators
- internally, move Operator to be a string type to make our lives easier with overloading.
- fix member access on structs that were passed as arguments (ie. 'did not have pointer' -- solved by using ExtractValue in such cases)
- fix method calling (same thing as above) -- but this time we need to use ImmutAlloc, because we need a
this
pointer - add basic operator overloading for binary, non-assigment operators.
- check for, and error on, duplicate module imports.
- add deferred statements and blocks
- add single-expression functions with
fn foo(a: T) -> T => a * 2
- add support for reverse ranges (negative steps, start > end)
- add ranges
- add foreach loops on ranges, arrays, and strings
- add '=>' syntax for single-statement blocks, eg.
if x == 0 => x += 4
- fix lexing/parsing of negative numerical literals
- better type inference/support for empty array literals
- implicit conversion from pointers to booleans for null checking
- fix runtime glue code for arrays wrt. reference counting
- add alloc and dealloc
- add dynamic array operators (
pop()
,back()
)
- add enums
- add classes