-
Notifications
You must be signed in to change notification settings - Fork 137
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
Custom ternary operators #154
Comments
If we pull out the ternary plugin by default, then different variations could be implemented by others, maybe? Perhaps the Jsep ternary plugin could provide options? What kind of use cases have you come across? |
Not sure what you mean here exactly, could you elaborate? What I was saying is, right now the code for the ternary explicitly checks for
Personally, I use jsep to parse Mavo's expression language, MavoScript. It has a fair bit of word-like operators, e.g. |
The plugin file could export a function that returns the plugin: export (options = {}) => {
const operators = new Set([options.operators | '?']);
const alternatives = new Set([options.alternatives | ':']);
return {
name: 'jsepTernary',
init(jsep) { ... };
}); So the user could then use the plugin something like: import jsepTernary from 'jsep/plugins/jsepTernary.js';
jsep.register(jsepTernary({ operators: ['?', 'by'], alternatives: [':', 'as'] }); However, I can almost see 2 different plugins from your given examples, one that's like a ternary with no alternative ( |
(I'm going to use my use case as a meta-example here, but this applies to most ternary use cases, I think) I was thinking of more along the lines of an Related, should it be possible to add ternary operators with the same symbol as binary operators? |
I think this can be closed by the introducement of: |
I think @LeaVerou 's question was to support non-standard ternary separators (
|
Correct.
I think you may be getting confused with the specific operators, which are merely examples.
IMO it seems far more reasonable to make ternary operators just as generalizable as binary and unary ones than these hacks. |
I think something like this would do what you're asking? (it could be updated to be more efficient. But it deviates from esprima, too by adding the const CONDITIONAL_EXP = 'ConditionalExpression';
export default {
name: 'ternary',
ternaryOps: {
'?': ':',
'by': 'as',
},
addTernaryOp(conditional, alternate) {
this.ternaryOps[conditional] = alternate;
},
removeTernaryOp(conditional) {
delete this.ternaryOps[conditional];
},
init(jsep) {
// Ternary expression: test ? consequent : alternate
const self = this;
jsep.hooks.add('after-expression', function gobbleTernary(env) {
const operator = env.node && Object
.keys(self.ternaryOps)
.find(op => op === this.expr.substr(this.index, op.length));
if (operator) {
this.index++;
const test = env.node;
const consequent = this.gobbleExpression();
if (!consequent) {
this.throwError('Expected expression');
}
this.gobbleSpaces();
if (self.ternaryOps[operator] === this.expr.substr(this.index, operator.length)) {
this.index++;
const alternate = this.gobbleExpression();
if (!alternate) {
this.throwError('Expected expression');
}
env.node = {
type: CONDITIONAL_EXP,
test,
consequent,
alternate,
operator,
};
}
// if binary operator is custom-added (i.e. object plugin), then correct it to a ternary node:
else if (consequent.operator === self.ternaryOps[operator]) {
env.node = {
type: CONDITIONAL_EXP,
test,
consequent: consequent.left,
alternate: consequent.right,
operator,
};
}
else {
this.throwError('Expected :');
}
}
});
},
}; |
This has come up many times in my use cases: Jsep allows custom unary and binary operators, but the ternary operator is implemented ad hoc. It would be nice if there was an analogous
addTernaryOp()
function that allowed custom ternary operators. Possibly via the ternary operator plugin?The text was updated successfully, but these errors were encountered: