-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tuple for Infix sample language #126
base: main
Are you sure you want to change the base?
Conversation
…distinction is TBD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is part 1 of at least 2, maybe 3.
samples/infix/parse.cc
Outdated
// [tuples only] Commas: might be tuple literals, function calls. | ||
R"(,)" >> | ||
[use_parser_tuples](auto& m) { | ||
if (use_parser_tuples) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you may be better off using a separate mode for this logic, which also gives an opportunity to teach about parser modes. Basically, if the use_parser_tuples
flag is set, then jump into a paren
mode and then pop back to start
once you encounter the close paren. That way you don't have to worry about doing these checks. There will be some duplication of patterns, but that may actually help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. I'm ambivalent about modes helping here (since the two effective modes are so very close), but it's worth a try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up writing the same pass cloned twice with one tiny difference. You still need to count parentheses, anyhow...
Well, not sure if we actually need the separate modes, but it is nicer to work with using the parentheses counter, so maybe keep that at least?
samples/infix/reader.cc
Outdated
// in the parser. | ||
In(Expression) * | ||
(T(Paren)[Paren] | ||
<< T(Group)[Group])(enable_if_parens_no_parser_tuples) >> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might make sense to add a scanning of the group for a comma to the predicate? Something like:
([](auto& n){
return enable_if_parens_no_parser_tuples && n.front().contains(Comma);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I discuss this design option in the prose; I didn't implement it. Arguably it is a 4th option for this tutorial, and should not replace this demonstration of what happens when you don't.
Doing the comma lookahead instead of other approaches would be much simpler, but would also be very case-specific and would give fewer chances to show big rulesets.
// --- if not, see next section | ||
|
||
// the initial 2-element tuple case | ||
In(Expression) * T(TupleCandidate)[TupleCandidate] * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this rule a bit confusing. What is a sample input that would produce this sequence of tokens? Given that parentheses are required, it feels like this would be something like:
(6 / 3, 2) 1 + 1, 5 - 3
Which I didn't think was valid (when parens are required).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parentheses are stripped in the expression
pass, so this case is needed for just (6 / 3, 2)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra note: the TupleCandidate
part marks expressions that once had parentheses.
@@ -358,6 +513,42 @@ namespace | |||
return false; | |||
} | |||
|
|||
// These 2 outputs below are a postfix encoding of variadic operations, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you pushed the size first it would be closer to what a typical postfix approach would be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that works. The size has to be where it is, as the tuple
operator has to pop it first unconditionally. Putting it at the other end means the tuple
has to already know how many elements it needs to pop to get to it.
Realistically, the prose is actually a little smarter and explains that Forth dialects usually have a special syntax for tuples rather than this counting stuff, but as-is I think this is the only way round it can work.
Adds 3 different implementations of tuples in Infix, optionally enabled via flags.
Pending:
Prose write-up in the Markdown file(s).Possibly minor clean-up on the testing code. I tried to keep it organized, but I'm not sure about polish.Done:
Might need reverting:
changes to how the maths pass handles calculations (wondered what it would look like, but probably overcomplicated)Bug in infix language that's not fixed:x = 5 = 6;
is accepted with no error