You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					1756 lines
				
				48 KiB
			
		
		
			
		
	
	
					1756 lines
				
				48 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import { codeFrameFromSource } from "@webassemblyjs/helper-code-frame";
							 | 
						||
| 
								 | 
							
								import * as t from "@webassemblyjs/ast";
							 | 
						||
| 
								 | 
							
								import { parse32I } from "./number-literals";
							 | 
						||
| 
								 | 
							
								import { parseString } from "./string-literals";
							 | 
						||
| 
								 | 
							
								import { tokens, keywords } from "./tokenizer";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function hasPlugin(name) {
							 | 
						||
| 
								 | 
							
								  if (name !== "wast") throw new Error("unknow plugin");
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function isKeyword(token, id) {
							 | 
						||
| 
								 | 
							
								  return token.type === tokens.keyword && token.value === id;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function tokenToString(token) {
							 | 
						||
| 
								 | 
							
								  if (token.type === "keyword") {
							 | 
						||
| 
								 | 
							
								    return "keyword (".concat(token.value, ")");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return token.type;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function identifierFromToken(token) {
							 | 
						||
| 
								 | 
							
								  var _token$loc = token.loc,
							 | 
						||
| 
								 | 
							
								      end = _token$loc.end,
							 | 
						||
| 
								 | 
							
								      start = _token$loc.start;
							 | 
						||
| 
								 | 
							
								  return t.withLoc(t.identifier(token.value), end, start);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export function parse(tokensList, source) {
							 | 
						||
| 
								 | 
							
								  var current = 0;
							 | 
						||
| 
								 | 
							
								  var getUniqueName = t.getUniqueNameGenerator();
							 | 
						||
| 
								 | 
							
								  var state = {
							 | 
						||
| 
								 | 
							
								    registredExportedElements: []
							 | 
						||
| 
								 | 
							
								  }; // But this time we're going to use recursion instead of a `while` loop. So we
							 | 
						||
| 
								 | 
							
								  // define a `walk` function.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function walk() {
							 | 
						||
| 
								 | 
							
								    var token = tokensList[current];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function eatToken() {
							 | 
						||
| 
								 | 
							
								      token = tokensList[++current];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function getEndLoc() {
							 | 
						||
| 
								 | 
							
								      var currentToken = token;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (typeof currentToken === "undefined") {
							 | 
						||
| 
								 | 
							
								        var lastToken = tokensList[tokensList.length - 1];
							 | 
						||
| 
								 | 
							
								        currentToken = lastToken;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return currentToken.loc.end;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function getStartLoc() {
							 | 
						||
| 
								 | 
							
								      return token.loc.start;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function eatTokenOfType(type) {
							 | 
						||
| 
								 | 
							
								      if (token.type !== type) {
							 | 
						||
| 
								 | 
							
								        throw new Error("\n" + codeFrameFromSource(source, token.loc) + "Assertion error: expected token of type " + type + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      eatToken();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseExportIndex(token) {
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        var index = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        return index;
							 | 
						||
| 
								 | 
							
								      } else if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								        var _index = t.numberLiteralFromRaw(token.value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        return _index;
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        throw function () {
							 | 
						||
| 
								 | 
							
								          return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "unknown export index" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								        }();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function lookaheadAndCheck() {
							 | 
						||
| 
								 | 
							
								      var len = arguments.length;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      for (var i = 0; i < len; i++) {
							 | 
						||
| 
								 | 
							
								        var tokenAhead = tokensList[current + i];
							 | 
						||
| 
								 | 
							
								        var expectedToken = i < 0 || arguments.length <= i ? undefined : arguments[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (tokenAhead.type === "keyword") {
							 | 
						||
| 
								 | 
							
								          if (isKeyword(tokenAhead, expectedToken) === false) {
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        } else if (expectedToken !== tokenAhead.type) {
							 | 
						||
| 
								 | 
							
								          return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return true;
							 | 
						||
| 
								 | 
							
								    } // TODO(sven): there is probably a better way to do this
							 | 
						||
| 
								 | 
							
								    // can refactor it if it get out of hands
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function maybeIgnoreComment() {
							 | 
						||
| 
								 | 
							
								      if (typeof token === "undefined") {
							 | 
						||
| 
								 | 
							
								        // Ignore
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type === tokens.comment) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (typeof token === "undefined") {
							 | 
						||
| 
								 | 
							
								          // Hit the end
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a memory instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * memory:  ( memory <name>? <memory_sig> )
							 | 
						||
| 
								 | 
							
								     *          ( memory <name>? ( export <string> ) <...> )
							 | 
						||
| 
								 | 
							
								     *          ( memory <name>? ( import <string> <string> ) <memory_sig> )
							 | 
						||
| 
								 | 
							
								     *          ( memory <name>? ( export <string> )* ( data <string>* )
							 | 
						||
| 
								 | 
							
								     * memory_sig: <nat> <nat>?
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseMemory() {
							 | 
						||
| 
								 | 
							
								      var id = t.identifier(getUniqueName("memory"));
							 | 
						||
| 
								 | 
							
								      var limits = t.limit(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.string || token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        id = t.identifier(token.value);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        id = t.withRaw(id, ""); // preserve anonymous
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Maybe data
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (lookaheadAndCheck(tokens.openParen, keywords.data)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken(); // data
							 | 
						||
| 
								 | 
							
								        // TODO(sven): do something with the data collected here
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var stringInitializer = token.value;
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.string); // Update limits accordingly
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        limits = t.limit(stringInitializer.length);
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Maybe export
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (lookaheadAndCheck(tokens.openParen, keywords.export)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken(); // export
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type !== tokens.string) {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Expected string in export" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _name = token.value;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        state.registredExportedElements.push({
							 | 
						||
| 
								 | 
							
								          exportType: "Memory",
							 | 
						||
| 
								 | 
							
								          name: _name,
							 | 
						||
| 
								 | 
							
								          id: id
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Memory signature
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								        limits = t.limit(parse32I(token.value));
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								          limits.max = parse32I(token.value);
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.memory(limits, id);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a data section
							 | 
						||
| 
								 | 
							
								     * https://webassembly.github.io/spec/core/text/modules.html#data-segments
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * data:  ( data <index>? <offset> <string> )
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseData() {
							 | 
						||
| 
								 | 
							
								      // optional memory index
							 | 
						||
| 
								 | 
							
								      var memidx = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								        memidx = token.value;
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.number); // .
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      eatTokenOfType(tokens.openParen);
							 | 
						||
| 
								 | 
							
								      var offset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.valtype); // i32
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.dot); // .
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.value !== "const") {
							 | 
						||
| 
								 | 
							
								          throw new Error("constant expression required");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.name); // const
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var numberLiteral = t.numberLiteralFromRaw(token.value, "i32");
							 | 
						||
| 
								 | 
							
								        offset = t.objectInstruction("const", "i32", [numberLiteral]);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.name); // get_global
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _numberLiteral = t.numberLiteralFromRaw(token.value, "i32");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        offset = t.instruction("get_global", [_numberLiteral]);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var byteArray = parseString(token.value);
							 | 
						||
| 
								 | 
							
								      eatToken(); // "string"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.data(t.memIndexLiteral(memidx), offset, t.byteArray(byteArray));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a table instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * table:   ( table <name>? <table_type> )
							 | 
						||
| 
								 | 
							
								     *          ( table <name>? ( export <string> ) <...> )
							 | 
						||
| 
								 | 
							
								     *          ( table <name>? ( import <string> <string> ) <table_type> )
							 | 
						||
| 
								 | 
							
								     *          ( table <name>? ( export <string> )* <elem_type> ( elem <var>* ) )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * table_type:  <nat> <nat>? <elem_type>
							 | 
						||
| 
								 | 
							
								     * elem_type: anyfunc
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * elem:    ( elem <var>? (offset <instr>* ) <var>* )
							 | 
						||
| 
								 | 
							
								     *          ( elem <var>? <expr> <var>* )
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseTable() {
							 | 
						||
| 
								 | 
							
								      var name = t.identifier(getUniqueName("table"));
							 | 
						||
| 
								 | 
							
								      var limit = t.limit(0);
							 | 
						||
| 
								 | 
							
								      var elemIndices = [];
							 | 
						||
| 
								 | 
							
								      var elemType = "anyfunc";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.string || token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        name = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        name = t.withRaw(name, ""); // preserve anonymous
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Maybe export
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(tokens.openParen, keywords.elem)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // elem
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          while (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								            elemIndices.push(t.identifier(token.value));
							 | 
						||
| 
								 | 
							
								            eatToken();
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(tokens.openParen, keywords.export)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // export
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (token.type !== tokens.string) {
							 | 
						||
| 
								 | 
							
								            throw function () {
							 | 
						||
| 
								 | 
							
								              return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Expected string in export" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								            }();
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          var exportName = token.value;
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          state.registredExportedElements.push({
							 | 
						||
| 
								 | 
							
								            exportType: "Table",
							 | 
						||
| 
								 | 
							
								            name: exportName,
							 | 
						||
| 
								 | 
							
								            id: name
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        } else if (isKeyword(token, keywords.anyfunc)) {
							 | 
						||
| 
								 | 
							
								          // It's the default value, we can ignore it
							 | 
						||
| 
								 | 
							
								          eatToken(); // anyfunc
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								          /**
							 | 
						||
| 
								 | 
							
								           * Table type
							 | 
						||
| 
								 | 
							
								           */
							 | 
						||
| 
								 | 
							
								          var min = parseInt(token.value);
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								            var max = parseInt(token.value);
							 | 
						||
| 
								 | 
							
								            eatToken();
							 | 
						||
| 
								 | 
							
								            limit = t.limit(min, max);
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								            limit = t.limit(min);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (elemIndices.length > 0) {
							 | 
						||
| 
								 | 
							
								        return t.table(elemType, limit, name, elemIndices);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        return t.table(elemType, limit, name);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses an import statement
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * import:  ( import <string> <string> <imkind> )
							 | 
						||
| 
								 | 
							
								     * imkind:  ( func <name>? <func_sig> )
							 | 
						||
| 
								 | 
							
								     *          ( global <name>? <global_sig> )
							 | 
						||
| 
								 | 
							
								     *          ( table <name>? <table_sig> )
							 | 
						||
| 
								 | 
							
								     *          ( memory <name>? <memory_sig> )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * global_sig: <type> | ( mut <type> )
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseImport() {
							 | 
						||
| 
								 | 
							
								      if (token.type !== tokens.string) {
							 | 
						||
| 
								 | 
							
								        throw new Error("Expected a string, " + token.type + " given.");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var moduleName = token.value;
							 | 
						||
| 
								 | 
							
								      eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type !== tokens.string) {
							 | 
						||
| 
								 | 
							
								        throw new Error("Expected a string, " + token.type + " given.");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var name = token.value;
							 | 
						||
| 
								 | 
							
								      eatToken();
							 | 
						||
| 
								 | 
							
								      eatTokenOfType(tokens.openParen);
							 | 
						||
| 
								 | 
							
								      var descr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.func)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var fnParams = [];
							 | 
						||
| 
								 | 
							
								        var fnResult = [];
							 | 
						||
| 
								 | 
							
								        var typeRef;
							 | 
						||
| 
								 | 
							
								        var fnName = t.identifier(getUniqueName("func"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								          fnName = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (lookaheadAndCheck(keywords.type) === true) {
							 | 
						||
| 
								 | 
							
								            eatToken();
							 | 
						||
| 
								 | 
							
								            typeRef = parseTypeReference();
							 | 
						||
| 
								 | 
							
								          } else if (lookaheadAndCheck(keywords.param) === true) {
							 | 
						||
| 
								 | 
							
								            eatToken();
							 | 
						||
| 
								 | 
							
								            fnParams.push.apply(fnParams, _toConsumableArray(parseFuncParam()));
							 | 
						||
| 
								 | 
							
								          } else if (lookaheadAndCheck(keywords.result) === true) {
							 | 
						||
| 
								 | 
							
								            eatToken();
							 | 
						||
| 
								 | 
							
								            fnResult.push.apply(fnResult, _toConsumableArray(parseFuncResult()));
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								            throw function () {
							 | 
						||
| 
								 | 
							
								              return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in import of type" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								            }();
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (typeof fnName === "undefined") {
							 | 
						||
| 
								 | 
							
								          throw new Error("Imported function must have a name");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        descr = t.funcImportDescr(fnName, typeRef !== undefined ? typeRef : t.signature(fnParams, fnResult));
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.global)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.keyword); // mut keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          var valtype = token.value;
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          descr = t.globalType(valtype, "var");
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          var _valtype = token.value;
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.valtype);
							 | 
						||
| 
								 | 
							
								          descr = t.globalType(_valtype, "const");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.memory) === true) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // Keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        descr = parseMemory();
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.table) === true) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // Keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        descr = parseTable();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        throw new Error("Unsupported import type: " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      return t.moduleImport(moduleName, name, descr);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a block instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * expr: ( block <name>? <block_sig> <instr>* )
							 | 
						||
| 
								 | 
							
								     * instr: block <name>? <block_sig> <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     * block_sig : ( result <type>* )*
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseBlock() {
							 | 
						||
| 
								 | 
							
								      var label = t.identifier(getUniqueName("block"));
							 | 
						||
| 
								 | 
							
								      var blockResult = null;
							 | 
						||
| 
								 | 
							
								      var instr = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        label = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        label = t.withRaw(label, ""); // preserve anonymous
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(keywords.result) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          blockResult = token.value;
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(tokens.name) === true || lookaheadAndCheck(tokens.valtype) === true || token.type === "keyword" // is any keyword
							 | 
						||
| 
								 | 
							
								        ) {
							 | 
						||
| 
								 | 
							
								            // Instruction
							 | 
						||
| 
								 | 
							
								            instr.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in block body of type" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.blockInstruction(label, instr, blockResult);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a if instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * expr:
							 | 
						||
| 
								 | 
							
								     * ( if <name>? <block_sig> ( then <instr>* ) ( else <instr>* )? )
							 | 
						||
| 
								 | 
							
								     * ( if <name>? <block_sig> <expr>+ ( then <instr>* ) ( else <instr>* )? )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * instr:
							 | 
						||
| 
								 | 
							
								     * if <name>? <block_sig> <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     * if <name>? <block_sig> <instr>* else <name>? <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * block_sig : ( result <type>* )*
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseIf() {
							 | 
						||
| 
								 | 
							
								      var blockResult = null;
							 | 
						||
| 
								 | 
							
								      var label = t.identifier(getUniqueName("if"));
							 | 
						||
| 
								 | 
							
								      var testInstrs = [];
							 | 
						||
| 
								 | 
							
								      var consequent = [];
							 | 
						||
| 
								 | 
							
								      var alternate = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        label = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        label = t.withRaw(label, ""); // preserve anonymous
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Block signature
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (isKeyword(token, keywords.result) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          blockResult = token.value;
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.valtype);
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Then
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (isKeyword(token, keywords.then) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // then
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								            eatToken(); // Instruction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (lookaheadAndCheck(tokens.name) === true || lookaheadAndCheck(tokens.valtype) === true || token.type === "keyword" // is any keyword
							 | 
						||
| 
								 | 
							
								            ) {
							 | 
						||
| 
								 | 
							
								                consequent.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								              } else {
							 | 
						||
| 
								 | 
							
								              throw function () {
							 | 
						||
| 
								 | 
							
								                return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in consequent body of type" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								              }();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Alternate
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (isKeyword(token, keywords.else)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								            eatToken(); // Instruction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (lookaheadAndCheck(tokens.name) === true || lookaheadAndCheck(tokens.valtype) === true || token.type === "keyword" // is any keyword
							 | 
						||
| 
								 | 
							
								            ) {
							 | 
						||
| 
								 | 
							
								                alternate.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								              } else {
							 | 
						||
| 
								 | 
							
								              throw function () {
							 | 
						||
| 
								 | 
							
								                return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in alternate body of type" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								              }();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Test instruction
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(tokens.name) === true || lookaheadAndCheck(tokens.valtype) === true || token.type === "keyword" // is any keyword
							 | 
						||
| 
								 | 
							
								        ) {
							 | 
						||
| 
								 | 
							
								            testInstrs.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								            eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw function () {
							 | 
						||
| 
								 | 
							
								          return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in if body" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								        }();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.ifInstruction(label, testInstrs, blockResult, consequent, alternate);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a loop instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAT:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * blockinstr :: 'loop' I:label rt:resulttype (in:instr*) 'end' id?
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * instr     :: loop <name>? <block_sig> <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     * expr      :: ( loop <name>? <block_sig> <instr>* )
							 | 
						||
| 
								 | 
							
								     * block_sig :: ( result <type>* )*
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseLoop() {
							 | 
						||
| 
								 | 
							
								      var label = t.identifier(getUniqueName("loop"));
							 | 
						||
| 
								 | 
							
								      var blockResult;
							 | 
						||
| 
								 | 
							
								      var instr = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        label = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        label = t.withRaw(label, ""); // preserve anonymous
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(keywords.result) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          blockResult = token.value;
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(tokens.name) === true || lookaheadAndCheck(tokens.valtype) === true || token.type === "keyword" // is any keyword
							 | 
						||
| 
								 | 
							
								        ) {
							 | 
						||
| 
								 | 
							
								            // Instruction
							 | 
						||
| 
								 | 
							
								            instr.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in loop body" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.loopInstruction(label, blockResult, instr);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseCallIndirect() {
							 | 
						||
| 
								 | 
							
								      var typeRef;
							 | 
						||
| 
								 | 
							
								      var params = [];
							 | 
						||
| 
								 | 
							
								      var results = [];
							 | 
						||
| 
								 | 
							
								      var instrs = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(tokens.openParen, keywords.type)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // type
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          typeRef = parseTypeReference();
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(tokens.openParen, keywords.param)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // param
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          /**
							 | 
						||
| 
								 | 
							
								           * Params can be empty:
							 | 
						||
| 
								 | 
							
								           * (params)`
							 | 
						||
| 
								 | 
							
								           */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								            params.push.apply(params, _toConsumableArray(parseFuncParam()));
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(tokens.openParen, keywords.result)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          /**
							 | 
						||
| 
								 | 
							
								           * Results can be empty:
							 | 
						||
| 
								 | 
							
								           * (result)`
							 | 
						||
| 
								 | 
							
								           */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								            results.push.apply(results, _toConsumableArray(parseFuncResult()));
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.openParen);
							 | 
						||
| 
								 | 
							
								          instrs.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.callIndirectInstruction(typeRef !== undefined ? typeRef : t.signature(params, results), instrs);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses an export instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAT:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * export:  ( export <string> <exkind> )
							 | 
						||
| 
								 | 
							
								     * exkind:  ( func <var> )
							 | 
						||
| 
								 | 
							
								     *          ( global <var> )
							 | 
						||
| 
								 | 
							
								     *          ( table <var> )
							 | 
						||
| 
								 | 
							
								     *          ( memory <var> )
							 | 
						||
| 
								 | 
							
								     * var:    <nat> | <name>
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseExport() {
							 | 
						||
| 
								 | 
							
								      if (token.type !== tokens.string) {
							 | 
						||
| 
								 | 
							
								        throw new Error("Expected string after export, got: " + token.type);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var name = token.value;
							 | 
						||
| 
								 | 
							
								      eatToken();
							 | 
						||
| 
								 | 
							
								      var moduleExportDescr = parseModuleExportDescr();
							 | 
						||
| 
								 | 
							
								      return t.moduleExport(name, moduleExportDescr);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseModuleExportDescr() {
							 | 
						||
| 
								 | 
							
								      var startLoc = getStartLoc();
							 | 
						||
| 
								 | 
							
								      var type = "";
							 | 
						||
| 
								 | 
							
								      var index;
							 | 
						||
| 
								 | 
							
								      eatTokenOfType(tokens.openParen);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								        if (isKeyword(token, keywords.func)) {
							 | 
						||
| 
								 | 
							
								          type = "Func";
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          index = parseExportIndex(token);
							 | 
						||
| 
								 | 
							
								        } else if (isKeyword(token, keywords.table)) {
							 | 
						||
| 
								 | 
							
								          type = "Table";
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          index = parseExportIndex(token);
							 | 
						||
| 
								 | 
							
								        } else if (isKeyword(token, keywords.global)) {
							 | 
						||
| 
								 | 
							
								          type = "Global";
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          index = parseExportIndex(token);
							 | 
						||
| 
								 | 
							
								        } else if (isKeyword(token, keywords.memory)) {
							 | 
						||
| 
								 | 
							
								          type = "Memory";
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          index = parseExportIndex(token);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (type === "") {
							 | 
						||
| 
								 | 
							
								        throw new Error("Unknown export type");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (index === undefined) {
							 | 
						||
| 
								 | 
							
								        throw new Error("Exported function must have a name");
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var node = t.moduleExportDescr(type, index);
							 | 
						||
| 
								 | 
							
								      var endLoc = getEndLoc();
							 | 
						||
| 
								 | 
							
								      eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      return t.withLoc(node, endLoc, startLoc);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseModule() {
							 | 
						||
| 
								 | 
							
								      var name = null;
							 | 
						||
| 
								 | 
							
								      var isBinary = false;
							 | 
						||
| 
								 | 
							
								      var isQuote = false;
							 | 
						||
| 
								 | 
							
								      var moduleFields = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        name = token.value;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (hasPlugin("wast") && token.type === tokens.name && token.value === "binary") {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        isBinary = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (hasPlugin("wast") && token.type === tokens.name && token.value === "quote") {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        isQuote = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isBinary === true) {
							 | 
						||
| 
								 | 
							
								        var blob = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (token.type === tokens.string) {
							 | 
						||
| 
								 | 
							
								          blob.push(token.value);
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.binaryModule(name, blob);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isQuote === true) {
							 | 
						||
| 
								 | 
							
								        var string = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (token.type === tokens.string) {
							 | 
						||
| 
								 | 
							
								          string.push(token.value);
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.quoteModule(name, string);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								        moduleFields.push(walk());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (state.registredExportedElements.length > 0) {
							 | 
						||
| 
								 | 
							
								          state.registredExportedElements.forEach(function (decl) {
							 | 
						||
| 
								 | 
							
								            moduleFields.push(t.moduleExport(decl.name, t.moduleExportDescr(decl.exportType, decl.id)));
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								          state.registredExportedElements = [];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        token = tokensList[current];
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      return t.module(name, moduleFields);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses the arguments of an instruction
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseFuncInstrArguments(signature) {
							 | 
						||
| 
								 | 
							
								      var args = [];
							 | 
						||
| 
								 | 
							
								      var namedArgs = {};
							 | 
						||
| 
								 | 
							
								      var signaturePtr = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type === tokens.name || isKeyword(token, keywords.offset)) {
							 | 
						||
| 
								 | 
							
								        var key = token.value;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.equal);
							 | 
						||
| 
								 | 
							
								        var value = void 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								          value = t.numberLiteralFromRaw(token.value);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          throw new Error("Unexpected type for argument: " + token.type);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        namedArgs[key] = value;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } // $FlowIgnore
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var signatureLength = signature.vector ? Infinity : signature.length;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type !== tokens.closeParen && ( // $FlowIgnore
							 | 
						||
| 
								 | 
							
								      token.type === tokens.openParen || signaturePtr < signatureLength)) {
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								          args.push(t.identifier(token.value));
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								          // Handle locals
							 | 
						||
| 
								 | 
							
								          args.push(t.valtypeLiteral(token.value));
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.string) {
							 | 
						||
| 
								 | 
							
								          args.push(t.stringLiteral(token.value));
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								          args.push( // TODO(sven): refactor the type signature handling
							 | 
						||
| 
								 | 
							
								          // https://github.com/xtuc/webassemblyjs/pull/129 is a good start
							 | 
						||
| 
								 | 
							
								          t.numberLiteralFromRaw(token.value, // $FlowIgnore
							 | 
						||
| 
								 | 
							
								          signature[signaturePtr] || "f64")); // $FlowIgnore
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (!signature.vector) {
							 | 
						||
| 
								 | 
							
								            ++signaturePtr;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								          /**
							 | 
						||
| 
								 | 
							
								           * Maybe some nested instructions
							 | 
						||
| 
								 | 
							
								           */
							 | 
						||
| 
								 | 
							
								          eatToken(); // Instruction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (lookaheadAndCheck(tokens.name) === true || lookaheadAndCheck(tokens.valtype) === true || token.type === "keyword" // is any keyword
							 | 
						||
| 
								 | 
							
								          ) {
							 | 
						||
| 
								 | 
							
								              // $FlowIgnore
							 | 
						||
| 
								 | 
							
								              args.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								            throw function () {
							 | 
						||
| 
								 | 
							
								              return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in nested instruction" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								            }();
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (token.type === tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								            eatToken();
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in instruction argument" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return {
							 | 
						||
| 
								 | 
							
								        args: args,
							 | 
						||
| 
								 | 
							
								        namedArgs: namedArgs
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses an instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAT:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * instr      :: plaininst
							 | 
						||
| 
								 | 
							
								     *               blockinstr
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * blockinstr :: 'block' I:label rt:resulttype (in:instr*) 'end' id?
							 | 
						||
| 
								 | 
							
								     *               'loop' I:label rt:resulttype (in:instr*) 'end' id?
							 | 
						||
| 
								 | 
							
								     *               'if' I:label rt:resulttype (in:instr*) 'else' id? (in2:intr*) 'end' id?
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * plaininst  :: 'unreachable'
							 | 
						||
| 
								 | 
							
								     *               'nop'
							 | 
						||
| 
								 | 
							
								     *               'br' l:labelidx
							 | 
						||
| 
								 | 
							
								     *               'br_if' l:labelidx
							 | 
						||
| 
								 | 
							
								     *               'br_table' l*:vec(labelidx) ln:labelidx
							 | 
						||
| 
								 | 
							
								     *               'return'
							 | 
						||
| 
								 | 
							
								     *               'call' x:funcidx
							 | 
						||
| 
								 | 
							
								     *               'call_indirect' x, I:typeuse
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * instr:
							 | 
						||
| 
								 | 
							
								     *   <expr>
							 | 
						||
| 
								 | 
							
								     *   <op>
							 | 
						||
| 
								 | 
							
								     *   block <name>? <block_sig> <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     *   loop <name>? <block_sig> <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     *   if <name>? <block_sig> <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     *   if <name>? <block_sig> <instr>* else <name>? <instr>* end <name>?
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * expr:
							 | 
						||
| 
								 | 
							
								     *   ( <op> )
							 | 
						||
| 
								 | 
							
								     *   ( <op> <expr>+ )
							 | 
						||
| 
								 | 
							
								     *   ( block <name>? <block_sig> <instr>* )
							 | 
						||
| 
								 | 
							
								     *   ( loop <name>? <block_sig> <instr>* )
							 | 
						||
| 
								 | 
							
								     *   ( if <name>? <block_sig> ( then <instr>* ) ( else <instr>* )? )
							 | 
						||
| 
								 | 
							
								     *   ( if <name>? <block_sig> <expr>+ ( then <instr>* ) ( else <instr>* )? )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * op:
							 | 
						||
| 
								 | 
							
								     *   unreachable
							 | 
						||
| 
								 | 
							
								     *   nop
							 | 
						||
| 
								 | 
							
								     *   br <var>
							 | 
						||
| 
								 | 
							
								     *   br_if <var>
							 | 
						||
| 
								 | 
							
								     *   br_table <var>+
							 | 
						||
| 
								 | 
							
								     *   return
							 | 
						||
| 
								 | 
							
								     *   call <var>
							 | 
						||
| 
								 | 
							
								     *   call_indirect <func_sig>
							 | 
						||
| 
								 | 
							
								     *   drop
							 | 
						||
| 
								 | 
							
								     *   select
							 | 
						||
| 
								 | 
							
								     *   get_local <var>
							 | 
						||
| 
								 | 
							
								     *   set_local <var>
							 | 
						||
| 
								 | 
							
								     *   tee_local <var>
							 | 
						||
| 
								 | 
							
								     *   get_global <var>
							 | 
						||
| 
								 | 
							
								     *   set_global <var>
							 | 
						||
| 
								 | 
							
								     *   <type>.load((8|16|32)_<sign>)? <offset>? <align>?
							 | 
						||
| 
								 | 
							
								     *   <type>.store(8|16|32)? <offset>? <align>?
							 | 
						||
| 
								 | 
							
								     *   current_memory
							 | 
						||
| 
								 | 
							
								     *   grow_memory
							 | 
						||
| 
								 | 
							
								     *   <type>.const <value>
							 | 
						||
| 
								 | 
							
								     *   <type>.<unop>
							 | 
						||
| 
								 | 
							
								     *   <type>.<binop>
							 | 
						||
| 
								 | 
							
								     *   <type>.<testop>
							 | 
						||
| 
								 | 
							
								     *   <type>.<relop>
							 | 
						||
| 
								 | 
							
								     *   <type>.<cvtop>/<type>
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * func_type:   ( type <var> )? <param>* <result>*
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseFuncInstr() {
							 | 
						||
| 
								 | 
							
								      var startLoc = getStartLoc();
							 | 
						||
| 
								 | 
							
								      maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * A simple instruction
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.name || token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								        var _name2 = token.value;
							 | 
						||
| 
								 | 
							
								        var object;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.dot) {
							 | 
						||
| 
								 | 
							
								          object = _name2;
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (token.type !== tokens.name) {
							 | 
						||
| 
								 | 
							
								            throw new TypeError("Unknown token: " + token.type + ", name expected");
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          _name2 = token.value;
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								          var _endLoc = token.loc.end;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (typeof object === "undefined") {
							 | 
						||
| 
								 | 
							
								            return t.withLoc(t.instruction(_name2), _endLoc, startLoc);
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								            return t.withLoc(t.objectInstruction(_name2, object, []), _endLoc, startLoc);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var signature = t.signatureForOpcode(object || "", _name2);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _parseFuncInstrArgume = parseFuncInstrArguments(signature),
							 | 
						||
| 
								 | 
							
								            _args = _parseFuncInstrArgume.args,
							 | 
						||
| 
								 | 
							
								            _namedArgs = _parseFuncInstrArgume.namedArgs;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var endLoc = token.loc.end;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (typeof object === "undefined") {
							 | 
						||
| 
								 | 
							
								          return t.withLoc(t.instruction(_name2, _args, _namedArgs), endLoc, startLoc);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          return t.withLoc(t.objectInstruction(_name2, object, _args, _namedArgs), endLoc, startLoc);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.loop)) {
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Else a instruction with a keyword (loop or block)
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        eatToken(); // keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return parseLoop();
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.block)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return parseBlock();
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.call_indirect)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return parseCallIndirect();
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.call)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var index;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								          index = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								          index = t.indexLiteral(token.value);
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var instrArgs = []; // Nested instruction
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          instrArgs.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (typeof index === "undefined") {
							 | 
						||
| 
								 | 
							
								          throw new Error("Missing argument in call instruciton");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (instrArgs.length > 0) {
							 | 
						||
| 
								 | 
							
								          return t.callInstruction(index, instrArgs);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          return t.callInstruction(index);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.if)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // Keyword
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return parseIf();
							 | 
						||
| 
								 | 
							
								      } else if (isKeyword(token, keywords.module) && hasPlugin("wast")) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // In WAST you can have a module as an instruction's argument
							 | 
						||
| 
								 | 
							
								        // we will cast it into a instruction to not break the flow
							 | 
						||
| 
								 | 
							
								        // $FlowIgnore
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var module = parseModule();
							 | 
						||
| 
								 | 
							
								        return module;
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        throw function () {
							 | 
						||
| 
								 | 
							
								          return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected instruction in function body" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								        }();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								     * Parses a function
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAT:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * functype :: ( 'func' t1:vec(param) t2:vec(result) )
							 | 
						||
| 
								 | 
							
								     * param    :: ( 'param' id? t:valtype )
							 | 
						||
| 
								 | 
							
								     * result   :: ( 'result' t:valtype )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * func     :: ( func <name>? <func_sig> <local>* <instr>* )
							 | 
						||
| 
								 | 
							
								     *             ( func <name>? ( export <string> ) <...> )
							 | 
						||
| 
								 | 
							
								     *             ( func <name>? ( import <string> <string> ) <func_sig> )
							 | 
						||
| 
								 | 
							
								     * func_sig :: ( type <var> )? <param>* <result>*
							 | 
						||
| 
								 | 
							
								     * param    :: ( param <type>* ) | ( param <name> <type> )
							 | 
						||
| 
								 | 
							
								     * result   :: ( result <type>* )
							 | 
						||
| 
								 | 
							
								     * local    :: ( local <type>* ) | ( local <name> <type> )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseFunc() {
							 | 
						||
| 
								 | 
							
								      var fnName = t.identifier(getUniqueName("func"));
							 | 
						||
| 
								 | 
							
								      var typeRef;
							 | 
						||
| 
								 | 
							
								      var fnBody = [];
							 | 
						||
| 
								 | 
							
								      var fnParams = [];
							 | 
						||
| 
								 | 
							
								      var fnResult = []; // name
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        fnName = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        fnName = t.withRaw(fnName, ""); // preserve anonymous
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type === tokens.openParen || token.type === tokens.name || token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								        // Instructions without parens
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.name || token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								          fnBody.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(keywords.param) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          fnParams.push.apply(fnParams, _toConsumableArray(parseFuncParam()));
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(keywords.result) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          fnResult.push.apply(fnResult, _toConsumableArray(parseFuncResult()));
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(keywords.export) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          parseFuncExport(fnName);
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(keywords.type) === true) {
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								          typeRef = parseTypeReference();
							 | 
						||
| 
								 | 
							
								        } else if (lookaheadAndCheck(tokens.name) === true || lookaheadAndCheck(tokens.valtype) === true || token.type === "keyword" // is any keyword
							 | 
						||
| 
								 | 
							
								        ) {
							 | 
						||
| 
								 | 
							
								            // Instruction
							 | 
						||
| 
								 | 
							
								            fnBody.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								          } else {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in func body" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.func(fnName, typeRef !== undefined ? typeRef : t.signature(fnParams, fnResult), fnBody);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses shorthand export in func
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * export :: ( export <string> )
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseFuncExport(funcId) {
							 | 
						||
| 
								 | 
							
								      if (token.type !== tokens.string) {
							 | 
						||
| 
								 | 
							
								        throw function () {
							 | 
						||
| 
								 | 
							
								          return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Function export expected a string" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								        }();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var name = token.value;
							 | 
						||
| 
								 | 
							
								      eatToken();
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Func export shorthand, we trait it as a syntaxic sugar.
							 | 
						||
| 
								 | 
							
								       * A export ModuleField will be added later.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * We give the anonymous function a generated name and export it.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var id = t.identifier(funcId.value);
							 | 
						||
| 
								 | 
							
								      state.registredExportedElements.push({
							 | 
						||
| 
								 | 
							
								        exportType: "Func",
							 | 
						||
| 
								 | 
							
								        name: name,
							 | 
						||
| 
								 | 
							
								        id: id
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a type instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * typedef: ( type <name>? ( func <param>* <result>* ) )
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseType() {
							 | 
						||
| 
								 | 
							
								      var id;
							 | 
						||
| 
								 | 
							
								      var params = [];
							 | 
						||
| 
								 | 
							
								      var result = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        id = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (lookaheadAndCheck(tokens.openParen, keywords.func)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken(); // func
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // function with an empty signature, we can abort here
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          return t.typeInstruction(id, t.signature([], []));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(tokens.openParen, keywords.param)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // param
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          params = parseFuncParam();
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(tokens.openParen, keywords.result)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          result = parseFuncResult();
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.typeInstruction(id, t.signature(params, result));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a function result
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * result :: ( result <type>* )
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseFuncResult() {
							 | 
						||
| 
								 | 
							
								      var results = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								        if (token.type !== tokens.valtype) {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unexpected token in func result" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var valtype = token.value;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        results.push(valtype);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return results;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a type reference
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseTypeReference() {
							 | 
						||
| 
								 | 
							
								      var ref;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        ref = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								        ref = t.numberLiteralFromRaw(token.value);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return ref;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a global instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * global:  ( global <name>? <global_sig> <instr>* )
							 | 
						||
| 
								 | 
							
								     *          ( global <name>? ( export <string> ) <...> )
							 | 
						||
| 
								 | 
							
								     *          ( global <name>? ( import <string> <string> ) <global_sig> )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * global_sig: <type> | ( mut <type> )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseGlobal() {
							 | 
						||
| 
								 | 
							
								      var name = t.identifier(getUniqueName("global"));
							 | 
						||
| 
								 | 
							
								      var type; // Keep informations in case of a shorthand import
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var importing = null;
							 | 
						||
| 
								 | 
							
								      maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        name = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        name = t.withRaw(name, ""); // preserve anonymous
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * maybe export
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (lookaheadAndCheck(tokens.openParen, keywords.export)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken(); // export
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var exportName = token.value;
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.string);
							 | 
						||
| 
								 | 
							
								        state.registredExportedElements.push({
							 | 
						||
| 
								 | 
							
								          exportType: "Global",
							 | 
						||
| 
								 | 
							
								          name: exportName,
							 | 
						||
| 
								 | 
							
								          id: name
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * maybe import
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (lookaheadAndCheck(tokens.openParen, keywords.import)) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken(); // import
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var moduleName = token.value;
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.string);
							 | 
						||
| 
								 | 
							
								        var _name3 = token.value;
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.string);
							 | 
						||
| 
								 | 
							
								        importing = {
							 | 
						||
| 
								 | 
							
								          module: moduleName,
							 | 
						||
| 
								 | 
							
								          name: _name3,
							 | 
						||
| 
								 | 
							
								          descr: undefined
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * global_sig
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								        type = t.globalType(token.value, "const");
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      } else if (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								        eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (isKeyword(token, keywords.mut) === false) {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unsupported global type, expected mut" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken(); // mut
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        type = t.globalType(token.value, "var");
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (type === undefined) {
							 | 
						||
| 
								 | 
							
								        throw function () {
							 | 
						||
| 
								 | 
							
								          return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Could not determine global type" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								        }();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								      var init = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (importing != null) {
							 | 
						||
| 
								 | 
							
								        importing.descr = type;
							 | 
						||
| 
								 | 
							
								        init.push(t.moduleImport(importing.module, importing.name, importing.descr));
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * instr*
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        init.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.global(type, init, name);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses a function param
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * param    :: ( param <type>* ) | ( param <name> <type> )
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseFuncParam() {
							 | 
						||
| 
								 | 
							
								      var params = [];
							 | 
						||
| 
								 | 
							
								      var id;
							 | 
						||
| 
								 | 
							
								      var valtype;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        id = token.value;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								        valtype = token.value;
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        params.push({
							 | 
						||
| 
								 | 
							
								          id: id,
							 | 
						||
| 
								 | 
							
								          valtype: valtype
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Shorthand notation for multiple anonymous parameters
							 | 
						||
| 
								 | 
							
								         * @see https://webassembly.github.io/spec/core/text/types.html#function-types
							 | 
						||
| 
								 | 
							
								         * @see https://github.com/xtuc/webassemblyjs/issues/6
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (id === undefined) {
							 | 
						||
| 
								 | 
							
								          while (token.type === tokens.valtype) {
							 | 
						||
| 
								 | 
							
								            valtype = token.value;
							 | 
						||
| 
								 | 
							
								            eatToken();
							 | 
						||
| 
								 | 
							
								            params.push({
							 | 
						||
| 
								 | 
							
								              id: undefined,
							 | 
						||
| 
								 | 
							
								              valtype: valtype
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } else {// ignore
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return params;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses an element segments instruction
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * elem:    ( elem <var>? (offset <instr>* ) <var>* )
							 | 
						||
| 
								 | 
							
								     *          ( elem <var>? <expr> <var>* )
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * var:    <nat> | <name>
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseElem() {
							 | 
						||
| 
								 | 
							
								      var tableIndex = t.indexLiteral(0);
							 | 
						||
| 
								 | 
							
								      var offset = [];
							 | 
						||
| 
								 | 
							
								      var funcs = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        tableIndex = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								        tableIndex = t.indexLiteral(token.value);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								        if (lookaheadAndCheck(tokens.openParen, keywords.offset)) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatToken(); // offset
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          while (token.type !== tokens.closeParen) {
							 | 
						||
| 
								 | 
							
								            eatTokenOfType(tokens.openParen);
							 | 
						||
| 
								 | 
							
								            offset.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								            eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								          funcs.push(t.identifier(token.value));
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								          funcs.push(t.indexLiteral(token.value));
							 | 
						||
| 
								 | 
							
								          eatToken();
							 | 
						||
| 
								 | 
							
								        } else if (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								          eatToken(); // (
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          offset.push(parseFuncInstr());
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          throw function () {
							 | 
						||
| 
								 | 
							
								            return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unsupported token in elem" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								          }();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.elem(tableIndex, offset, funcs);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Parses the start instruction in a module
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAST:
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * start:   ( start <var> )
							 | 
						||
| 
								 | 
							
								     * var:    <nat> | <name>
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * WAT:
							 | 
						||
| 
								 | 
							
								     * start ::= ‘(’ ‘start’  x:funcidx ‘)’
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function parseStart() {
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.identifier) {
							 | 
						||
| 
								 | 
							
								        var index = identifierFromToken(token);
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        return t.start(index);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (token.type === tokens.number) {
							 | 
						||
| 
								 | 
							
								        var _index2 = t.indexLiteral(token.value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        return t.start(_index2);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      throw new Error("Unknown start, token: " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (token.type === tokens.openParen) {
							 | 
						||
| 
								 | 
							
								      eatToken();
							 | 
						||
| 
								 | 
							
								      var startLoc = getStartLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.export)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								        var node = parseExport();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc2 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return t.withLoc(node, _endLoc2, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.loop)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node = parseLoop();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc3 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node, _endLoc3, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.func)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node2 = parseFunc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc4 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node2, _endLoc4, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.module)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node3 = parseModule();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc5 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node3, _endLoc5, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.import)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node4 = parseImport();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc6 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node4, _endLoc6, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.block)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node5 = parseBlock();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc7 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node5, _endLoc7, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.memory)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node6 = parseMemory();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc8 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node6, _endLoc8, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.data)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node7 = parseData();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc9 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node7, _endLoc9, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.table)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node8 = parseTable();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc10 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node8, _endLoc10, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.global)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node9 = parseGlobal();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc11 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node9, _endLoc11, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.type)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node10 = parseType();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc12 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node10, _endLoc12, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.start)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node11 = parseStart();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc13 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node11, _endLoc13, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isKeyword(token, keywords.elem)) {
							 | 
						||
| 
								 | 
							
								        eatToken();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _node12 = parseElem();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        var _endLoc14 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        return t.withLoc(_node12, _endLoc14, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var instruction = parseFuncInstr();
							 | 
						||
| 
								 | 
							
								      var endLoc = getEndLoc();
							 | 
						||
| 
								 | 
							
								      maybeIgnoreComment();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (_typeof(instruction) === "object") {
							 | 
						||
| 
								 | 
							
								        if (typeof token !== "undefined") {
							 | 
						||
| 
								 | 
							
								          eatTokenOfType(tokens.closeParen);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return t.withLoc(instruction, endLoc, startLoc);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (token.type === tokens.comment) {
							 | 
						||
| 
								 | 
							
								      var _startLoc = getStartLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var builder = token.opts.type === "leading" ? t.leadingComment : t.blockComment;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var _node13 = builder(token.value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      eatToken(); // comment
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var _endLoc15 = getEndLoc();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return t.withLoc(_node13, _endLoc15, _startLoc);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    throw function () {
							 | 
						||
| 
								 | 
							
								      return new Error("\n" + codeFrameFromSource(source, token.loc) + "\n" + "Unknown token" + ", given " + tokenToString(token));
							 | 
						||
| 
								 | 
							
								    }();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var body = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (current < tokensList.length) {
							 | 
						||
| 
								 | 
							
								    body.push(walk());
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return t.program(body);
							 | 
						||
| 
								 | 
							
								}
							 |