walt-compiler
Version:
Alternative syntax for WebAssembly text format
1,140 lines (1,008 loc) • 204 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.Walt = {})));
}(this, (function (exports) { 'use strict';
var immutable = extend;
var hasOwnProperty = Object.prototype.hasOwnProperty;
function extend() {
var target = {};
for (var i = 0; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
}
const identity = id => id;
function map(visitors) {
function mapper(input) {
if (!Array.isArray(input)) {
throw new Error('Transform must be used on an Array. Received ' + JSON.stringify(input));
}
const visitor = (() => {
const [node] = input;
if (node.Type in visitors && typeof visitors[node.Type] === 'function') {
return visitors[node.Type];
}
return identity;
})();
if (visitor.length === 2) {
return visitor(input, mapper);
}
const [node, ...rest] = visitor(input);
const params = node.params.filter(Boolean).map(child => mapper([child, ...rest]));
return immutable(node, { params });
}
return mapper;
}
// This should maybe be it's own module.
function mapNode$2(visitor) {
const nodeMapper = node => {
if (node == null) {
return node;
}
const mappingFunction = (() => {
if ('*' in visitor && typeof visitor['*'] === 'function') {
return visitor['*'];
}
if (node.Type in visitor && typeof visitor[node.Type] === 'function') {
return visitor[node.Type];
}
return identity;
})();
if (mappingFunction.length === 2) {
return mappingFunction(node, nodeMapper);
}
const mappedNode = mappingFunction(node);
const params = mappedNode.params.map(nodeMapper);
return immutable(mappedNode, { params });
};
return nodeMapper;
}
var mapNode_1$1 = {
map,
mapNode: mapNode$2
};
var mapNode = mapNode_1$1;
var mapNode_1 = mapNode.map;
var mapNode_2 = mapNode.mapNode;
// Dead simple AST walker, takes a visitor object and calls all methods for
// appropriate node Types.
var walkNode$2 = function (visitor) {
const walkNode = node => {
if (node == null) {
return node;
}
const { params } = node;
const mappingFunction = (() => {
if ('*' in visitor && typeof visitor['*'] === 'function') {
return visitor['*'];
}
if (node.Type in visitor && typeof visitor[node.Type] === 'function') {
return visitor[node.Type];
}
return () => node;
})();
if (mappingFunction.length === 2) {
mappingFunction(node, walkNode);
return node;
}
mappingFunction(node);
params.forEach(walkNode);
return node;
};
return walkNode;
};
var walkNode = walkNode$2;
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
var invariant = function (condition, format, a, b, c, d, e, f) {
if (format === undefined) {
throw new Error('invariant requires an error message argument');
}
if (!condition) {
var error;
if (format === undefined) {
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
} else {
var args = [a, b, c, d, e, f];
var argIndex = 0;
error = new Error(format.replace(/%s/g, function () {
return args[argIndex++];
}));
error.name = 'Invariant Violation';
}
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
}
};
var invariant_1 = invariant;
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function unwrapExports (x) {
return x && x.__esModule ? x['default'] : x;
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var waltSyntax = createCommonjsModule(function (module, exports) {
(function (global, factory) {
factory(exports);
})(commonjsGlobal, function (exports) {
const tokens = {
whitespace: /[ \t]+/,
comment: [{ match: /\/\/.*?$/ }, { match: /\/\*[^]*?\*\//, lineBreaks: true }],
number: [{ match: /0[xX][0-9a-fA-F]+/ }, { match: /0[oO][0-9]+/ }, { match: /0[bB][01]+/ }, { match: /(?:[0-9]+(?:\.[0-9]+)?e-?[0-9]+)/ }, { match: /[0-9]+\.[0-9]+|[0-9]+/ }],
char: [{ match: /'(?:\\['\\bfnrtv0]|[^'\\\n])'/, value: x => x.slice(1, -1) }],
string: [{ match: /"(?:\\["\\rn]|[^"\\\n])*?"/, value: x => x.slice(1, -1) }, { match: /'(?:\\['\\bfnrtv0]|[^'\\\n])*?'/, value: x => x.slice(1, -1) }, { match: /`(?:\\['\\bfnrtv0]|[^'\\])*?`/, value: x => x.slice(1, -1) }],
identifier: {
match: /[A-Za-z_$][A-Za-z0-9_$]*/,
keywords: { keyword: [
// EcmaScript
'break', 'if', 'else', 'import', 'as', 'from', 'export', 'return', 'switch', 'case', 'default', 'const', 'let', 'for', 'continue', 'do', 'while', 'throw', 'function',
// s-expression
'global', 'module', 'type', 'lambda'], type: ['i32', 'i64', 'f32', 'f64', 'bool'] }
},
punctuator: ['+', '++', '-', '--', '>>', '>>>', '<<', '=', '==', '+=', '-=', '=>', '<=', '>=', '!=', '%', '*', '/', '^', '&', '~', '|', '!', '**', ':', '(', ')', '.', '{', '}', ',', '[', ']', ';', '>', '<', '?', '||', '&&', '{', '}', '...'],
newline: { match: /(?:\r\n|\r|\n)/, lineBreaks: true }
};
// Main Program
const Program = 'Program';
const Keyword = 'Keyword';
const Export = 'Export';
const Import = 'Import';
const Statement = 'Statement';
const IfThenElse = 'IfThenElse';
const Select = 'Select';
const Else = 'Else';
const UnaryExpression = 'UnaryExpression';
const BinaryExpression = 'BinaryExpression';
const TernaryExpression = 'TernaryExpression';
const NumberLiteral = 'NumberLiteral';
const StringLiteral = 'StringLiteral';
const CharacterLiteral = 'CharacterLiteral';
const Punctuator = 'Punctuator';
const Identifier = 'Identifier';
const ArraySubscript = 'ArraySubscript';
const Constant = 'Constant';
const Type = 'Type';
const ArrayType = 'ArrayType';
const DeclType = 'DeclType';
const GenericType = 'GenericType';
const UserType = 'UserType';
const FunctionType = 'FunctionType';
const Declaration = 'Declaration';
const StaticDeclaration = 'StaticDeclaration';
const StaticValueList = 'StaticValueList';
const ImmutableDeclaration = 'ImmutableDeclaration';
const FunctionDeclaration = 'FunctionDeclaration';
const ArrayDeclaration = 'ArrayDeclaration';
const IndirectFunctionCall = 'IndirectFunctionCall';
const FunctionCall = 'FunctionCall';
const Loop = 'Loop';
const MemoryAssignment = 'MemoryAssignment';
const Assignment = 'Assignment';
const AssignmentExpression = 'AssignmentExpression';
const Param = 'Param';
const Typedef = 'Typedef';
const Struct = 'Struct';
const UnionType = 'UnionType';
const ReturnStatement = 'ReturnStatement';
const Sequence = 'Sequence';
const ObjectLiteral = 'ObjectLiteral';
const Pair = 'Pair';
const TypeCast = 'TypeCast';
const Break = 'Break';
const Comment = 'Comment';
const Sizeof = 'Sizeof';
const Spread = 'Spread';
const Closure = 'Closure';
const Noop = 'Noop';
const ClosureType = 'ClosureType';
const Block = 'Block';
const ObjectField = 'ObjectField';
const FunctionIndex = 'FunctionIndex';
const FunctionIdentifier = 'FunctionIdentifier';
const FunctionPointer = 'FunctionPointer';
const FunctionArguments = 'FunctionArguments';
const FunctionResult = 'FunctionResult';
const FunctionLocals = 'FunctionLocals';
const NativeMethod = 'NativeMethod';
const Unreachable = 'Unreachable';
const Access = 'Access';
const i32 = 'i32';
const f32 = 'f32';
const i64 = 'i64';
const f64 = 'f64';
const Memory = 'Memory';
const Table = 'Table';
const bool = 'bool';
exports.Program = Program;
exports.Keyword = Keyword;
exports.Export = Export;
exports.Import = Import;
exports.Statement = Statement;
exports.IfThenElse = IfThenElse;
exports.Select = Select;
exports.Else = Else;
exports.UnaryExpression = UnaryExpression;
exports.BinaryExpression = BinaryExpression;
exports.TernaryExpression = TernaryExpression;
exports.NumberLiteral = NumberLiteral;
exports.StringLiteral = StringLiteral;
exports.CharacterLiteral = CharacterLiteral;
exports.Punctuator = Punctuator;
exports.Identifier = Identifier;
exports.ArraySubscript = ArraySubscript;
exports.Constant = Constant;
exports.Type = Type;
exports.ArrayType = ArrayType;
exports.DeclType = DeclType;
exports.GenericType = GenericType;
exports.UserType = UserType;
exports.FunctionType = FunctionType;
exports.Declaration = Declaration;
exports.StaticDeclaration = StaticDeclaration;
exports.StaticValueList = StaticValueList;
exports.ImmutableDeclaration = ImmutableDeclaration;
exports.FunctionDeclaration = FunctionDeclaration;
exports.ArrayDeclaration = ArrayDeclaration;
exports.IndirectFunctionCall = IndirectFunctionCall;
exports.FunctionCall = FunctionCall;
exports.Loop = Loop;
exports.MemoryAssignment = MemoryAssignment;
exports.Assignment = Assignment;
exports.AssignmentExpression = AssignmentExpression;
exports.Param = Param;
exports.Typedef = Typedef;
exports.Struct = Struct;
exports.UnionType = UnionType;
exports.ReturnStatement = ReturnStatement;
exports.Sequence = Sequence;
exports.ObjectLiteral = ObjectLiteral;
exports.Pair = Pair;
exports.TypeCast = TypeCast;
exports.Break = Break;
exports.Comment = Comment;
exports.Sizeof = Sizeof;
exports.Spread = Spread;
exports.Closure = Closure;
exports.Noop = Noop;
exports.ClosureType = ClosureType;
exports.Block = Block;
exports.ObjectField = ObjectField;
exports.FunctionIndex = FunctionIndex;
exports.FunctionIdentifier = FunctionIdentifier;
exports.FunctionPointer = FunctionPointer;
exports.FunctionArguments = FunctionArguments;
exports.FunctionResult = FunctionResult;
exports.FunctionLocals = FunctionLocals;
exports.NativeMethod = NativeMethod;
exports.Unreachable = Unreachable;
exports.Access = Access;
exports.i32 = i32;
exports.f32 = f32;
exports.i64 = i64;
exports.f64 = f64;
exports.Memory = Memory;
exports.Table = Table;
exports.bool = bool;
exports.builtinTypes = {
i32,
f32,
i64,
f64,
Memory,
Table,
bool
};
exports.statements = {
// Main Program
Program,
// Syntax Nodes
Export,
Import,
IfThenElse,
Else,
Declaration,
ImmutableDeclaration,
FunctionDeclaration,
ArrayDeclaration,
Loop,
MemoryAssignment,
Assignment,
Typedef,
Struct,
UnionType,
ReturnStatement,
Sequence,
ObjectLiteral,
Pair,
Break,
Comment,
Sizeof,
Spread,
Noop,
Block,
Unreachable
};
exports.default = {
// Main Program
Program,
// Syntax Nodes
Keyword,
Export,
Import,
Statement,
IfThenElse,
Select,
Else,
UnaryExpression,
BinaryExpression,
TernaryExpression,
NumberLiteral,
StringLiteral,
CharacterLiteral,
Punctuator,
Identifier,
ArraySubscript,
Constant,
Type,
ArrayType,
DeclType,
GenericType,
UserType,
FunctionType,
Declaration,
ImmutableDeclaration,
FunctionDeclaration,
ArrayDeclaration,
StaticDeclaration,
StaticValueList,
IndirectFunctionCall,
FunctionCall,
Loop,
MemoryAssignment,
Assignment,
AssignmentExpression,
Param,
Typedef,
Struct,
UnionType,
ReturnStatement,
Sequence,
ObjectLiteral,
Pair,
TypeCast,
Break,
Comment,
Sizeof,
Spread,
Closure,
Access,
Noop,
// Semantic Nodes
ClosureType,
Block,
ObjectField,
FunctionIndex,
FunctionIdentifier,
FunctionPointer,
FunctionArguments,
FunctionResult,
FunctionLocals,
// Natives
NativeMethod,
Unreachable
};
exports.tokens = tokens;
Object.defineProperty(exports, '__esModule', { value: true });
});
});
var Syntax = unwrapExports(waltSyntax);
var waltSyntax_1 = waltSyntax.tokens;
var waltSyntax_2 = waltSyntax.semantics;
var waltSyntax_3 = waltSyntax.builtinTypes;
var waltSyntax_4 = waltSyntax.statements;
var waltSyntax_5 = waltSyntax.i32;
var waltSyntax_6 = waltSyntax.f32;
var waltSyntax_7 = waltSyntax.i64;
var waltSyntax_8 = waltSyntax.f64;
var moo = createCommonjsModule(function (module) {
(function (root, factory) {
if (typeof undefined === 'function' && undefined.amd) {
undefined([], factory); /* global define */
} else if ('object' === 'object' && module.exports) {
module.exports = factory();
} else {
root.moo = factory();
}
})(commonjsGlobal, function () {
var hasOwnProperty = Object.prototype.hasOwnProperty;
// polyfill assign(), so we support IE9+
var assign = typeof Object.assign === 'function' ? Object.assign :
// https://tc39.github.io/ecma262/#sec-object.assign
function (target, sources) {
if (target == null) {
throw new TypeError('Target cannot be null or undefined');
}
target = Object(target);
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
if (source == null) continue;
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var hasSticky = typeof new RegExp().sticky === 'boolean';
/***************************************************************************/
function isRegExp(o) {
return o && o.constructor === RegExp;
}
function isObject(o) {
return o && typeof o === 'object' && o.constructor !== RegExp && !Array.isArray(o);
}
function reEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function reGroups(s) {
var re = new RegExp('|' + s);
return re.exec('').length - 1;
}
function reCapture(s) {
return '(' + s + ')';
}
function reUnion(regexps) {
var source = regexps.map(function (s) {
return "(?:" + s + ")";
}).join('|');
return "(?:" + source + ")";
}
function regexpOrLiteral(obj) {
if (typeof obj === 'string') {
return '(?:' + reEscape(obj) + ')';
} else if (isRegExp(obj)) {
// TODO: consider /u support
if (obj.ignoreCase) {
throw new Error('RegExp /i flag not allowed');
}
if (obj.global) {
throw new Error('RegExp /g flag is implied');
}
if (obj.sticky) {
throw new Error('RegExp /y flag is implied');
}
if (obj.multiline) {
throw new Error('RegExp /m flag is implied');
}
return obj.source;
} else {
throw new Error('not a pattern: ' + obj);
}
}
function objectToRules(object) {
var keys = Object.getOwnPropertyNames(object);
var result = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var thing = object[key];
var rules = Array.isArray(thing) ? thing : [thing];
var match = [];
rules.forEach(function (rule) {
if (isObject(rule)) {
if (match.length) result.push(ruleOptions(key, match));
result.push(ruleOptions(key, rule));
match = [];
} else {
match.push(rule);
}
});
if (match.length) result.push(ruleOptions(key, match));
}
return result;
}
function arrayToRules(array) {
var result = [];
for (var i = 0; i < array.length; i++) {
var obj = array[i];
if (!obj.name) {
throw new Error('Rule has no name: ' + JSON.stringify(obj));
}
result.push(ruleOptions(obj.name, obj));
}
return result;
}
function ruleOptions(name, obj) {
if (typeof obj !== 'object' || Array.isArray(obj) || isRegExp(obj)) {
obj = { match: obj };
}
// nb. error implies lineBreaks
var options = assign({
tokenType: name,
lineBreaks: !!obj.error,
pop: false,
next: null,
push: null,
error: false,
value: null,
getType: null
}, obj);
// convert to array
var match = options.match;
options.match = Array.isArray(match) ? match : match ? [match] : [];
options.match.sort(function (a, b) {
return isRegExp(a) && isRegExp(b) ? 0 : isRegExp(b) ? -1 : isRegExp(a) ? +1 : b.length - a.length;
});
if (options.keywords) {
options.getType = keywordTransform(options.keywords);
}
return options;
}
function compileRules(rules, hasStates) {
rules = Array.isArray(rules) ? arrayToRules(rules) : objectToRules(rules);
var errorRule = null;
var groups = [];
var parts = [];
for (var i = 0; i < rules.length; i++) {
var options = rules[i];
if (options.error) {
if (errorRule) {
throw new Error("Multiple error rules not allowed: (for token '" + options.tokenType + "')");
}
errorRule = options;
}
// skip rules with no match
if (options.match.length === 0) {
continue;
}
groups.push(options);
// convert to RegExp
var pat = reUnion(options.match.map(regexpOrLiteral));
// validate
var regexp = new RegExp(pat);
if (regexp.test("")) {
throw new Error("RegExp matches empty string: " + regexp);
}
var groupCount = reGroups(pat);
if (groupCount > 0) {
throw new Error("RegExp has capture groups: " + regexp + "\nUse (?: … ) instead");
}
if (!hasStates && (options.pop || options.push || options.next)) {
throw new Error("State-switching options are not allowed in stateless lexers (for token '" + options.tokenType + "')");
}
// try and detect rules matching newlines
if (!options.lineBreaks && regexp.test('\n')) {
throw new Error('Rule should declare lineBreaks: ' + regexp);
}
// store regex
parts.push(reCapture(pat));
}
var suffix = hasSticky ? '' : '|(?:)';
var flags = hasSticky ? 'ym' : 'gm';
var combined = new RegExp(reUnion(parts) + suffix, flags);
return { regexp: combined, groups: groups, error: errorRule };
}
function compile(rules) {
var result = compileRules(rules);
return new Lexer({ start: result }, 'start');
}
function compileStates(states, start) {
var keys = Object.getOwnPropertyNames(states);
if (!start) start = keys[0];
var map = Object.create(null);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
map[key] = compileRules(states[key], true);
}
for (var i = 0; i < keys.length; i++) {
var groups = map[keys[i]].groups;
for (var j = 0; j < groups.length; j++) {
var g = groups[j];
var state = g && (g.push || g.next);
if (state && !map[state]) {
throw new Error("Missing state '" + state + "' (in token '" + g.tokenType + "' of state '" + keys[i] + "')");
}
if (g && g.pop && +g.pop !== 1) {
throw new Error("pop must be 1 (in token '" + g.tokenType + "' of state '" + keys[i] + "')");
}
}
}
return new Lexer(map, start);
}
function keywordTransform(map) {
var reverseMap = Object.create(null);
var byLength = Object.create(null);
var types = Object.getOwnPropertyNames(map);
for (var i = 0; i < types.length; i++) {
var tokenType = types[i];
var item = map[tokenType];
var keywordList = Array.isArray(item) ? item : [item];
keywordList.forEach(function (keyword) {
(byLength[keyword.length] = byLength[keyword.length] || []).push(keyword);
if (typeof keyword !== 'string') {
throw new Error("keyword must be string (in keyword '" + tokenType + "')");
}
reverseMap[keyword] = tokenType;
});
}
// fast string lookup
// https://jsperf.com/string-lookups
function str(x) {
return JSON.stringify(x);
}
var source = '';
source += '(function(value) {\n';
source += 'switch (value.length) {\n';
for (var length in byLength) {
var keywords = byLength[length];
source += 'case ' + length + ':\n';
source += 'switch (value) {\n';
keywords.forEach(function (keyword) {
var tokenType = reverseMap[keyword];
source += 'case ' + str(keyword) + ': return ' + str(tokenType) + '\n';
});
source += '}\n';
}
source += '}\n';
source += '})';
return eval(source); // getType
}
/***************************************************************************/
var Lexer = function (states, state) {
this.startState = state;
this.states = states;
this.buffer = '';
this.stack = [];
this.reset();
};
Lexer.prototype.reset = function (data, info) {
this.buffer = data || '';
this.index = 0;
this.line = info ? info.line : 1;
this.col = info ? info.col : 1;
this.setState(info ? info.state : this.startState);
return this;
};
Lexer.prototype.save = function () {
return {
line: this.line,
col: this.col,
state: this.state
};
};
Lexer.prototype.setState = function (state) {
if (!state || this.state === state) return;
this.state = state;
var info = this.states[state];
this.groups = info.groups;
this.error = info.error || { lineBreaks: true, shouldThrow: true };
this.re = info.regexp;
};
Lexer.prototype.popState = function () {
this.setState(this.stack.pop());
};
Lexer.prototype.pushState = function (state) {
this.stack.push(this.state);
this.setState(state);
};
Lexer.prototype._eat = hasSticky ? function (re) {
// assume re is /y
return re.exec(this.buffer);
} : function (re) {
// assume re is /g
var match = re.exec(this.buffer);
// will always match, since we used the |(?:) trick
if (match[0].length === 0) {
return null;
}
return match;
};
Lexer.prototype._getGroup = function (match) {
if (match === null) {
return -1;
}
var groupCount = this.groups.length;
for (var i = 0; i < groupCount; i++) {
if (match[i + 1] !== undefined) {
return i;
}
}
throw new Error('oops');
};
function tokenToString() {
return this.value;
}
Lexer.prototype.next = function () {
var re = this.re;
var buffer = this.buffer;
var index = re.lastIndex = this.index;
if (index === buffer.length) {
return; // EOF
}
var match = this._eat(re);
var i = this._getGroup(match);
var group, text;
if (i === -1) {
group = this.error;
// consume rest of buffer
text = buffer.slice(index);
} else {
text = match[0];
group = this.groups[i];
}
// count line breaks
var lineBreaks = 0;
if (group.lineBreaks) {
var matchNL = /\n/g;
var nl = 1;
if (text === '\n') {
lineBreaks = 1;
} else {
while (matchNL.exec(text)) {
lineBreaks++;nl = matchNL.lastIndex;
}
}
}
var token = {
type: group.getType && group.getType(text) || group.tokenType,
value: group.value ? group.value(text) : text,
text: text,
toString: tokenToString,
offset: index,
lineBreaks: lineBreaks,
line: this.line,
col: this.col
// nb. adding more props to token object will make V8 sad!
};var size = text.length;
this.index += size;
this.line += lineBreaks;
if (lineBreaks !== 0) {
this.col = size - nl + 1;
} else {
this.col += size;
}
// throw, if no rule with {error: true}
if (group.shouldThrow) {
throw new Error(this.formatError(token, "invalid syntax"));
}
if (group.pop) this.popState();else if (group.push) this.pushState(group.push);else if (group.next) this.setState(group.next);
return token;
};
if (typeof Symbol !== 'undefined' && Symbol.iterator) {
var LexerIterator = function (lexer) {
this.lexer = lexer;
};
LexerIterator.prototype.next = function () {
var token = this.lexer.next();
return { value: token, done: !token };
};
LexerIterator.prototype[Symbol.iterator] = function () {
return this;
};
Lexer.prototype[Symbol.iterator] = function () {
return new LexerIterator(this);
};
}
Lexer.prototype.formatError = function (token, message) {
var value = token.value;
var index = token.offset;
var eol = token.lineBreaks ? value.indexOf('\n') : value.length;
var start = Math.max(0, index - token.col + 1);
var firstLine = this.buffer.substring(start, index + eol);
message += " at line " + token.line + " col " + token.col + ":\n\n";
message += " " + firstLine + "\n";
message += " " + Array(token.col).join(" ") + "^";
return message;
};
Lexer.prototype.clone = function () {
return new Lexer(this.states, this.state);
};
Lexer.prototype.has = function (tokenType) {
for (var s in this.states) {
var groups = this.states[s].groups;
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
if (group.tokenType === tokenType) return true;
if (group.keywords && hasOwnProperty.call(group.keywords, tokenType)) {
return true;
}
}
}
return false;
};
return {
compile: compile,
states: compileStates,
error: Object.freeze({ error: true })
};
});
});
var slice = Array.prototype.slice;
var toArray = function (a) {
return slice.call(a);
};
var tail = function (a) {
return slice.call(a, 1);
};
// fn, [value] -> fn
//-- create a curried function, incorporating any number of
//-- pre-existing arguments (e.g. if you're further currying a function).
var createFn = function (fn, args, totalArity) {
var remainingArity = totalArity - args.length;
switch (remainingArity) {
case 0:
return function () {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 1:
return function (a) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 2:
return function (a, b) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 3:
return function (a, b, c) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 4:
return function (a, b, c, d) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 5:
return function (a, b, c, d, e) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 6:
return function (a, b, c, d, e, f) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 7:
return function (a, b, c, d, e, f, g) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 8:
return function (a, b, c, d, e, f, g, h) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 9:
return function (a, b, c, d, e, f, g, h, i) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
case 10:
return function (a, b, c, d, e, f, g, h, i, j) {
return processInvocation(fn, concatArgs(args, arguments), totalArity);
};
default:
return createEvalFn(fn, args, remainingArity);
}
};
// [value], arguments -> [value]
//-- concat new arguments onto old arguments array
var concatArgs = function (args1, args2) {
return args1.concat(toArray(args2));
};
// fn, [value], int -> fn
//-- create a function of the correct arity by the use of eval,
//-- so that curry can handle functions of any arity
var createEvalFn = function (fn, args, arity) {
var argList = makeArgList(arity);
//-- hack for IE's faulty eval parsing -- http://stackoverflow.com/a/6807726
var fnStr = 'false||' + 'function(' + argList + '){ return processInvocation(fn, concatArgs(args, arguments)); }';
return eval(fnStr);
};
var makeArgList = function (len) {
var a = [];
for (var i = 0; i < len; i += 1) a.push('a' + i.toString());
return a.join(',');
};
var trimArrLength = function (arr, length) {
if (arr.length > length) return arr.slice(0, length);else return arr;
};
// fn, [value] -> value
//-- handle a function being invoked.
//-- if the arg list is long enough, the function will be called
//-- otherwise, a new curried version is created.
var processInvocation = function (fn, argsArr, totalArity) {
argsArr = trimArrLength(argsArr, totalArity);
if (argsArr.length === totalArity) return fn.apply(null, argsArr);
return createFn(fn, argsArr, totalArity);
};
// fn -> fn
//-- curries a function! <3
var curry = function (fn) {
return createFn(fn, [], fn.length);
};
// num, fn -> fn
//-- curries a function to a certain arity! <33
curry.to = curry(function (arity, fn) {
return createFn(fn, [], arity);
});
// num, fn -> fn
//-- adapts a function in the context-first style
//-- to a curried version. <3333
curry.adaptTo = curry(function (num, fn) {
return curry.to(num, function (context) {
var args = tail(arguments).concat(context);
return fn.apply(this, args);
});
});
// fn -> fn
//-- adapts a function in the context-first style to
//-- a curried version. <333
curry.adapt = function (fn) {
return curry.adaptTo(fn.length, fn);
};
var curry_1 = curry;
// Custom Walt Grammar Generator
function id(x) {
return x[0];
}
function grammar() {
const lexer = this.lexer;
const Syntax = this.Syntax;
const {
extendNode,
drop,
nth,
nuller,
nonEmpty,
add,
flatten,
compose
} = this.helpers;
const {
node,
binary,
constant,
identifier,
statement,
unary,
ternary,
subscript,
access,
fun,
declaration,
call,
struct,
result,
string,
char,
typedef,
voidFun,
type,
arrayType,
assignment,
forLoop,
whileLoop,
typeGeneric,
spread,
builtinDecl,
assignmentExpr,
addressOf
} = this.nodes(lexer);
return {
Lexer: lexer,
ParserRules: [{ "name": "_$ebnf$1", "symbols": [] }, { "name": "_$ebnf$1", "symbols": ["_$ebnf$1", "wschar"], "postprocess": function (d) {
return d[0].concat([d[1]]);
} }, { "name": "_", "symbols": ["_$ebnf$1"], "postprocess": function (d) {
return null;
} }, { "name": "__$ebnf$1", "symbols": ["wschar"] }, { "name": "__$ebnf$1", "symbols": ["__$ebnf$1", "wschar"], "postprocess": function (d) {
return d[0].concat([d[1]]);
} }, { "name": "__", "symbols": ["__$ebnf$1"], "postprocess": function (d) {
return null;
} }, { "name": "wschar", "symbols": [/[ \t\n\v\f]/], "postprocess": id }, { "name": "Struct", "symbols": ["TYPE", "__", "Identifier", "_", "EQUALS", "_", "Union", "SEPARATOR"], "postprocess": struct }, { "name": "Struct", "symbols": ["TYPE", "__", "Identifier", "_", "EQUALS", "_", "NativeType", "SEPARATOR"], "postprocess": struct }, { "name": "Union", "symbols": ["StructDefinition"], "postprocess": id }, { "name": "Union", "symbols": ["StructDefinition", "_", "OR", "_", "Union"], "postprocess": node(Syntax.UnionType) }, { "name": "StructDefinition", "symbols": ["ArrayType"], "postprocess": id }, { "name": "StructDefinition", "symbols": ["Identifier"], "postprocess": id }, { "name": "StructDefinition", "symbols": ["LCB", "_", "StructBody", "_", "RCB"], "postprocess": compose(node(Syntax.ObjectLiteral), flatten) }, { "name": "StructBody", "symbols": ["StructNameAndType"], "postprocess": id }, { "name": "StructBody", "symbols": ["StructNameAndType", "_", "COMMA", "_", "StructBody"], "postprocess": flatten }, { "name": "StructNameAndType", "symbols": ["Identifier", "_", "COLON", "_", "Type"], "postprocess": node(Syntax.Pair) }, { "name": "StructNameAndType", "symbols": ["AddressOf", "_", "COLON", "_", "Type"], "postprocess": node(Syntax.Pair) }, { "name": "AddressOf", "symbols": ["AND", "Identifier"], "postprocess": addressOf }, { "name": "TypeDef", "symbols": ["TYPE", "__", "Identifier", "_", "EQUALS", "_", "TypeDefinition", "_", "FATARROW", "_", "Type", "_", "SEPARATOR"], "postprocess": compose(typedef) }, { "name": "TypeDefinition", "symbols": ["LB", "_", "TypeList", "_", "RB"], "postprocess": flatten }, { "name": "TypeDefinition", "symbols": ["LB", "_", "RB"], "postprocess": flatten }, { "name": "TypeList", "symbols": ["Type"], "postprocess": id }, { "name": "TypeList", "symbols": ["Type", "_", "COMMA", "_", "TypeList"], "postprocess": flatten }, { "name": "_Type", "symbols": ["NativeType"], "postprocess": id }, { "name": "_Type", "symbols": ["GenericType"], "postprocess": id }, { "name": "_Type", "symbols": ["Identifier"], "postprocess": id }, { "name": "ArrayType", "symbols": ["_Type", "_", "LSB", "_", "RSB"], "postprocess": arrayType }, { "name": "Type", "symbols": ["_Type"], "postprocess": id }, { "name": "Type", "symbols": ["ArrayType"], "postprocess": id }, { "name": "GenericType", "symbols": ["Identifier", "LT", "_", "StaticObjectLiteral", "_", "GT"], "postprocess": typeGeneric }, { "name": "StaticObjectLiteral", "symbols": ["LCB", "_", "RCB"], "postprocess": compose(node(Syntax.ObjectLiteral)) }, { "name": "StaticObjectLiteral", "symbols": ["LCB", "_", "StaticPropertyList", "_", "RCB"], "postprocess": compose(node(Syntax.ObjectLiteral), flatten) }, { "name": "StaticPropertyValue", "symbols": ["Number"], "postprocess": id }, { "name": "StaticPropertyValue", "symbols": ["Boolean"], "postprocess": id }, { "name": "StaticPropertyValue", "symbols": ["StringLiteral"], "postprocess": id }, { "name": "StaticProperty", "symbols": ["Identifier", "_", "COLON", "_", "StaticPropertyValue"], "postprocess": node(Syntax.Pair) }, { "name": "StaticPropertyList", "symbols": ["StaticProperty"], "postprocess": id }, { "name": "StaticPropertyList", "symbols": ["StaticProperty", "_", "COMMA", "_", "StaticPropertyList"], "postprocess": flatten }, { "name": "ObjectLiteral", "symbols": ["LCB", "_", "RCB"], "postprocess": node(Syntax.ObjectLiteral) }, { "name": "ObjectLiteral", "symbols": ["LCB", "_", "PropertyList", "_", "RCB"], "postprocess": compose(node(Syntax.ObjectLiteral), flatten) }, { "name": "PropertyList", "symbols": ["Property"], "postprocess": id }, { "name": "PropertyList", "symbols": ["Property", "_", "COMMA", "_", "PropertyList"], "postprocess": flatten }, { "name": "Property", "symbols": ["Identifier", "_", "COLON", "_", "Ternary"], "postprocess": node(Syntax.Pair) }, { "name": "Property", "symbols": ["SPREAD", "Identifier"], "postprocess": spread }, { "name": "Property", "symbols": ["Identifier"], "postprocess": id }, { "name": "Import", "symbols": ["IMPORT", "_", "ImportDefinition", "__", "FROM", "__", "StringLiteral", "_", "SEPARATOR"], "postprocess": node(Syntax.Import) }, { "name": "ImportDefinition", "symbols": ["LCB", "_", "ImportAndTypeList", "_", "RCB"], "postprocess": compose(node(Syntax.ObjectLiteral), flatten) }, { "name": "ImportAndTypeList", "symbols": ["ImportName"], "postprocess": id }, { "name": "ImportAndTypeList", "symbols": ["ImportAndType"], "postprocess": id }, { "name": "ImportAndTypeList", "symbols": ["ImportName", "_", "COMMA", "_", "ImportAndTypeList"], "postprocess": flatten }, { "name": "ImportAndTypeList", "symbols": ["ImportAndType", "_", "COMMA", "_", "ImportAndTypeList"], "postprocess": flatten }, { "name": "ImportAndType", "symbols": ["ImportName", "_", "COLON", "_", "Type"], "postprocess": node(Syntax.Pair) }, { "name": "ImportAndType", "symbols": ["ImportName", "_", "AS", "_", "Identifier"], "postprocess": node(Syntax.BinaryExpression, { value: 'as' }) }, { "name": "ImportAndType", "symbols": ["ImportAndType", "_", "AS", "_", "Identifier"], "postprocess": node(Syntax.BinaryExpression, { value: 'as' }) }, { "name": "ImportName", "symbols": ["Identifier"], "postprocess": id }, { "name": "If", "symbols": ["IF", "_", "LB", "_", "Expression", "_", "RB", "_", "BranchBody"], "postprocess": node(Syntax.IfThenElse) }, { "name": "If", "symbols": ["IF", "_", "LB", "_", "Expression", "_", "RB", "_", "BranchBody", "_", "Else"], "postprocess": node(Syntax.IfThenElse) }, { "name": "Else", "symbols": ["ELSE", "_", "BranchBody"], "postprocess": node(Syntax.Else) }, { "name": "BranchBody", "symbols": ["Statement"], "postprocess": id }, { "name": "BranchBody", "symbols": ["Block"], "postprocess": id }, { "name": "For", "symbols": ["FOR", "_", "LB", "_", "ForArg", "_", "SEPARATOR", "_", "Expression", "_", "SEPARATOR", "_", "ForArg", "_", "RB", "_", "BranchBody"], "postprocess": forLoop }, { "name": "ForArg", "symbols": ["_Assignment"], "postprocess": id }, { "name": "ForArg", "symbols": ["Ternary"], "postprocess": id }, { "name": "While", "symbols": ["WHILE", "_", "LB", "_", "Expression", "_", "RB", "_", "BranchBody"], "postprocess": whileLoop }, { "name": "Break", "symbols": ["BREAK", "_", "SEPARATOR"], "postprocess": node(Syntax.Break) }, { "name": "Program", "symbols": ["_"], "postprocess": compose(node('Program', { value: 'ROOT_NODE' }), flatten) }, { "name": "Program", "symbols": ["_", "SourceElementList", "_"], "postprocess": compose(node('Program', { value: 'ROOT_NODE' }), flatten) }, { "name": "SourceElementList", "symbols": ["SourceElement"], "postprocess": flatten }, { "name": "SourceElementList", "symbols": ["SourceElement", "_", "SourceElementList"], "postprocess": compose(drop, flatten, flatten) }, { "name": "SourceElement", "symbols": ["Function"], "postprocess": id }, { "name": "SourceElement", "symbols": ["GlobalDeclaration"], "postprocess": id }, { "name": "SourceElement", "symbols": ["GlobalImmutableDeclaration"], "postprocess": id }, { "name": "SourceElement", "symbols": ["StaticDeclaration"], "postprocess": id }, { "name": "SourceElement", "symbols": ["Struct"], "postprocess": id }, { "name": "SourceElement", "symbols": ["TypeDef"], "postprocess": id }, { "name": "SourceElement", "symbols": ["Export"], "postprocess": id }, { "name": "SourceElement", "symbols": ["Import"], "postprocess": id }, { "name": "Statement", "symbols": ["ExpressionStatement"], "postprocess": id }, { "name": "Statement", "symbols": ["Declaration"], "postprocess": id }, { "name": "Statement", "symbols": ["ImmutableDeclaration"], "postprocess": id }, { "name": "Statement", "symbols": ["Assignment"], "postprocess": id }, { "name": "Statement", "symbols": ["If"], "postprocess": id }, { "name": "Statement", "symbols": ["For"], "postprocess": id }, { "name": "Statement", "symbols": ["While"], "postprocess": id }, { "name": "Statement", "symbols": ["Break"], "postprocess": id }, { "name": "Statement", "symbols": ["Unreachable"], "postprocess": id }, { "name": "Statement", "symbols": ["ReturnStatement"], "postprocess": id }, { "name": "Block", "symbols": ["LCB", "_", "RCB"], "postprocess": node(Syntax.Block) }, { "name": "Block", "symbols": ["LCB", "_", "StatementList", "_", "RCB"], "postprocess": compose(node(Syntax.Block), flatten) }, { "name": "StatementList", "symbols": ["Statement"], "postprocess": drop }, { "name": "StatementList", "symbols": ["Statement", "_", "StatementList"], "postprocess": flatten }, { "name": "Function", "symbols": ["FUNCTION", "__", "Identifier", "_", "FunctionParameters", "_", "Block"], "postprocess": voidFun }, { "name": "Function", "symbols": ["FUNCTION", "__", "Identifier", "_", "FunctionParameters", "_", "FunctionResult", "_", "Block"], "postprocess": fun }, { "name": "FunctionParameters", "symbols": ["LB", "_", "RB"], "postprocess": node(Syntax.FunctionArguments) }, { "name": "FunctionParameters", "symbols": ["LB", "_", "ParameterList", "_", "RB"], "postprocess": compose(node(Syntax.FunctionArguments), flatten, flatten) }, { "name": "ParameterList", "symbols": ["NameAndType"], "postprocess": id }, { "name": "ParameterList", "symbols": ["NameAndType", "_", "COMMA", "_", "ParameterList"], "postprocess": flatten }, { "name": "NameAndType", "symbols": ["Identifier", "_", "COLON", "_", "DeclType"], "postprocess": node(Syntax.Pair) }, { "name": "DeclType", "symbols": ["Type"], "postprocess": compose(extendNode({ Type: Syntax.DeclType }), nth(0)) }, { "name": "FunctionResult", "symbols": ["COLON", "_", "Type"], "postprocess": compose(result, drop) }, { "name": "GlobalDeclaration", "symbols": ["LET", "_", "NameAndType", "_", "SEPARATOR"], "postprocess": declaration(Syntax.Declaration) }, { "name": "GlobalDeclaration", "symbols": ["LET", "_", "NameAndType", "_", "EQUALS", "_", "Atom", "_", "SEPARATOR"], "postprocess": declaration(Syntax.Declaration) }, { "name": "GlobalImmutableDeclaration", "symbols": ["CONST", "_", "Identifier", "_", "COLON", "_", "GenericType", "_", "SEPARATOR"], "postprocess": builtinDecl }, { "name": "GlobalImmutableDeclaration", "symbols": ["CONST", "_", "NameAndType", "_", "EQUALS", "_", "ObjectLiteral", "_", "SEPARATOR"], "postprocess": declaration(Syntax.ImmutableDeclaration) }, { "name": "GlobalImmutableDeclaration", "symbols": ["CONST", "_", "NameAndType", "_", "EQUALS", "_", "Atom", "_", "SEPARATOR"], "postprocess": declaration(Syntax.ImmutableDeclaration) }, { "name": "Declaration", "symbols": ["LET", "_", "NameAndType", "_", "EQUALS", "_", "Expression", "_", "SEPARATOR"], "postprocess": declaration(Syntax.Declaration) }, { "name": "Declaration", "symbols": ["LET", "_", "NameAndType", "_", "SEPARATOR"], "postprocess": declaration(Syntax.Declaration) }, { "name": "ImmutableDeclaration", "symbols": ["CONST", "_", "NameAndType", "_", "EQUALS", "_", "Expression", "_", "SEPARATOR"], "postprocess": declaration(Syntax.ImmutableDeclaration) }, { "name": "ImmutableDeclaration", "symbols": ["CONST", "_", "NameAndType", "_", "EQUALS", "_", "ObjectLiteral", "_", "SEPARATOR"], "postprocess": declaration(Syntax.ImmutableDeclaration) }, { "name": "ImmutableDeclaration", "symbols": ["CONST", "_", "Identifier", "_", "COLON", "_", "GenericType", "_", "SEPARATOR"], "postprocess": builtinDecl }, { "name": "StaticNameAndType", "symbols": ["Identifier", "_", "COLON", "_", "ArrayType"], "postprocess": node(Syntax.Pair) }, { "name": "StaticDeclaration", "symbols": ["CONST", "_", "StaticNameAndType", "_", "EQUALS", "_", "LSB", "_", "RSB", "_", "SEPARATOR"], "postprocess": declaration(Syntax.StaticDeclaration) }, { "name": "StaticDeclaration", "symbols": ["CONST", "_", "StaticNameAndType", "_", "EQUALS", "_", "LSB", "_", "StaticValueList", "_", "RSB", "_", "SEPARATOR"], "postprocess": compose(declaration(Syntax.StaticDeclaration), flatten) }, { "name": "StaticValueList", "symbols": ["Atom"], "postprocess": id }, { "name": "StaticValueList", "symbols": ["Atom", "_", "COMMA", "_", "StaticValueList"], "postprocess": flatten }, { "name": "Unreachable", "symbols": ["THROW", "_", "SEPARATOR"], "postprocess": node(Syntax.Unreachable) }, { "name": "Unreachable", "symbols": ["THROW", "_", "Expression", "_", "SEPARATOR"], "postprocess": node(Syntax.Unreachable) }, { "name": "Pair", "symbols": ["Identifier", "_", "COLON", "_", "Identifier"], "postprocess": node(Syntax.Pair) }, { "name": "Export", "symbols": ["EXPORT", "__", "ImmutableDeclaration"], "postprocess": node(Syntax.Export, { value: 'export' }) }, { "name": "Export", "symbols": ["EXPORT", "__", "Function"], "postprocess": node(Syntax.Export, { value: 'export' }) }, { "name": "Export", "symbols": ["EXPORT", "__", "TypeDef"], "postprocess": node(Syntax.Export, { value: 'export' }) }, { "name": "Export", "symbols": ["EXPORT", "__", "Struct"], "postprocess": node(Syntax.Export, { value: 'export' }) }, { "name": "ReturnStatement", "symbols": ["RETURN", "__", "Expression", "_", "SEPARATOR"], "postprocess": node(Syntax.ReturnStatement) }, { "name": "ReturnStatement$subexpression$1", "symbols": [{ "literal": ";" }], "postprocess": nuller }, { "name": "ReturnStatement", "symbols": ["RETURN", "ReturnStatement$subexpression$1"], "postprocess": node(Syntax.ReturnStatement) }, { "name": "Assignment", "symbols": ["_Assignment", "_", "SEPARATOR"], "postprocess": id }, { "name": "_Assignment", "symbols": ["Subscript", "_", "EQUALS", "_", "Expression"], "postprocess": d => assignment(d, '=') }, { "name": "_Assignment", "symbols": ["Subscript", "_", "PLSEQUALS", "_", "Expression"], "postprocess": d => assignment(d, '+=') }, { "name": "_Assignment", "symbols": ["Subscript", "_", "MINEQUALS", "_", "Expression"], "postprocess": d => assignment(d, '-=') }, { "name": "_Assignment", "symbols": ["Subscript", "_", "EQUALS", "_", "ObjectLiteral"], "postprocess": d => assignment(d, '=') }, { "name": "ExpressionStatement", "symbols": ["Call", "_", "SEPARATOR"], "postprocess": id }, { "name": "Expression", "symbols": ["AssignmentExpression"], "postprocess": id }, { "name": "AssignmentExpression", "symbols": ["Identifier", "_", "EQUALS", "_", "Ternary"], "postprocess": d => assignmentExpr(d, '=') }, { "name": "AssignmentExpression", "symbols": ["Identifier", "_", "PLSEQUALS", "_", "Ternary"], "postprocess": d => assignmentExpr(d, '+=') }, { "name": "AssignmentExpression", "symbols": ["Identifier", "_", "MINEQUALS", "_", "Ternary"], "postprocess": d => assignmentExpr(d, '-=') }, { "name": "AssignmentExpression", "symbols": ["Ternary"], "postprocess": id }, { "name": "Ternary", "symbols": ["Ternary", "_", "QUESTION", "_", "TernaryPair"], "postprocess": ternary }, { "name": "Ternary", "symbols": ["Binary"], "postprocess": id }, { "name": "TernaryPair", "symbols": ["Expression", "_", "COLON", "_", "Expression"], "postprocess": node(Syntax.Pair) }, { "name": "Binary", "symbols": ["Logical"], "postprocess": id }, { "name": "Logical", "symbols": ["Logical", "_", { "literal": "||" }, "_", "Bitwise"], "postprocess": binary }, { "name": "Logical", "symbols": ["Logical", "_", { "literal": "&&" }, "_", "Bitwise"], "postprocess": binary }, { "name": "Logical", "symbols": ["Bitwise"], "postprocess": id }, { "name": "Bitwise", "symbols": ["Bitwise", "_", { "literal": "|" }, "_", "Sum"], "postprocess": binary }, { "name": "Bitwise", "symbols": ["Bitwise", "_", { "literal": "^" }, "_", "Sum"], "postprocess": binary }, { "name": "Bitwise", "symbols": ["Bitwise", "_", { "literal": "&" }, "_", "Sum"], "postprocess": binary }, { "name": "Bitwise", "symbols": ["Equality"], "postprocess": id }, { "name": "Equality", "symbols": ["Equality", "_", { "literal": "==" }, "_", "Comparison"], "postprocess": binary }, { "name": "Equality", "symbols": ["Equality", "_", { "literal": "!=" }, "_", "Comparison"], "postprocess": binary }, { "name": "Equality", "symbols": ["Comparison"], "postprocess": id }, { "name": "Comparison", "symbols": ["Comparison", "_", { "literal": "<" }, "_", "Shift"], "postprocess": binary }, { "name": "Comparison", "symbols": ["Comparison", "_", { "literal": ">" }, "_", "Shift"], "postprocess": binary }, { "name": "Comparison", "symbols": ["Comparison", "_", { "literal": "<=" }, "_", "Shift"], "postprocess": binary }, { "name": "Comparison", "symbols": ["Comparison", "_", { "literal": ">=" }, "_", "Shift"], "postprocess": binary }, { "name": "Comparison", "symbols": ["Shift"], "postprocess": id }, { "name": "Shift", "symbols": ["Shift", "_", { "literal": ">>" }, "_", "Sum"], "postprocess": binary }, { "name": "Shift", "symbols": ["Shift", "_", { "literal": "<<" }, "_", "Sum"], "postprocess": binary }, { "name": "Shift", "symbols": ["Shift", "_", { "literal": ">>>" }, "_", "Sum"], "postprocess": binary }, { "name": "Shift", "symbols": ["Sum"], "postprocess": id }, { "name": "Sum", "symbols": ["Sum", "_", { "literal": "+" }, "_", "Product"], "postprocess": binary }, { "name": "Sum", "symbols": ["Sum", "_", { "literal": "-" }, "_", "Product"], "postprocess": binary }, { "name": "Sum", "symbols": ["Product"], "postprocess": id }, { "name": "Product", "symbols": ["Product", "_", { "literal": "*" }, "_", "Typecast"], "postprocess": binary }, { "name": "Product", "symbols": ["Product", "_", { "literal": "/" }, "_", "Typecast"], "postprocess": binary }, { "name": "Product", "symbols": ["Product", "_", { "literal": "%" }, "_", "Typecast"], "postprocess": binary }, { "name": "Product", "symbols": ["Typecast"], "postprocess": id }, { "name": "Typecast", "symbols": ["Expression", "_", "COLON", "_", "DeclType"], "postprocess": node(Syntax.Pair) }, { "name": "Typecast", "symbols": ["Expression", "_", "AS", "_", "DeclType"], "postprocess": node(Syntax.Pair) }, { "name": "Typecast", "symbols": ["Unary"], "postprocess": id }, { "name": "Unary", "symbols": [{ "literal": "!" }, "Call"], "postprocess": unary }, { "name": "Unary", "symbols": [{ "literal": "~" }, "Call"], "postprocess": unary }, { "name": "Unary", "symbols": [{ "literal": "-" }, "Call"], "postprocess": unary }, { "name": "Unary", "symbols": [{ "literal": "+" }, "Call"], "postprocess": unary }, { "name": "Unary", "symbols": [{ "literal": "++" }, "Call"], "postprocess": unary }, { "name": "Unary", "symbols": [{ "literal": "--" }, "Call"], "postprocess": unary }, { "name": "Unary", "symbo