Commit Graph
24 Commits
Author SHA1 Message Date
Jon Ross-Perkins 4ae0fa6f86 Adjust handling of cases where conditions are missing. (#3119)
In #3064, code was changed to look at a future token. This is an issue
because the parser is set up to enforce that tokens aren't used without
being consumed. That's part of #3118; related validation fails. Also,
since it's not necessarily the open paren that was consumed, it could be
a different opening symbol, which the closing symbol handling doesn't
check.

Under this approach, it's tracked whether an open paren was consumed,
and the open paren is associated with the state. That's more aligned
with how the parser expects to be fed information.

In paren condition handling for if and while, I'm also adding some
special casing for `if {` in particular to not assume the `{` is a
struct. I just think that this will come up somewhat often and the
resulting output is better this way (an error either way). I'm not doing
similar with `for` because there's already some `var` handling there,
and I'd need a little more time to think about structure -- whereas
right now I'm just trying to fix the crashes (`if {}`, `if []`, etc).

Fixes #3118
2023-08-18 23:04:30 +00:00
Farzana Ahmed SiddiqueandFarzana Ahmed Siddique a67aeb5724 Parser for array type. (#3075)
Co-authored-by: Farzana Ahmed Siddique <fasiddique@google.com>
2023-08-09 19:04:44 +00:00
Farzana Ahmed SiddiqueandFarzana Ahmed Siddique 6cca85534f Parser for index expression such as a[0] (#3033)
Co-authored-by: Farzana Ahmed Siddique <fasiddique@google.com>
2023-07-28 18:31:12 +00:00
Richard Smith c4b880c6ef Parsing for pointer types and pointer operators. (#3026)
This provides parsing support for the functionality added in #2006.
2023-07-26 21:24:54 +00:00
Jon Ross-Perkins 918c089e03 Add namespace support. (#2940)
This handles namespacing of functions. Parsing and semantics are changed
significantly, while lowering works without changes. Variables can't be
namespaced yet because they're dealing with patterns, and I didn't dig
through that code.

Most of the logic is done through the new name declaration stack, which
is necessary because semantics isn't quite sure where the declaration
name ends. It'd be complex for parsing to send a signal about this,
probably involving node variants and rewrites of the tree, and this
solution seems to work well. Unfortunately this means a new stack, but
that may be inevitable due to the extra information needing to be
tracked.

Note this doesn't deal with scoped lookups of non-namespace things,
which we'll need for generics. That'll probably involve pushing resolved
scopes onto a stack (or maybe just setting a singleton value?) to affect
contextual name lookup. But, I think the basics are there to make it
work when we can test the behavior.

This renames "designator expression" to "qualified expression" and adds
"qualified declaration" in order to use terminology more consistent with
C++.

Namespaces will probably need to be considered for name mangling down
the line, but this still uses the basic name.
2023-07-06 20:43:40 +00:00
Richard Smith 202d3f5993 Semantic analysis for if expressions (#2893)
Add semantic analysis and semantics IR building for `if` expressions, and add the first parts of control flow handling to semantics IR. After discussion with @chandlerc, use [block arguments](https://en.wikipedia.org/wiki/Static_single-assignment_form#Block_arguments) to convey values from the two arms of the `if` to the result. For now, only a single block argument is supported, but we should revisit this as we explore more of the requirements of the Semantics IR form.

Functions can now contain multiple code blocks, so grab the entry block up-front instead of assuming the entry block will be at the top of the block stack when we reach the end of function emission.

Add trivial support for `bool` type literal, because without it we can't write testcases.
2023-06-13 14:38:27 -07:00
Richard Smith 2c45cb3be8 Parsing support for if expressions. (#2883)
We model `if a then b else` as a prefix operator for parsing precedence purposes. The rule that a statement starting with `if` is never an `if` expression is handled implicitly because the statement parser never invokes the expression parser for a statement starting with `if`.

This exposed a bug in our diagnosis of the whitespace rule for prefix operators, which was incorrectly being applied to non-symbolic operators in some cases, and was producing a bogus second diagnostic in some cases, which is also fixed here.
2023-06-09 16:41:10 -07:00
Jon Ross-PerkinsandRichard Smith d7ab71ba7d Parsing for generic and template parameters. (#2685)
Also cleans up some comments about related parse nodes. Currently basic and not heavily validated.

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-03-16 10:50:35 -07:00
Jon Ross-Perkins 7d553107dd Extend deduced and regular parameter handling to types. (#2684)
This makes it possible to specify both deduced and regular parameters on types. It reorganizes the handling of parameter lists in order to allow more reuse of code in this approach. Both functions and types use the new DeclarationNameAndParams handling. Overall the goal here is to take advantage of commonality in structure.

Regarding destructors, the likely approach would be to use ParameterListAsDeduced directly because `destructor` is a keyword with no declaration name and no regular parameters.
2023-03-16 09:06:45 -07:00
Jon Ross-PerkinsandChandler Carruth 51f887c348 Add a macro to simplify XAsY variant state generation (#2679)
This is just a mild simplification to address repeat macro use. I'm hoping it makes it clearer and easier in parser_state.def to write down the multiple variants.

I'm writing these macros in a simple form that I think is easy to read, versus some complex macro recursion which I think is _possible_ but would be harder to reason. And, we don't really need arbitrary arg counts -- this is probably going to stay fairly limited long-term, although I could easily see something like a half dozen in some cases so maybe I'll be wrong and it'll go higher. But, I feel like these macros still make it easier to focus on the _intent_ of cases, rather than visually comparing each line for differences.

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2023-03-14 10:19:40 -07:00
Jon Ross-Perkins e613ad5323 Reorganize interface parsing so that it's shared with class and constraint (#2666)
We could similarly add others -- this is intended to make it easy to add more that parse essentially the same.

The functionality expected is that types will use GetDeclarationContext in order to error on certain functionality in the declaration scope loop. e.g., with how constraints and interfaces currently don't allow definitions.

I've only moved out `package` because it's only valid on the top line. It might still be good to parse it later, but with slightly different logic because it would always be an error, and the declaration context isn't quite the right framing for that.

Also unifies some errors with `fn`.
2023-03-13 17:24:01 -07:00
Jon Ross-Perkins b35e803a7f Fold deduced pattern parsing into the general pattern parsing. (#2649)
Depends on #2646 

Right now, deduced parameter handling is very narrow to `self` support. This folds it into pattern handling, which should eventually be a superset of deduced parameter support, so this will avoid more duplication of logic.

Note, this subtly adds handling of multiple deduced parameters, but not generic parameters (`:!`) so it's still not quite right.
2023-03-07 09:27:55 -08:00
Jon Ross-Perkins 4083d7f5b9 Reorganize interface parsing to be more consistent with other declarations. (#2646)
The comments in parse_node_kind.def capture the change being made here.

Before:

```
//   _external_: DeclaredName
//     InterfaceBodyStart
//     _external_: statements
//   InterfaceBodyEnd
// InterfaceDefinition
```

After:

```
//     InterfaceIntroducer
//     DeclaredName
//   InterfaceDefinitionStart
//   _external_: declarations
// InterfaceDefinition
```

Really I just want to treat introduced things consistently. `var` defines my philosophy here: it doesn't always have a `DeclaredName`, so the `VarIntroducer` _must_ be the bounding node. By being consistent with that, I believe that overall the structure becomes easier to understand (that is, there are fewer inconsistencies to understand).

This also adds InterfaceDeclaration, since I think it can be predicted we'll have that, and it's helpful for making recover consistent with HandleDeclarationError.

Similarly, I'm also trying to standardize the loop processing a little with HandleDeclarationLoop. In the current approach, InterfaceDefinitionFinish isn't a necessary state, so I'm removing it.
2023-03-06 16:31:01 -08:00
Jon Ross-Perkins 6bb0a5b55e Do a cleanup of the x-macro enum comments. (#2650)
Trying to make some boilerplate-y comments more boilerplate, and also explain what's in the files a little more.
2023-03-06 15:13:41 -08:00
Jon Ross-Perkins 11deb14dc6 Handle var init-with-self situations. (#2488)
The problem I'm trying to solve is: `var x: i32 = x;`. This change makes it so that name lookup fails, by removing `x` from name lookup between the `=` and `;`.

`var x: i32` still adds to name lookup to handle future situations like `var (x: i32, x: i32);` which is still a redefinition of `x`; if we don't add `x` to name lookup, it gets harder to catch that example.

The VariableDeclaration/VariableInitializer refactor in ParseTree supports this by given a bracketing-like structure for semantics to cue that it's entering an initialization expression. With this, VariableInitializer can remove the name lookup and queue it to be restored. VariableDeclaration doesn't need to change too much since it's still bracketed by VariableIntroducer, and so we just traverse slightly differently.

Note this also incidentally changes a little about NameReference, that it's returning the storage consistently instead of the name. You can see this e.g. in global_lookup.carbon, `Assign(node8, node4): node2;` using node4 (VarStorage) instead of Node5 (BindName). Really either _could_ work, since from a BindName we can get to the VarStorage, and that may be reason to switch later if we find it preferable to have the BindName for whatever reason.

But the *actual* value in NameLookup is a BindName so that errors can associate with the _name_ instead of the "storage" parse node, which is currently the `:`. This is mainly for fail_duplicate_decl.carbon, which has a "Previous definition" note that points at the storage's parse node.
2022-12-28 12:55:40 -08:00
Jon Ross-Perkins 5d123189c3 Small cleanups in toolchain code (#2474)
Doing some sorting of functions / enums (generally speaking, I've been trying to keep these loosely lexically sorted for lack of a better ordering).

Also removes some code that seems to be dead, and a minor TODO comment fix.
2022-12-16 15:46:53 -08:00
Kareem Ergawy c74e39dbb3 [parser] More support for interfaces: methods and self deduced param. (#2427)
Summary:

Extends the current support for parsing `interface`s. In particular, adds support for parsing functions and `me` params.
2022-12-16 11:23:02 -08:00
Jon Ross-PerkinsandChandler Carruth 84deb62aef Work on ParseTree structure to use more bracketed structures. (#2416)
This works on multiple statements to make them better for the bracketing model. Stub nodes are added in more cases of invalid syntax, simply so that the semantics has reliably structured input. Comments in parse_node_kind.def now try to show the expected parse tree structure in postorder form.

This labels If, While, and For a little differently in parse nodes so that at the start of the postorder traversal, it'll already be available to semantics which structure is being processed. I need to do a little more with If in particular, but this felt like a reasonable stopping point.

While this makes significant parser changes, the changes to parser_state.def are minimal, mostly naming-related. The actual flow isn't substantively changed, just a couple minor names and the new As(If|While) state which allows distinguishing IfCondition and WhileCondition.

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2022-11-28 15:02:59 -08:00
Kareem Ergawyandergawy a508390423 [parser] Start re-implementing interfaces using the stack parser. (#2412)
First change towards re-implementing interfaces using the new parser. I kept it small to make sure we are on the same page regarding stack states and how the parse tree should look like.

Co-authored-by: ergawy <kareem.ergawy@guardsquare.com>
2022-11-28 12:58:41 -08:00
Jon Ross-Perkins 310cf0d2f9 Refactor Pattern and FunctionParameter handling for Parser consistency (#2385)
While the Parser has similar divergent states, lists of Expressions tend to be handled more like this. I'm keeping the divergent start state in order to continue support of a distinct error, but I think this organization of FunctionParameter/FunctionParameterFinish will be less surprising.
2022-11-15 22:36:52 -08:00
Jon Ross-Perkins cd93ae6618 Finish Parser2 support and switch. (#2381)
Adds remaining expression support, and switches the default to Parser2.

Note, this doesn't delete the current Parser yet. I'll just do that in its own PR.
2022-11-11 08:36:17 -08:00
Jon Ross-PerkinsandChandler Carruth d3be5c2827 Parser2 support for while and expressions (#2379)
Adds `while` and most of the expression support. Splits apart the fixity test to demonstrate more closely which bits are still failing.

```
//toolchain/parser/testdata:basics/fail_paren_match_regression.carbon.test FAILED in 0.8s
//toolchain/parser/testdata:basics/function_call.carbon.test             FAILED in 0.7s
//toolchain/parser/testdata:basics/package.carbon.test                   FAILED in 0.7s
//toolchain/parser/testdata:basics/structs.carbon.test                   FAILED in 0.7s
//toolchain/parser/testdata:basics/tuples.carbon.test                    FAILED in 0.6s
//toolchain/parser/testdata:basics/var.carbon.test                       FAILED in 0.7s
//toolchain/parser/testdata:for/fail_colon_instead_of_in.carbon.test     FAILED in 0.7s
//toolchain/parser/testdata:for/fail_missing_in.carbon.test              FAILED in 0.7s
//toolchain/parser/testdata:for/fail_missing_var.carbon.test             FAILED in 0.7s
//toolchain/parser/testdata:for/nested.carbon.test                       FAILED in 0.6s
//toolchain/parser/testdata:for/simple.carbon.test                       FAILED in 0.8s
//toolchain/parser/testdata:function/definition/with_params.carbon.test  FAILED in 0.8s
//toolchain/parser/testdata:operators/fixity_in_call.carbon.test         FAILED in 0.7s
//toolchain/parser/testdata:operators/fixity_in_var.carbon.test          FAILED in 0.8s
```

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2022-11-10 09:24:54 -08:00
Jon Ross-Perkins 7c102d3726 Adding more function support to the Parser2 rewrite (#2375)
Also does `if` support, discussed refactorings, like PopState/PushState instead of edits.

With these changes, I'm to where I can start talking about what's still missing:

```
//toolchain/parser/testdata:basics/fail_invalid_designators.carbon.test  FAILED in 0.7s
//toolchain/parser/testdata:basics/fail_paren_match_regression.carbon.test FAILED in 0.6s
//toolchain/parser/testdata:basics/function_call.carbon.test             FAILED in 0.7s
//toolchain/parser/testdata:basics/package.carbon.test                   FAILED in 0.7s
//toolchain/parser/testdata:basics/structs.carbon.test                   FAILED in 0.7s
//toolchain/parser/testdata:basics/tuples.carbon.test                    FAILED in 0.6s
//toolchain/parser/testdata:basics/var.carbon.test                       FAILED in 0.7s
//toolchain/parser/testdata:for/fail_colon_instead_of_in.carbon.test     FAILED in 0.6s
//toolchain/parser/testdata:for/fail_missing_in.carbon.test              FAILED in 0.6s
//toolchain/parser/testdata:for/fail_missing_var.carbon.test             FAILED in 0.7s
//toolchain/parser/testdata:for/nested.carbon.test                       FAILED in 0.6s
//toolchain/parser/testdata:for/simple.carbon.test                       FAILED in 0.6s
//toolchain/parser/testdata:function/definition/with_params.carbon.test  FAILED in 0.7s
//toolchain/parser/testdata:operators/associative.carbon.test            FAILED in 0.6s
//toolchain/parser/testdata:operators/fail_missing_precedence_and_or.carbon.test FAILED in 0.6s
//toolchain/parser/testdata:operators/fail_missing_precedence_or_and.carbon.test FAILED in 0.6s
//toolchain/parser/testdata:operators/fail_variety.carbon.test           FAILED in 0.6s
//toolchain/parser/testdata:operators/fixity.carbon.test                 FAILED in 0.9s
//toolchain/parser/testdata:operators/missing_precedence_not.carbon.test FAILED in 0.6s
//toolchain/parser/testdata:operators/postfix_unary.carbon.test          FAILED in 0.7s
//toolchain/parser/testdata:operators/prefix_unary.carbon.test           FAILED in 0.7s
//toolchain/parser/testdata:while/basic.carbon.test                      FAILED in 0.6s
//toolchain/parser/testdata:while/fail_unbraced.carbon.test              FAILED in 0.6s
```

This does modify a couple `if` tests to not test so much expression syntax -- that just seems like unrelated syntax.
2022-11-08 08:47:09 -08:00
Jon Ross-Perkins 9107916b11 Checkpoint for a parser rewrite (#2364)
The intent of this approach is to eliminate recursion limits as a barrier for the parser. While it may not be urgent to address, I want to avoid pouring effort into a parser approach that we don't think will be usable long-term.

Right now this is passing a minor set of tests. It's intended to be enough to show how I'm thinking about flow control for the parser. I'm manually switching back and forth because it seemed like the easiest approach that avoids duplicating tests.
2022-11-02 14:43:40 -07:00