path: root/parse/stab.c
AgeCommit message (Collapse)Author
2019-04-12Rename traits correctly.Ori Bernstein
2019-03-14Get a bit better at wrangling type bindings.Ori Bernstein
2019-02-26Accept that `file` isn't a node.Ori Bernstein
Shrink node sizes, simplify code a bit.
2019-02-26Add support for `__fini__` functions.Ori Bernstein
2019-02-10Boundtype should be harmless on non-params.Ori Bernstein
2018-08-03Record the closure into all nested funcs.Ori Bernstein
Funcs can go inside funcs.
2018-04-18Merge remote-tracking branch 'ori/master' into HEADS. Gilles
2018-04-17Merge trait specs if provided.Ori Bernstein
This is a bit ugly, since if there are duplicate specs for a trait, we'll end up duplicating the constraints. On the other hand, since we put them into a set, it's mostly an esthetic issue.
2018-01-26New auto operator.Quentin Carbonneaux
Summary: -------- During the Myrcon in September Ori suggested an 'auto' operator that would evaluate what it applies to, store the result in a temporary t, and call __dispose__(t) when the current block exits. This patch implements this idea under the form of a unary operator. This, for instance, allows to have: impl disposable regex# = __dispose__ = {r;} ;; regex.exec(auto std.try(regex.compile("")), "foobar") Like before, it is guaranteed that __dispose__ is called in reverse order of auto appearance. Backward compatibility: ----------------------- Nope. Auto variables are now gone. This should not be a problem, simply rewrite: var auto x = foo() into: var x = auto foo() Implementation: --------------- It largely reuses the code I had written for 'auto' variables but needs a little finer grain tracking because we don't always want to call __dispose__ for *all* auto expression results when leaving a block (some might not be evaluated yet). For example: auto 1 if b -> void ;; auto 2 Only __dispose__(1) must be called when '-> void' is executed. If the block falls through, __dispose__(2) and __dispose__(1) will be called in sequence. TODO: ----- - Err when goto jumps in/out of a block that has auto expressions. - Support auto in patterns. match ... | `std.Some (auto x): ... is essentially rewritten to: match ... | `std.Some (auto x): auto x ... - Test edge cases (e.g., auto in loop condition) Actually, test. Cheers,
2018-01-11Fix how we bind types.Ori Bernstein
Now we accept most valid programs, and reject most invalid ones.
2017-11-05Accept the globalness of file.Ori Bernstein
2017-10-29Fix traits when exported cross-namespaces.Ori Bernstein
2017-10-23Propagate hiddenness properly across usefile merges.Ori Bernstein
2017-10-21Don't bungle trait merging and exporting.Ori Bernstein
2017-08-08Bring back enforced namespaces.Ori Bernstein
It turns out that people actually like being forced to type the full names. Go figure. It does have the benefit of adding pressure to keep package names short. Eventually, we'll probably grow the ability to alias a package at import. We'll see how that goes. This reverts commit c5245eaa80064b77186fa286f8e5e8bca73309ab.
2017-07-29Don't use tyhash for scoping.Ori Bernstein
Soon enough, it's going to use a strict equality comparison, so that params from different scopes will be considered different. It's a step towards deduping.
2017-07-29Finally do a by-scope comparison of generic types.Ori Bernstein
This should clear the way for better deduplication.
2017-07-29Automatic variablesOri Bernstein
Hello, I wrote this patch to start a conversation about resource management in Myrddin. ~ Introduction ~~~~~~~~~~~~~~ The patch attached provides a hopefully life-improving and surely non-invasive mechanism to handle resources that have block-limited lifetimes: automatic variables. This resource-management scheme can be found in multiple languages today. For example, C++ calls destructors automatically at the end of the scope of a variable; similarly, Rust automatically calls user-defined code when a variable's scope ends; finally, also related is Go's defer statement which ensures that resource-releasing code is called at the end of a function. ~ Description ~~~~~~~~~~~~~ The idea is that every "binder" of the language (var/const/ fn args/match) offers the possibility to mark the variables it binds as "automatic" using the 'auto' keyword. An automatic variable must be of a type that implements the new builtin 'disposable' trait below. When the scope of a variable 'v' marked as automatic ends, '__dispose__(v)' is called. That's it. trait disposable @a = __dispose__ : (val : @a -> void) ;; ~ Example Programs ~~~~~~~~~~~~~~~~~~ The language modification is shown in action in the program below. use std impl disposable int = __dispose__ = {x std.put("__dispose__({})\n", x) } ;; const g = {auto x -> x++ - 1 } const main = { var auto i, auto j = 42 for i = 1; i < 6; i=i+1 var auto z : int = 2*i if i == 3 std.put("z = {} -- cont\n", z) continue ;; std.put("z = {}\n", z) if i/2 == 2 var auto inner : int = 1234 break ;; ;; i = g(321) } The output of the previous test program is: 1: z = 2 2: __dispose__(2) 3: z = 4 4: __dispose__(4) 5: z = 6 -- cont 6: __dispose__(6) 7: z = 8 8: __dispose__(1234) 9: __dispose__(8) 10: __dispose__(322) 11: __dispose__(42) 12: __dispose__(320) Some important remarks: * Unlike Go, __dispose__ is called as soon as the scope of a variable ends, not at the end of the function. In particular, the variable 'z' in the example is always disposed of before starting the next iteration. (An iteration ends the loop body block.) * __dispose__ is called in reverse order of declaration This allows variables to depend on resources of variables already in scope. * Regardless of how a block is exited (fallthrough, break, continue, return), variables of the blocks left are disposed of in reverse order and exactly once. * As line 10 of the output shows, the __dispose__ calls happen "after" the return statement of the function. (It happens after the post-increment, so x's value when it is disposed of is 322.) The following example shows that, using an ad hoc type, it is possible to execute arbitrary code at the end of a scope. type defer = (-> void) impl disposable defer = __dispose__ = {f: defer; f()} ;; const foobar = {... const auto _dummy = ({ std.put("Bye!\n") }: defer) ... } ~ Discussion ~~~~~~~~~~~~ Multiple alternatives exist for resource management, and hopefully this mail starts an interesting debate. According to me, here are the pros and cons of the current proposal: - PROS - * Opt-in * Backward compatible * Simple * The spirit of C's original auto * It has an implementation - CONS - * No safety guarantees/compiler checks whatsoever * Syntactic pollution: 'auto' keyword, 'disposable' trait Finally, note that the current patch does not implement auto support for variables bound in match statements. This will come in a followup patch if there is sufficient interest. Also, the patch does not provide proper support (or proper errors) for gotos and labels.
2017-07-27std.change std.lookup std.rules.Ori Bernstein std.on std.every std.use. The rules for an un-namespaced name now are as follows: 1) Attempt to look up a name in the current file. 2) Check all namespaces for a unique name. If the name is not globally unique, give an error.
2017-07-15Use type hashing instead of string hasing in tyenv.Ori Bernstein
Set the stage for stricter env lookups.
2017-07-15Type binding refactoring now compiles.Ori Bernstein
Still a bit sloppy on a few things, needs some dedup work, but it's working.
2017-07-09Style(9)-ify.Ori Bernstein
2017-07-09Don't allow hidden decls to clobber each other.Ori Bernstein
Hidden decls are still global, which means that if two modules define them, they are going to alias to the same symbol. This can lead to really painful to debug errors, since writes to one variable that seems to be file-local will cause some other variable in some other unrelated file to get clobbered. This turns the situation into a compile-time error.
2017-07-03Errors are conventionally lowercase.Ori Bernstein
2017-07-03Clean up formatting of error reporting.Ori Bernstein
2017-06-20Generics get specialized. No capture.Ori Bernstein
2016-06-21Don't accidentally duck type unions.Ori Bernstein
std.option is not the same as any union with `Some x; `None.
2016-06-17Fix a stupidOri Bernstein
We don't need to look up the namespace in variables, since we already do it at other points.
2016-06-17Allow implementing traits from other namespaces.Ori Bernstein
2016-03-02Allow importing multiple instances of a trait.Ori Bernstein
Hidden imports ftw.
2016-02-25Fix forward labels in nested blocks.Ori Bernstein
Fixes #91
2016-02-22Extract util functions into separate dir from parse/Ori Bernstein
2016-01-21Add labels before linking them up.Ori Bernstein
Forward jumps were broken since we were looking up labels before adding them. Oops.
2016-01-20Put labels into scopes.Ori Bernstein
2016-01-12Fix copy-paste error in stab.cOri Bernstein
Thanks to 'paperwing' dude on irc.
2016-01-02Correctly check for decls without initializers.Ori Bernstein
This turns them into errors. Also fixes a couple that slipped into the code.
2016-01-02Disallow out of sync types.Ori Bernstein
We currently toss out all the info to unify them, so.. uh.
2016-01-01Fix style.Ori Bernstein
2015-12-24Fix scoping issues.Ori Bernstein
2015-12-24Fix importing/exporting traits.Ori Bernstein
2015-12-22Make traits work across files.Ori Bernstein
This bumps ABI, and contains a hack.
2015-12-14Don't use a null variable.Ori Bernstein
Didn't fix everything in the last commit.
2015-12-13Fix a couple of segfaults.Ori Bernstein
We should actually use valid values when generating errors.
2015-11-17MEGAPATCH: Tabification.Ori Bernstein
Tabs > spaces. By 4 spaces, to be precise. Let's use them.
2015-10-02Allow redefinition of externs.Ori Bernstein
We don't want externs to conflict with their actual definition.
2015-10-01Don't double-insert namespaces.Ori Bernstein
updatens() was changed at some point to register the namespace. We don't need to put it in again after we call it, and in fact, we crash if we do.
2015-09-29Storing the visibility caused a regression.Ori Bernstein
Reverting until I can think more about it.
2015-09-29Complain about missing trait impls.Ori Bernstein
Because exploding with an abort is confusing for the user.
2015-09-25Unhide declarations if needed.Ori Bernstein
We don't want to keep a declaration hidden if we saw an exported declaration of it.
2015-09-24Error out correctly with closures.Ori Bernstein