2019-09-15 14:16:32 +02:00
|
|
|
import { AutoTypeRunner } from 'auto-type/auto-type-runner';
|
2016-04-08 17:40:00 +02:00
|
|
|
|
2017-01-31 07:50:28 +01:00
|
|
|
const AutoTypeParser = function(sequence) {
|
2016-04-08 17:40:00 +02:00
|
|
|
this.sequence = sequence;
|
|
|
|
this.ix = 0;
|
|
|
|
this.states = [];
|
|
|
|
};
|
|
|
|
|
2017-05-06 19:28:22 +02:00
|
|
|
AutoTypeParser.opRegex = /^(.*?)(?:([\s:=])[\s:=]*(.*))?$/;
|
2016-04-08 17:40:00 +02:00
|
|
|
|
|
|
|
AutoTypeParser.prototype.parse = function() {
|
2017-01-31 07:50:28 +01:00
|
|
|
const len = this.sequence.length;
|
2016-04-08 17:40:00 +02:00
|
|
|
this.pushState();
|
|
|
|
while (this.ix < len) {
|
2017-01-31 07:50:28 +01:00
|
|
|
const ch = this.sequence[this.ix];
|
2016-04-08 17:40:00 +02:00
|
|
|
switch (ch) {
|
|
|
|
case '{':
|
|
|
|
this.readOp();
|
2016-04-08 22:33:07 +02:00
|
|
|
continue;
|
2016-04-08 17:40:00 +02:00
|
|
|
case '+':
|
|
|
|
case '%':
|
|
|
|
case '^':
|
|
|
|
this.readModifier(ch);
|
|
|
|
break;
|
|
|
|
case '(':
|
|
|
|
this.pushState();
|
|
|
|
break;
|
|
|
|
case ')':
|
|
|
|
this.popState();
|
|
|
|
break;
|
2016-04-09 08:29:30 +02:00
|
|
|
case ' ':
|
|
|
|
break;
|
2016-04-08 17:40:00 +02:00
|
|
|
case '~':
|
2016-04-09 14:55:27 +02:00
|
|
|
this.addOp('enter');
|
2016-04-08 17:40:00 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
this.addChar(ch);
|
|
|
|
break;
|
|
|
|
}
|
2016-04-08 22:33:07 +02:00
|
|
|
this.ix++;
|
2016-04-08 17:40:00 +02:00
|
|
|
}
|
2016-04-08 22:33:07 +02:00
|
|
|
if (this.states.length !== 1) {
|
2016-04-08 17:40:00 +02:00
|
|
|
throw 'Groups count mismatch';
|
|
|
|
}
|
|
|
|
return new AutoTypeRunner(this.state().ops);
|
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.pushState = function() {
|
|
|
|
this.states.unshift({
|
|
|
|
modifiers: null,
|
|
|
|
ops: []
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.popState = function() {
|
|
|
|
if (this.states.length <= 1) {
|
|
|
|
throw 'Unexpected ")" at index ' + this.ix;
|
|
|
|
}
|
2017-01-31 07:50:28 +01:00
|
|
|
const state = this.states.shift();
|
2016-04-08 17:40:00 +02:00
|
|
|
this.addState(state);
|
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.state = function() {
|
|
|
|
return this.states[0];
|
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.readOp = function() {
|
2017-01-31 07:50:28 +01:00
|
|
|
const toIx = this.sequence.indexOf('}', this.ix + 2);
|
2016-04-08 17:40:00 +02:00
|
|
|
if (toIx < 0) {
|
|
|
|
throw 'Mismatched "{" at index ' + this.ix;
|
|
|
|
}
|
2017-01-31 07:50:28 +01:00
|
|
|
const contents = this.sequence.substring(this.ix + 1, toIx);
|
2016-04-08 17:40:00 +02:00
|
|
|
this.ix = toIx + 1;
|
|
|
|
if (contents.length === 1) {
|
|
|
|
this.addChar(contents);
|
|
|
|
return;
|
|
|
|
}
|
2017-05-06 19:28:22 +02:00
|
|
|
const [, op, sep, arg] = contents.match(AutoTypeParser.opRegex);
|
|
|
|
this.addOp(op, sep, arg);
|
2016-04-08 17:40:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.readModifier = function(modifier) {
|
2017-01-31 07:50:28 +01:00
|
|
|
const state = this.state();
|
2016-04-08 17:40:00 +02:00
|
|
|
if (!state.modifiers) {
|
|
|
|
state.modifiers = {};
|
|
|
|
}
|
|
|
|
if (modifier === '^' && state.modifiers['^']) {
|
2016-04-08 22:33:07 +02:00
|
|
|
delete state.modifiers['^'];
|
2016-04-08 17:40:00 +02:00
|
|
|
modifier = '^^';
|
|
|
|
}
|
|
|
|
state.modifiers[modifier] = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.resetModifiers = function() {
|
2017-01-31 07:50:28 +01:00
|
|
|
const state = this.state();
|
|
|
|
const modifiers = state.modifiers;
|
2016-04-08 22:33:07 +02:00
|
|
|
state.modifiers = null;
|
|
|
|
return modifiers;
|
2016-04-08 17:40:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.addState = function(state) {
|
|
|
|
this.state().ops.push({
|
|
|
|
type: 'group',
|
|
|
|
value: state.ops,
|
|
|
|
mod: this.resetModifiers()
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.addChar = function(ch) {
|
|
|
|
this.state().ops.push({
|
|
|
|
type: 'text',
|
|
|
|
value: ch,
|
|
|
|
mod: this.resetModifiers()
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
AutoTypeParser.prototype.addOp = function(op, sep, arg) {
|
|
|
|
this.state().ops.push({
|
|
|
|
type: 'op',
|
|
|
|
value: op,
|
|
|
|
mod: this.resetModifiers(),
|
2019-08-18 10:17:09 +02:00
|
|
|
sep,
|
|
|
|
arg
|
2016-04-08 17:40:00 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2019-09-15 14:16:32 +02:00
|
|
|
export { AutoTypeParser };
|