Related to discussion on #738, but also trying to standardize handling of everything and make placement of token spellings (`AND "and"`) consistently in lexer.lpp.
I could have gone the other direction, removing the list of things in lexer.lpp, but this feels like it does more to use the compiler to detect skew between lexer.lpp and parser.ypp.
Note this makes a few cases where the Statement was optional explicit (Block, If, Sequence). I do add a few CHECKs around where statements were optional and assumed but unverified.
I switch TypeCheckStmt to not take an optional Statement because I think it makes the call sites clearer in behavior. It's also a smaller change than the converse, because taking an optional Statement means the returned statement would also need to be optional. Arguably a wrapper for optional statements could be added, but this still seems cleaner to me, and there aren't that many cases of an optional statement.
Co-authored-by: Geoff Romer <gromer@google.com>
This supports both struct type literals, `{.x: i32, .y: i32}`, and struct
value literals, `{.x = 3, .y = 4}`. The degenerate case of `{}` is
treated as a struct value literal, with the expectation that an empty
struct value has the same type/value duality as an empty tuple value.
I've modified the text from the proposal slightly, focusing the overview more on a design setup, but mostly kept the details. One important thing here is I noticed that raw tab characters are disallowed -- this was a little buried before, and I've now updated the list of characters allowed in a string to exclude tabs. Additionally, I've noted `\0D` in the list of escapes as explicitly invalid.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Recent experience indicates that the system of thumbs-up doesn't seem to
work consistently. Replace it with more broad encouragement to use PR
reactions to surface sentiment and a judgement call by the leads on when
a proposal is ready to merge.
An explicit goal here is that leads can make this judgement call
reflecting the nature of the proposal. Many of these are low-risk.
Either they are easily fixed-forward or minimally disruptive. This can
be because they are merely beginning to fill out a largely open area, or
because they are minor changes.
Also try to clarify that it is expected for the leads to sometimes miss
things or make mistakes, and encourage a revert or fix-forward mentality
rather than slowing down progress to reduce the rate of mistakes.
Sorry about the big change, this is hard to split. ParenContents is used by both, templated, and expects the same pointer type. While I could duplicate ParenContents with some ExpressionParenContents or PatternParenContents, that seems a little kludgy versus a single large change handling both. The worst of it is that Expression is already pretty sweeping, Pattern is really just incrementally adding.
That said, I believe this includes a couple fixes I found with incorrect use of dyn_cast in typecheck.cpp (checked nullptr at the wrong step in 2 code locations). There's also a missing `*` in member.cpp this caught. I adjust passing of expressions for Return due to nullness (I felt adding another constructor was the best solution).
I add a `.Release()` to BisonWrap due to things like `$3.first` needing some way to work through BIsonWrap. I felt this was better than `operator->`, but feel free to comment if you prefer the other path (`.Release()` conveniently lets me do pair unwrapping, so it felt a better solution).
I do add a TODO to think about better Ptr-to-Ptr cast<> support too, though, as that doesn't work cleanly with LLVM's infra. But so far it seems to only come up in one spot, so I'm not prioritizing it.
.pre-commit-config.yaml and proposals/p0540.md (linking goals.html, fixed to goals.md link) are the two references I could find.
The site is disabled, though; I think it makes the most sense to delete supporting code, and in the future hopefully we can use GH pages to publish.
- brew instead of pyenv to centralize package management
- can't recall why we used pyenv before, may not have been the best choice.
- pyenv has been a burden in updating versions, a single `brew upgrade` works better
- python3.9 because it's the latest and greatest, feels weird going to old versions if we're recommending installs.
- bazel 5.0.0 pre-release due to https://github.com/bazelbuild/bazel/commit/b9fc66d327debcfbdb2964afdba35a1cc8919b81
- earlier versions want `python` to be on the path, which pyenv did but brew does not
For most people this will mean: `rm -rf ~/.pyenv && brew uninstall pyenv && brew install python@3.9 && pip3 install -U pip && pip3 install pre-commit`, plus removing any `pyenv` invocations from the shell `rc` file.
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
The m4/flex/bison commits are in, unreleased, but we can still go back to the canonical repo. Also updates the python version.
This pulls out the version statement mainly because it's typically repeated, not due to the m4/flex/bison verbosity. Pulling it out makes it more obvious and easier to change.
Per https://github.com/bazelbuild/rules_cc this still isn't necessary. There's no build-time enforcement, so usage is inconsistent/incorrect. Rather than letting this linger, remove it pending Bazel tooling enforcing it.
Add support for nominal (or "named") classes with encapsulation. Inheritance will be in a later proposal. Here is an example of the proposed syntax:
```
class Circle {
fn Create(c: Point, r: f32) -> Self {
return {.center = c, .radius = r};
}
fn Diameter[me: Self]() -> f32 {
return me.radius * 2;
}
fn Expand[addr me: Self*](distance: f32);
private var center: Point;
private var radius: f32;
}
fn Circle.Expand[addr me: Self*](distance: f32) {
me->radius += distance;
}
```
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This enables the interpreter logic to express its intent more directly, especially in the common cases, and enables us to get rid of ValAction. It's also a step toward simplifying and encapsulating `state->stack`.
This also eliminates the ctad wrapper for Stack: I think the leaning is to remove it. It felt worth keeping the constructor because constructing with a single element is a common use-case.
Adds a single-argument constructor for Scope because the `std::list<std::string>()` is common, and eliding it is consistent with what we've done for things like tuples.
I was considering a vector constructor due to the double-Push on line 1139, but thought the Push() semantics may mean that it's better not to provide.
I think Stack used to use ListNode, but you'd previously removed that dependency. This finalizes the split, and merges ListNode so that we don't accidentally accrue more dependencies. In part I think we'll eventually want to change how Dictionary is set up.
This opens up a path for switching `int line_num` to a `Location loc`, which I want to do for tracking filenames of code. But I don't think we should have a default constructor on `Location` to avoid mistakes, and switching FunctionDefinition to an arena alloc seems more consistent anyways.
Moving "Global variables" out of "Alternatives"; I don't think it's really been considered in the same way that others have, so there's no reference to provide.
It was in my mind to add String in order to support libraries in `package`. `print` is added in order to have a String go to stdout. I've tried to do `print` in a way that won't be too hard to add other printable types, but it's probably also somewhat optional here -- that is, if desired, I could remove it. But it was a lot easier to doublecheck `\n` behavior with it, and I suspect it'll be helpful in other tests if it supports more value types.
On the side, this also fixes dereferencing in Pattern/Expression Print() calls, which I was noticing printing pointers instead of values. This may be another argument for moving away from passing pointers, since this seems to be a difficult-to-catch error.
Co-authored-by: Geoff Romer <gromer@google.com>
This proposal defines the very basics of `class` types, primarily focused on:
- use cases including: data classes, encapsulated types, inheritance with and without `virtual`, interfaces as base classes, and mixins for code reuse;
- anonymous data types for called _structural data classes_ or _struct types_. Struct literals are used to initialize class values and ad-hoc parameter and return types with named components; and
- future work, including the provisional syntax already in use for features that have not been decided.
The intent is to both make some small incremental progress and get agreement on direction. As such it doesn't include things like nominal types, methods, access control, inheritance, etc.
It proposes this struct type and literal syntax:
```
var p: {.x: Int, .y: Int} = {.x = 0, .y = 1};
```
Note that it uses commas (`,`) between fields instead of semicolons (`;`), and no introducer for types or literal values.
Incorporates decisions from #665 , #653 , #651
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>