Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: frogsh

Issue 8400017: Peek past balanced parens to see if they are an expression or lambda. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/frog
Patch Set: expand comments Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | parser.dart » ('j') | parser.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
« no previous file with comments | « no previous file | parser.dart » ('j') | parser.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698