| Index: frogsh
|
| diff --git a/frogsh b/frogsh
|
| index 545e14dd1570e840da959798d88d363b6c1343d4..e47eca81fe01176e904a043128e3c426b9be569b 100755
|
| --- a/frogsh
|
| +++ b/frogsh
|
| @@ -412,8 +412,6 @@ Math.min = function(a, b) {
|
| if (isNaN(a)) return a;
|
| else return b;
|
| }
|
| -// ********** Code for Dispatcher **************
|
| -function Dispatcher() {}
|
| // ********** Code for Strings **************
|
| function Strings() {}
|
| Strings.String$fromCharCodes$factory = function(charCodes) {
|
| @@ -485,6 +483,7 @@ ListFactory$KeywordState = ListFactory;
|
| ListFactory$SplayTreeNode$K$V = ListFactory;
|
| ListFactory$String = ListFactory;
|
| ListFactory$T = ListFactory;
|
| +ListFactory$Token = ListFactory;
|
| ListFactory$V = ListFactory;
|
| // ********** Code for ListIterator **************
|
| function ListIterator(array) {
|
| @@ -1006,6 +1005,22 @@ $inherits(HashMapImplementation$String$DoubleLinkedQueueEntry$KeyValuePair$Strin
|
| HashMapImplementation$String$DoubleLinkedQueueEntry$KeyValuePair$String$Keyword._computeLoadLimit = function(capacity) {
|
| return $truncdiv((capacity * 3), 4);
|
| }
|
| +// ********** Code for HashMapImplementation$int$Token **************
|
| +function HashMapImplementation$int$Token() {
|
| + // Initializers done
|
| + if (HashMapImplementation._deletedKey == null) {
|
| + HashMapImplementation._deletedKey = new Object();
|
| + }
|
| + this._numberOfEntries = 0;
|
| + this._numberOfDeleted = 0;
|
| + this._loadLimit = HashMapImplementation._computeLoadLimit(8/*HashMapImplementation._INITIAL_CAPACITY*/);
|
| + this._keys = new ListFactory(8/*HashMapImplementation._INITIAL_CAPACITY*/);
|
| + this._values = new ListFactory$Token(8/*HashMapImplementation._INITIAL_CAPACITY*/);
|
| +}
|
| +$inherits(HashMapImplementation$int$Token, HashMapImplementation);
|
| +HashMapImplementation$int$Token._computeLoadLimit = function(capacity) {
|
| + return $truncdiv((capacity * 3), 4);
|
| +}
|
| // ********** Code for HashSetImplementation **************
|
| function HashSetImplementation() {
|
| // Initializers done
|
| @@ -11646,6 +11661,7 @@ TokenKind.kindFromAssign = function(kind) {
|
| }
|
| // ********** Code for lang_Parser **************
|
| function lang_Parser(source, diet, startOffset) {
|
| + this._highestCachePosition = -1
|
| this.source = source;
|
| this.diet = diet;
|
| // Initializers done
|
| @@ -11653,6 +11669,7 @@ function lang_Parser(source, diet, startOffset) {
|
| this._peekToken = this.tokenizer.next();
|
| this._previousToken = null;
|
| this._inInitializers = false;
|
| + this._afterCloseParenCache = new HashMapImplementation$int$Token();
|
| }
|
| lang_Parser.prototype.isPrematureEndOfFile = function() {
|
| if (this._maybeEat(1/*TokenKind.END_OF_FILE*/)) {
|
| @@ -12426,14 +12443,11 @@ lang_Parser.prototype.arguments = function() {
|
| }
|
| return args;
|
| }
|
| -lang_Parser.prototype.get$arguments = function() {
|
| - return lang_Parser.prototype.arguments.bind(this);
|
| -}
|
| lang_Parser.prototype.finishPostfixExpression = function(expr) {
|
| switch (this._peek()) {
|
| case 2/*TokenKind.LPAREN*/:
|
|
|
| - return this.finishPostfixExpression(new CallExpression(expr, this.arguments(), this._makeSpan(expr.get$span().start)));
|
| + return this.finishCallOrLambdaExpression(expr);
|
|
|
| case 4/*TokenKind.LBRACK*/:
|
|
|
| @@ -12458,9 +12472,7 @@ lang_Parser.prototype.finishPostfixExpression = function(expr) {
|
| case 9/*TokenKind.ARROW*/:
|
| case 6/*TokenKind.LBRACE*/:
|
|
|
| - if (this._inInitializers) return expr;
|
| - var body = this.functionBody(true);
|
| - return this._makeFunction(expr, body);
|
| + return expr;
|
|
|
| default:
|
|
|
| @@ -12473,6 +12485,17 @@ lang_Parser.prototype.finishPostfixExpression = function(expr) {
|
|
|
| }
|
| }
|
| +lang_Parser.prototype.finishCallOrLambdaExpression = function(expr) {
|
| + if (!this._inInitializers && this._atClosureParameters()) {
|
| + var formals = this.formalParameterList();
|
| + var body = this.functionBody(true);
|
| + return this._makeFunction(expr, formals, body);
|
| + }
|
| + else {
|
| + var args = this.arguments();
|
| + return this.finishPostfixExpression(new CallExpression(expr, args, this._makeSpan(expr.get$span().start)));
|
| + }
|
| +}
|
| lang_Parser.prototype._isBin = function(expr, kind) {
|
| return (expr instanceof BinaryExpression) && expr.op.kind == kind;
|
| }
|
| @@ -12647,14 +12670,14 @@ lang_Parser.prototype.maybeStringLiteral = function() {
|
| }
|
| lang_Parser.prototype._parenOrLambda = function() {
|
| var start = this._peekToken.start;
|
| - var args = this.arguments();
|
| - if (!this._inInitializers && (this._peekKind(9/*TokenKind.ARROW*/) || this._peekKind(6/*TokenKind.LBRACE*/))) {
|
| + if (!this._inInitializers && this._atClosureParameters()) {
|
| + var formals = this.formalParameterList();
|
| var body = this.functionBody(true);
|
| - var formals = this._makeFormals(args);
|
| var func = new FunctionDefinition(null, null, null, formals, null, body, this._makeSpan(start));
|
| return new LambdaExpression(func, func.get$span());
|
| }
|
| else {
|
| + var args = this.arguments();
|
| if (args.length == 1) {
|
| return new ParenExpression(args.$index(0).get$value(), this._makeSpan(start));
|
| }
|
| @@ -12664,6 +12687,45 @@ lang_Parser.prototype._parenOrLambda = function() {
|
| }
|
| }
|
| }
|
| +lang_Parser.prototype._atClosureParameters = function() {
|
| + var afterCloseParen = this._peekPastCloseParen();
|
| + return afterCloseParen.kind == 9/*TokenKind.ARROW*/ || afterCloseParen.kind == 6/*TokenKind.LBRACE*/;
|
| +}
|
| +lang_Parser.prototype._peekPastCloseParen = function() {
|
| + var pos = this._peekToken.start;
|
| + if (pos > this._highestCachePosition) return this._fillAfterCloseParenCache();
|
| + return this._afterCloseParenCache.$index(pos);
|
| +}
|
| +lang_Parser.prototype._fillAfterCloseParenCache = function() {
|
| + var tokens = [];
|
| + var positions = [];
|
| + var firstOpenParen = this._peekToken;
|
| + while (true) {
|
| + var token = this._lang_next();
|
| + tokens.add(token);
|
| + var kind = token.kind;
|
| + if (kind == 2/*TokenKind.LPAREN*/) {
|
| + positions.add(token.start);
|
| + }
|
| + else if (kind == 3/*TokenKind.RPAREN*/) {
|
| + var openPos = positions.removeLast();
|
| + if (positions.length == 0) break;
|
| + this._afterCloseParenCache.$setindex(openPos, this._peekToken);
|
| + if (openPos > this._highestCachePosition) this._highestCachePosition = openPos;
|
| + }
|
| + else if (kind == 1/*TokenKind.END_OF_FILE*/) {
|
| + this._lang_error('parenthesis never closed', firstOpenParen.get$span());
|
| + this._afterCloseParenCache = new HashMapImplementation$int$Token();
|
| + this._highestCachePosition = -1;
|
| + break;
|
| + }
|
| + }
|
| + var after = this._peekToken;
|
| + tokens.add(this._peekToken);
|
| + this.tokenizer = new DivertedTokenSource(tokens, this, this.tokenizer);
|
| + this._lang_next();
|
| + return after;
|
| +}
|
| lang_Parser.prototype._typeAsIdentifier = function(type) {
|
| return type.get$name();
|
| }
|
| @@ -13029,113 +13091,22 @@ lang_Parser.prototype.identifier = function() {
|
| }
|
| return new lang_Identifier(tok.get$text(), this._makeSpan(tok.start));
|
| }
|
| -lang_Parser.prototype._makeFunction = function(expr, body) {
|
| +lang_Parser.prototype._makeFunction = function(expr, formals, body) {
|
| var name, type;
|
| - if ((expr instanceof CallExpression)) {
|
| - if ((expr.target instanceof VarExpression)) {
|
| - name = expr.target.get$name();
|
| - type = null;
|
| - }
|
| - else if ((expr.target instanceof DeclaredIdentifier)) {
|
| - name = expr.target.get$name();
|
| - type = expr.target.type;
|
| - }
|
| - else {
|
| - this._lang_error('bad function');
|
| - }
|
| - var formals = this._makeFormals(expr.get$arguments());
|
| - var span = new SourceSpan(expr.get$span().file, expr.get$span().start, body.get$span().end);
|
| - var func = new FunctionDefinition(null, type, name, formals, null, body, span);
|
| - return new LambdaExpression(func, func.get$span());
|
| - }
|
| - else {
|
| - this._lang_error('expected function');
|
| - }
|
| -}
|
| -lang_Parser.prototype._makeFormal = function(expr) {
|
| if ((expr instanceof VarExpression)) {
|
| - return new FormalNode(false, false, null, expr.get$name(), null, expr.get$span());
|
| + name = expr.get$name();
|
| + type = null;
|
| }
|
| else if ((expr instanceof DeclaredIdentifier)) {
|
| - return new FormalNode(false, false, expr.type, expr.get$name(), null, expr.get$span());
|
| - }
|
| - else if (this._isBin(expr, 20/*TokenKind.ASSIGN*/) && ((expr.x instanceof DeclaredIdentifier))) {
|
| - var di = expr.x;
|
| - return new FormalNode(false, false, di.type, di.name, expr.y, expr.get$span());
|
| - }
|
| - else if (this._isBin(expr, 52/*TokenKind.LT*/)) {
|
| - return null;
|
| - }
|
| - else if ((expr instanceof ListExpression)) {
|
| - return this._makeFormalsFromList(expr);
|
| + name = expr.get$name();
|
| + type = expr.type;
|
| }
|
| else {
|
| - this._lang_error('expected formal', expr.get$span());
|
| + this._lang_error('bad function');
|
| }
|
| -}
|
| -lang_Parser.prototype._makeFormalsFromList = function(expr) {
|
| - if (expr.get$isConst()) {
|
| - this._lang_error('expected formal, but found "const"', expr.get$span());
|
| - }
|
| - else if ($ne(expr.type, null)) {
|
| - this._lang_error('expected formal, but found generic type arguments', expr.type.get$span());
|
| - }
|
| - return this._makeFormalsFromExpressions(expr.values, false);
|
| -}
|
| -lang_Parser.prototype._makeFormals = function(arguments) {
|
| - var expressions = [];
|
| - for (var i = 0;
|
| - i < arguments.length; i++) {
|
| - var arg = arguments.$index(i);
|
| - if (arg.label != null) {
|
| - this._lang_error('expected formal, but found ":"');
|
| - }
|
| - expressions.add(arg.get$value());
|
| - }
|
| - return this._makeFormalsFromExpressions(expressions, true);
|
| -}
|
| -lang_Parser.prototype._makeFormalsFromExpressions = function(expressions, allowOptional) {
|
| - var formals = [];
|
| - for (var i = 0;
|
| - i < expressions.length; i++) {
|
| - var formal = this._makeFormal(expressions.$index(i));
|
| - if (formal == null) {
|
| - var baseType = this._makeType(expressions.$index(i).x);
|
| - var typeParams = [this._makeType(expressions.$index(i).y)];
|
| - i++;
|
| - while (i < expressions.length) {
|
| - var expr = expressions.$index(i++);
|
| - if (this._isBin(expr, 53/*TokenKind.GT*/)) {
|
| - typeParams.add(this._makeType(expr.x));
|
| - var type = new GenericTypeReference(baseType, typeParams, 0, this._makeSpan(baseType.get$span().start));
|
| - var name = null;
|
| - if ((expr.y instanceof VarExpression)) {
|
| - var ve = expr.y;
|
| - name = ve.name;
|
| - }
|
| - else {
|
| - this._lang_error('expected formal', expr.get$span());
|
| - }
|
| - formal = new FormalNode(false, false, type, name, null, this._makeSpan(expressions.$index(0).get$span().start));
|
| - break;
|
| - }
|
| - else {
|
| - typeParams.add(this._makeType(expr));
|
| - }
|
| - }
|
| - formals.add(formal);
|
| - }
|
| - else if (!!(formal && formal.is$List)) {
|
| - formals.addAll(formal);
|
| - if (!allowOptional) {
|
| - this._lang_error('unexpected nested optional formal', expressions.$index(i).get$span());
|
| - }
|
| - }
|
| - else {
|
| - formals.add(formal);
|
| - }
|
| - }
|
| - return formals;
|
| + var span = new SourceSpan(expr.get$span().file, expr.get$span().start, body.get$span().end);
|
| + var func = new FunctionDefinition(null, type, name, formals, null, body, span);
|
| + return new LambdaExpression(func, func.get$span());
|
| }
|
| lang_Parser.prototype._makeDeclaredIdentifier = function(e) {
|
| if ((e instanceof VarExpression)) {
|
| @@ -13158,6 +13129,22 @@ lang_Parser.prototype._makeLabel = function(expr) {
|
| return null;
|
| }
|
| }
|
| +// ********** Code for DivertedTokenSource **************
|
| +function DivertedTokenSource(tokens, parser, previousTokenizer) {
|
| + this._lang_pos = 0
|
| + this.tokens = tokens;
|
| + this.parser = parser;
|
| + this.previousTokenizer = previousTokenizer;
|
| + // Initializers done
|
| +}
|
| +DivertedTokenSource.prototype.next = function() {
|
| + var token = this.tokens.$index(this._lang_pos);
|
| + ++this._lang_pos;
|
| + if (this._lang_pos == this.tokens.length) {
|
| + this.parser.tokenizer = this.previousTokenizer;
|
| + }
|
| + return token;
|
| +}
|
| // ********** Code for lang_Node **************
|
| function lang_Node(span) {
|
| this.span = span;
|
| @@ -13270,8 +13257,6 @@ function DirectiveDefinition(name, arguments, span) {
|
| $inherits(DirectiveDefinition, Definition);
|
| DirectiveDefinition.prototype.get$name = function() { return this.name; };
|
| DirectiveDefinition.prototype.set$name = function(value) { return this.name = value; };
|
| -DirectiveDefinition.prototype.get$arguments = function() { return this.arguments; };
|
| -DirectiveDefinition.prototype.set$arguments = function(value) { return this.arguments = value; };
|
| DirectiveDefinition.prototype.visit = function(visitor) {
|
| return visitor.visitDirectiveDefinition(this);
|
| }
|
| @@ -13558,8 +13543,6 @@ function CallExpression(target, arguments, span) {
|
| // Initializers done
|
| }
|
| $inherits(CallExpression, lang_Expression);
|
| -CallExpression.prototype.get$arguments = function() { return this.arguments; };
|
| -CallExpression.prototype.set$arguments = function(value) { return this.arguments = value; };
|
| CallExpression.prototype.visit = function(visitor) {
|
| return visitor.visitCallExpression(this);
|
| }
|
| @@ -13622,8 +13605,6 @@ lang_NewExpression.prototype.get$isConst = function() { return this.isConst; };
|
| lang_NewExpression.prototype.set$isConst = function(value) { return this.isConst = value; };
|
| lang_NewExpression.prototype.get$name = function() { return this.name; };
|
| lang_NewExpression.prototype.set$name = function(value) { return this.name = value; };
|
| -lang_NewExpression.prototype.get$arguments = function() { return this.arguments; };
|
| -lang_NewExpression.prototype.set$arguments = function(value) { return this.arguments = value; };
|
| lang_NewExpression.prototype.visit = function(visitor) {
|
| return visitor.visitNewExpression(this);
|
| }
|
|
|