-
Notifications
You must be signed in to change notification settings - Fork 65
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
Add support for plucking values with @ #89
Conversation
I back-ported the code from pegjs:HEAD, and got the tests to run. Figured I'd check in here so people could start to comment. I'm not 100% sold on this being the way forward, but having something to comment on felt like the next step. |
@@ -3,7 +3,7 @@ | |||
const asts = require("../asts"); | |||
const js = require("../js"); | |||
const op = require("../opcodes"); | |||
const VERSION = require('../../version') | |||
const VERSION = require("../../version"); |
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.
unrelated lint bug that needs to be landed even if this patch doesn't.
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 that this should be in the it's own PR or, at least, commit, together with other two unrelated changes in the package.json
])); | ||
|
||
expect(pass).to.changeAST("start = 'a' @'b' @'c'", bytecodeDetails([ | ||
// write a tool to generate comments |
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 decided to punt on making this pretty since we have #81 in the backlog.
I've fiddled around with the grammar, and this will work just fine if we want to add decorators later:
This was the use case I was most worried about impacting. I'm also interested in how we're going to do things like importing other grammars. Do people have existing syntax for that in other forks? |
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.
Also need to add an opcode description to the header comment of the generate-bytecode.js
); | ||
} | ||
|
||
if (node.expression.type.startsWith("semantic_")) { |
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.
It is better to forbid that on the grammar level. I understand that you just picked up the existing implementation, so that can be done in the follow up PR, but personally I prefer to keep the commit history as clean as we can (without "fix" commits). So if it possible it is better to make now
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.
The easiest fix is to just call error
inside of LabeledExpression if the type of the expression is bad, but that feels like a cheat. It's important that @$[a-z]i+
works, which is also in PrefixedExpression. Refactoring the grammar to get all of that nuance in feels like it would be more confusing than the quick fix, though.
Opinions?
I have one, but I don't like it more (pegjs/pegjs#308). I tend to use JS-familiar syntax: import rule_name from 'grammar';
import {rule1, rule2 as alias} from "grammar";
// usage
start
= rule_name
/ rule1
/ alias
;
|
@Mingun can you look at this please? I'm not familiar enough with the idioms used in those comments: // [30] PLUCK
//
// stack.pop(ip + 1);
// stack.push(ip + 3);
// ...
// stack.push(ip + 3 + [ip + 2]); the layout is [op.PLUCK, total_number_of_expression_items, number_of_plucks, pluck0, pluck1, ...] |
In order to make bytecode compatible with my other PRs, that I plan to port in the nearing future (ranges) it will make sense if you change PLUCK opcode number to Then the comment will look that: // [36] PLUCK n, k, p1, ..., pK
//
// value = [stack[p1], ..., stack[pK]]; // when k != 1
// -or-
// value = stack[p1]; // when k == 1
//
// stack.pop(n);
// stack.push(value);
// ( |
Done. See if you're willing to live with my change to the |
I'm going to squash this commit once I have @Mingun 's review of my latest changes. |
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.
Except the incorrect comment all good 👍 LGTM
Done. See if you're willing to live with my change to the
semantic_
checks, please?
Yes, good change
// [30] PLUCK | ||
// | ||
// stack.pop(ip + 1); | ||
// stack.push(ip + 3); | ||
// ... | ||
// stack.push(ip + 3 + [ip + 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.
That is not the same thing as I described. In the end stack
should contain one Array
object with k
elements, not the k
elements, as you might think from the current description
// [30] PLUCK | |
// | |
// stack.pop(ip + 1); | |
// stack.push(ip + 3); | |
// ... | |
// stack.push(ip + 3 + [ip + 2]); | |
// | |
// [36] PLUCK n, k, p1, ..., pK | |
// | |
// value = [stack[p1], ..., stack[pK]]; // when k != 1 | |
// -or- | |
// value = stack[p1]; // when k == 1 | |
// | |
// stack.pop(n); | |
// stack.push(value); | |
// |
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.
oh. heh, i didn't save that buffer. willfix
Squashed. |
Just remembered: it is good practice to update |
// Compiler pass to ensure the following are enforced: | ||
// | ||
// - plucking can not be done with an action block | ||
// - cannot pluck a semantic predicate |
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.
// - cannot pluck a semantic predicate |
Checked in the grammar
function reports(message, edgecases) { | ||
it(message, () => { | ||
edgecases.forEach(grammar => expect(pass).to.reportError(grammar)); | ||
}); | ||
} |
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.
Hadn't noticed before... need to check that location information in the error reports correct location. Here or whatever where similar checks is performed
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.
Willfix by undoing this reports
function and inlining the two tests.
Good call, will do |
OK, @Mingun I've got all of your feedback in, I think. Please double-check before I merge? |
Fixes #38 |
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.
For the sake of code purity, could you make a little rebase?
- fix lint errors (single quote to double quote, etc.)
- change matrix
- add changelog for not mentioned changes
- implement plucking without regenerating parser
- actual implementation
- documentation
- changelog
- tests
- maybe examples
- regenerate parser (examples also could be updated here)
In that case in the each point in the history project will able to build without errors and each commit will do the only one thing.
Fuhh... I think, that's all. Good work!
describe("compiler pass |reportIncorrectPlucking|", function() { | ||
it("prevents \"@\" from being used with an action block", function() { | ||
expect(pass).to.reportError("start1 = 'a' @'b' 'c' { /* empty action block */ }", { | ||
message: "\"@\" cannot be used with an action block at line 1, column 14." |
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.
message: "\"@\" cannot be used with an action block at line 1, column 14." | |
message: "\"@\" cannot be used with an action block at line 1, column 14.", | |
location: { | |
start: { offset: 13, line: 1, column: 14 }, | |
end: { offset: 17, line: 1, column: 18 } | |
} |
Actually, text in the message should point to the beginning of the action block (opening {
), but right now:
- that information is unavailable (action block
location
covers expression and the action itself) - other check passes that work with actions also should be modified
So for now will live with that
I'm willing to do that, but don't think i've done a rebase in that direction before. Can you point me to docs, or give me quick set of bullets on the mechanics, please? |
nm, i found https://stackoverflow.com/a/6217314/8388 which has the info i need. |
Done. I removed the matrix change, since @StoneCypher is making that change in his PR in progress. |
@Mingun final-final approval? I want to get this landed and cut a release. |
Yes, final 👍 |
This still needs docs, and prototyping to make sure we can add other @-related things later.
See #38