eval: allow taking address of arbitrary expressions This allows you to write a global like so: let x: *int = &1234; It generates a second global on the fly to store the address operator's operand. Signed-off-by: Drew DeVault <sir@cmpwn.com>
lex: scan and discard #[annotations] Signed-off-by: Drew DeVault <sir@cmpwn.com>
Save sources unaffected by -M for places using them as full paths When truncated module paths are used in debug info, debuggers can't find the correct source file. A similar issue can occur when printing harec errors with line context. Fixes: https://todo.sr.ht/~sircmpwn/hare/934 Signed-off-by: Alexey Yerin <yyp@disroot.org>
types: add missing newline to "Unsupported or unrecognized target" error message Signed-off-by: Antonio Terceiro <terceiro@debian.org>
parse: better error report in invalid local defines Old error when trying to use tuple unpacking in define was `syntax error: expected name, '(', found '('`. Now it just says it expected a name. Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
check: don't autodereference append/insert value Initial support for this (only in check) was introduced 3 years ago. Then someone reported this aborts in gen, tracked as #809. Some time later we fixed that, but really this should not have been introduced in the first place. Does not need a spec change because the spec doesn't say anything about append/insert values at the moment. Breaking-Change: language References: https://todo.sr.ht/~sircmpwn/hare/809 Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
check: disallow C variadism in @init/@fini/@test Breaking-Change: language Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
check: don't do type promotion on arrays Arrays can't be used in binary expressions, so it makes no sense to do type promotion on them. Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
gen: move an alloc instruction to function preamble Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
parse: simplify parse_binding_unpack Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
gen: fix expandable array gen_value type
check: use explicit false as nullability parameter
gen: handle a switch corner case Before 56f9fa50, switch expressions had result type never if all of their branches had result never. This was against the spec in cases where the switch was provided a non-never type hint. Now the result type matches what the spec dictates, but this created a problem in gen, where, based on the non-never type hint, a result is expected from at least one of the branches. To make QBE happy, a dummy initialization of the switch result is added. It has no practical impact, since QBE is able to optimize it away in all cases. Reported-by: Ember Sawady <ecs@d2evs.net>
tests: test string comparison
fix regression introduced in 7c980a13 That commit did not account for type aliases.
gen: fix a regression introduced in 13a6fc7df4c4 alloc(obj, cap) called memcpy with too big size parameter when `obj` was a slice, causing copying of unrelated memory next to initialzier object's memory location. This is a stupid thing to do, but strictly speaking, it's was actually almost legal and mostly harmless, since the copied memory was inaccessible from within hare without pointer hacks. The only thing this actually broke was allocation of empty slices (see added test), because when the initializer slice points to null, trying to copy anything out of it is a bad idea.
handle allocation failure by returning nomem previously, if the result type of an allocation-expression was not a nullable pointer type, the builtin would abort. this is now handled by instead returning nomem: let x: (*int | nomem) = alloc(1); the same goes for append and insert: let x: (void | nomem) = append(...); let y: (void | nomem) = insert(...); nomem is a zero-sized type (like void). it's error flag is always set. this commit introduces the following breaking changes: - nomem cannot be used as a name anymore - alloc, insert and append have different return values now - harec binary interface has changed. Co-authored-by: Bor Grošelj Simić <bgs@turminal.net> Signed-off-by: Lorenz (xha) <me@xha.li> Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
scope: remove split object init and insert functions They are no longer used anywhere. Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
scan: make incomplete_decl just a field in scope_object It doesn't make sense to treat O_SCAN objects differently than everything else. I'm not sure it was ever a good idea, but it certainly isn't a good idea now, because it just makes the interface harder to use correctly. Rename struct incomplete_declaration to incomplete_decl. It's shorter, unambiuous, and this commit touches nearly every line that uses it anyway. Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
all: intern names & identifiers Introduce a global structure that holds unique references to all strings used in identifiers and all identifiers. Code actually doing important complicated things can now check for equality by comparing pointers, while the complexity around memory management and details of identifier mechanics are extracted to a single place. This significantly simplifies some parts of check and parse. While this was done primarily because it makes some complicated code simpler, it also has other benefits: according to some measurements I made locally, the number of allocations harec performs is reduced by over 40%, and the total running time of harec when building the build driver is reduced by 15%. Hare code compilation time is dominated by QBE, so this amounts to only something like 5% smaller total build times. Also enables removal of token_finish, since it now has no more consumers in which its action would have any non-local effect. Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>