Fixed for-loop parsing

This commit is contained in:
dcodeIO 2017-11-29 00:18:14 +01:00
parent df637164a6
commit bad5175a55
10 changed files with 250 additions and 63 deletions

148
package-lock.json generated
View File

@ -14,16 +14,32 @@
"integrity": "sha512-q3zfJvaTroV5BjAAR+peTHEGAAhGrPX0z2EzCzpt2mwFA+qzUn2nigJLqSekXRtdULKmT8am7zjvTMZSapIgHw==", "integrity": "sha512-q3zfJvaTroV5BjAAR+peTHEGAAhGrPX0z2EzCzpt2mwFA+qzUn2nigJLqSekXRtdULKmT8am7zjvTMZSapIgHw==",
"dev": true "dev": true
}, },
"@types/glob": {
"version": "5.0.33",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.33.tgz",
"integrity": "sha512-BcD4yyWz+qmCggaYMSFF0Xn7GkO6tgwm3Fh9Gxk/kQmEU3Z7flQTnVlMyKBUNvXXNTCCyjqK4XT4/2hLd1gQ2A==",
"dev": true,
"requires": {
"@types/minimatch": "3.0.1",
"@types/node": "8.0.53"
}
},
"@types/long": { "@types/long": {
"version": "3.0.32", "version": "3.0.32",
"resolved": "https://registry.npmjs.org/@types/long/-/long-3.0.32.tgz", "resolved": "https://registry.npmjs.org/@types/long/-/long-3.0.32.tgz",
"integrity": "sha512-ZXyOOm83p7X8p3s0IYM3VeueNmHpkk/yMlP8CLeOnEcu6hIwPH7YjZBvhQkR0ZFS2DqZAxKtJ/M5fcuv3OU5BA==", "integrity": "sha512-ZXyOOm83p7X8p3s0IYM3VeueNmHpkk/yMlP8CLeOnEcu6hIwPH7YjZBvhQkR0ZFS2DqZAxKtJ/M5fcuv3OU5BA==",
"dev": true "dev": true
}, },
"@types/minimatch": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.1.tgz",
"integrity": "sha512-rUO/jz10KRSyA9SHoCWQ8WX9BICyj5jZYu1/ucKEJKb4KzLZCKMURdYbadP157Q6Zl1x0vHsrU+Z/O0XlhYQDw==",
"dev": true
},
"@types/node": { "@types/node": {
"version": "8.0.28", "version": "8.0.53",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.28.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz",
"integrity": "sha512-HupkFXEv3O3KSzcr3Ylfajg0kaerBg1DyaZzRBBQfrU3NN1mTBRE7sCveqHwXLS5Yrjvww8qFzkzYQQakG9FuQ==" "integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ=="
}, },
"ansi-styles": { "ansi-styles": {
"version": "3.2.0", "version": "3.2.0",
@ -31,7 +47,7 @@
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
"dev": true, "dev": true,
"requires": { "requires": {
"color-convert": "1.9.0" "color-convert": "1.9.1"
} }
}, },
"arrify": { "arrify": {
@ -40,26 +56,42 @@
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true "dev": true
}, },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"binaryen": { "binaryen": {
"version": "39.0.0-nightly.20171116", "version": "39.0.0-nightly.20171116",
"resolved": "https://registry.npmjs.org/binaryen/-/binaryen-39.0.0-nightly.20171116.tgz", "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-39.0.0-nightly.20171116.tgz",
"integrity": "sha512-ljl/qPne0+8hYtNWITRSAtxNM1EG5NnvTg+HRmSUdNAK2j9wcyAAg5uVj+TgipEqY82kmHt5C9+TSQNEwaxgrw==" "integrity": "sha512-ljl/qPne0+8hYtNWITRSAtxNM1EG5NnvTg+HRmSUdNAK2j9wcyAAg5uVj+TgipEqY82kmHt5C9+TSQNEwaxgrw=="
}, },
"brace-expansion": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
}
},
"chalk": { "chalk": {
"version": "2.1.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
"integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-styles": "3.2.0", "ansi-styles": "3.2.0",
"escape-string-regexp": "1.0.5", "escape-string-regexp": "1.0.5",
"supports-color": "4.4.0" "supports-color": "4.5.0"
} }
}, },
"color-convert": { "color-convert": {
"version": "1.9.0", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
"integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"color-name": "1.1.3" "color-name": "1.1.3"
@ -71,10 +103,16 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true "dev": true
}, },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"diff": { "diff": {
"version": "3.3.1", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
"integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
"dev": true "dev": true
}, },
"escape-string-regexp": { "escape-string-regexp": {
@ -83,12 +121,48 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true "dev": true
}, },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"has-flag": { "has-flag": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
"dev": true "dev": true
}, },
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"long": { "long": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
@ -101,6 +175,15 @@
"integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=",
"dev": true "dev": true
}, },
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.8"
}
},
"minimist": { "minimist": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
@ -124,6 +207,21 @@
} }
} }
}, },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"source-map": { "source-map": {
"version": "0.5.7", "version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@ -152,9 +250,9 @@
"dev": true "dev": true
}, },
"supports-color": { "supports-color": {
"version": "4.4.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
"integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
"dev": true, "dev": true,
"requires": { "requires": {
"has-flag": "2.0.0" "has-flag": "2.0.0"
@ -167,8 +265,8 @@
"dev": true, "dev": true,
"requires": { "requires": {
"arrify": "1.0.1", "arrify": "1.0.1",
"chalk": "2.1.0", "chalk": "2.3.0",
"diff": "3.3.1", "diff": "3.4.0",
"make-error": "1.3.0", "make-error": "1.3.0",
"minimist": "1.2.0", "minimist": "1.2.0",
"mkdirp": "0.5.1", "mkdirp": "0.5.1",
@ -189,9 +287,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "2.5.2", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
"integrity": "sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=", "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=",
"dev": true "dev": true
}, },
"user-home": { "user-home": {
@ -209,6 +307,12 @@
"user-home": "1.1.1" "user-home": "1.1.1"
} }
}, },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"yn": { "yn": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",

View File

@ -1,18 +1,20 @@
{ {
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": {
"@types/node": "^8.0.53",
"binaryen": "39.0.0-nightly.20171116"
},
"devDependencies": { "devDependencies": {
"@types/chalk": "^0.4.31", "@types/chalk": "^0.4.31",
"@types/diff": "^3.2.2", "@types/diff": "^3.2.2",
"@types/glob": "^5.0.33",
"@types/long": "^3.0.32", "@types/long": "^3.0.32",
"chalk": "^2.1.0", "chalk": "^2.3.0",
"diff": "^3.3.1", "diff": "^3.4.0",
"glob": "^7.1.2",
"long": "^3.2.0", "long": "^3.2.0",
"ts-node": "^3.3.0", "ts-node": "^3.3.0",
"typescript": "^2.5.2" "typescript": "^2.6.2"
},
"dependencies": {
"@types/node": "^8.0.28",
"binaryen": "39.0.0-nightly.20171116"
}, },
"scripts": { "scripts": {
"build": "tsc -P src", "build": "tsc -P src",

View File

@ -1257,7 +1257,6 @@ export class ExpressionStatement extends Statement {
serialize(sb: string[]): void { serialize(sb: string[]): void {
this.expression.serialize(sb); this.expression.serialize(sb);
sb.push(";");
} }
} }

View File

@ -1,6 +1,6 @@
import { PATH_DELIMITER } from "./constants"; import { PATH_DELIMITER } from "./constants";
import { DiagnosticCode, DiagnosticMessage, DiagnosticEmitter } from "./diagnostics"; import { DiagnosticCode, DiagnosticMessage, DiagnosticEmitter } from "./diagnostics";
import { Module, ModuleRef, MemorySegment, ExpressionRef, UnaryOp, BinaryOp, HostOp, NativeType, FunctionTypeRef, FunctionRef, ImportRef, ExportRef, GlobalRef, Relooper } from "./module"; import { Module, MemorySegment, ExpressionRef, UnaryOp, BinaryOp, NativeType, FunctionTypeRef } from "./module";
import { Program, ClassPrototype, Class, Element, ElementKind, Enum, FunctionPrototype, Function, Global, Local, Namespace, Parameter } from "./program"; import { Program, ClassPrototype, Class, Element, ElementKind, Enum, FunctionPrototype, Function, Global, Local, Namespace, Parameter } from "./program";
import { CharCode, I64, U64, normalizePath, sb } from "./util"; import { CharCode, I64, U64, normalizePath, sb } from "./util";
import { Token, Range } from "./tokenizer"; import { Token, Range } from "./tokenizer";

View File

@ -212,7 +212,7 @@ export class Parser extends DiagnosticEmitter {
return this.program; return this.program;
} }
parseType(tn: Tokenizer, acceptParenthesized: bool = true): TypeNode | null { parseType(tn: Tokenizer, acceptParenthesized: bool = true, suppressErrors: bool = false): TypeNode | null {
// not TypeScript-compatible // not TypeScript-compatible
const token: Token = tn.next(); const token: Token = tn.next();
const startPos: i32 = tn.tokenPos; const startPos: i32 = tn.tokenPos;
@ -225,11 +225,12 @@ export class Parser extends DiagnosticEmitter {
// ( ... ) // ( ... )
if (acceptParenthesized && token == Token.OPENPAREN) { if (acceptParenthesized && token == Token.OPENPAREN) {
const innerType: TypeNode | null = this.parseType(tn, false); const innerType: TypeNode | null = this.parseType(tn, false, suppressErrors);
if (!innerType) if (!innerType)
return null; return null;
if (!tn.skip(Token.CLOSEPAREN)) { if (!tn.skip(Token.CLOSEPAREN)) {
this.error(DiagnosticCode._0_expected, tn.range(tn.pos), "}"); if (!suppressErrors)
this.error(DiagnosticCode._0_expected, tn.range(tn.pos), "}");
return null; return null;
} }
type = innerType; type = innerType;
@ -264,7 +265,8 @@ export class Parser extends DiagnosticEmitter {
parameters.push(<TypeNode>parameter); parameters.push(<TypeNode>parameter);
} while (tn.skip(Token.COMMA)); } while (tn.skip(Token.COMMA));
if (!tn.skip(Token.GREATERTHAN)) { if (!tn.skip(Token.GREATERTHAN)) {
this.error(DiagnosticCode._0_expected, tn.range(tn.pos), ">"); if (!suppressErrors)
this.error(DiagnosticCode._0_expected, tn.range(tn.pos), ">");
return null; return null;
} }
} }
@ -273,21 +275,24 @@ export class Parser extends DiagnosticEmitter {
if (tn.skip(Token.NULL)) { if (tn.skip(Token.NULL)) {
nullable = true; nullable = true;
} else { } else {
this.error(DiagnosticCode._0_expected, tn.range(tn.pos), "null"); if (!suppressErrors)
this.error(DiagnosticCode._0_expected, tn.range(tn.pos), "null");
return null; return null;
} }
} }
type = TypeNode.create(identifier, parameters, nullable, tn.range(startPos, tn.pos)); type = TypeNode.create(identifier, parameters, nullable, tn.range(startPos, tn.pos));
} else { } else {
this.error(DiagnosticCode.Identifier_expected, tn.range()); if (!suppressErrors)
this.error(DiagnosticCode.Identifier_expected, tn.range());
return null; return null;
} }
// ... [][] // ... [][]
while (tn.skip(Token.OPENBRACKET)) { while (tn.skip(Token.OPENBRACKET)) {
let bracketStart: i32 = tn.tokenPos; let bracketStart: i32 = tn.tokenPos;
if (!tn.skip(Token.CLOSEBRACKET)) { if (!tn.skip(Token.CLOSEBRACKET)) {
this.error(DiagnosticCode._0_expected, tn.range(), "]"); if (!suppressErrors)
this.error(DiagnosticCode._0_expected, tn.range(), "]");
return null; return null;
} }
const bracketRange = tn.range(bracketStart, tn.pos); const bracketRange = tn.range(bracketStart, tn.pos);
@ -298,7 +303,8 @@ export class Parser extends DiagnosticEmitter {
if (tn.skip(Token.NULL)) { if (tn.skip(Token.NULL)) {
nullable = true; nullable = true;
} else { } else {
this.error(DiagnosticCode._0_expected, tn.range(), "null"); if (!suppressErrors)
this.error(DiagnosticCode._0_expected, tn.range(), "null");
return null; return null;
} }
} }
@ -999,26 +1005,36 @@ export class Parser extends DiagnosticEmitter {
// at 'for': '(' Statement? Expression? ';' Expression? ')' Statement // at 'for': '(' Statement? Expression? ';' Expression? ')' Statement
const startPos: i32 = tn.tokenPos; const startPos: i32 = tn.tokenPos;
if (tn.skip(Token.OPENPAREN)) { if (tn.skip(Token.OPENPAREN)) {
const initializer: Statement | null = this.parseStatement(tn); // skips the semicolon (actually an expression) let initializer: Statement | null = null;
if (!initializer) if (tn.skip(Token.LET) || tn.skip(Token.CONST) || tn.skip(Token.VAR)) {
return null; initializer = this.parseVariable(tn, /* TODO */ createModifiers());
if (initializer.kind != NodeKind.EXPRESSION && initializer.kind != NodeKind.VARIABLE) } else if (!tn.skip(Token.SEMICOLON)) {
this.error(DiagnosticCode.Expression_expected, initializer.range); // recoverable initializer = this.parseExpressionStatement(tn);
if (tn.token == Token.SEMICOLON) { if (!initializer)
const condition: Expression | null = this.parseExpression(tn);
if (!condition)
return null; return null;
if (tn.skip(Token.SEMICOLON)) { }
const incrementor: Expression | null = this.parseExpression(tn); if (tn.token == Token.SEMICOLON) {
if (!incrementor) let condition: ExpressionStatement | null = null;
if (!tn.skip(Token.SEMICOLON)) {
condition = this.parseExpressionStatement(tn);
if (!condition)
return null; return null;
if (tn.skip(Token.CLOSEPAREN)) { }
const statement: Statement | null = this.parseStatement(tn); if (tn.token == Token.SEMICOLON) {
if (!statement) let incrementor: Expression | null = null;
if (!tn.skip(Token.CLOSEPAREN)) {
incrementor = this.parseExpression(tn);
if (!incrementor)
return null; return null;
return Statement.createFor(initializer, condition, incrementor, statement, tn.range(startPos, tn.pos)); if (!tn.skip(Token.CLOSEPAREN)) {
} else this.error(DiagnosticCode._0_expected, tn.range(), ")");
this.error(DiagnosticCode._0_expected, tn.range(), ")"); return null;
}
}
const statement: Statement | null = this.parseStatement(tn);
if (!statement)
return null;
return Statement.createFor(initializer, condition ? condition.expression : null, incrementor, statement, tn.range(startPos, tn.pos));
} else } else
this.error(DiagnosticCode._0_expected, tn.range(), ";"); this.error(DiagnosticCode._0_expected, tn.range(), ";");
} else } else
@ -1225,6 +1241,7 @@ export class Parser extends DiagnosticEmitter {
parseExpressionPrefix(tn: Tokenizer): Expression | null { parseExpressionPrefix(tn: Tokenizer): Expression | null {
const token: Token = tn.next(); const token: Token = tn.next();
const startPos: i32 = tn.tokenPos; const startPos: i32 = tn.tokenPos;
let expr: Expression | null = null;
if (token == Token.NULL) if (token == Token.NULL)
return Expression.createNull(tn.range()); return Expression.createNull(tn.range());
@ -1248,10 +1265,10 @@ export class Parser extends DiagnosticEmitter {
if (tn.skip(Token.OPENPAREN)) { if (tn.skip(Token.OPENPAREN)) {
if (tn.peek() != Token.CLOSEPAREN) { if (tn.peek() != Token.CLOSEPAREN) {
do { do {
const expr: Expression | null = this.parseExpression(tn, Precedence.COMMA + 1); expr = this.parseExpression(tn, Precedence.COMMA + 1);
if (!expr) if (!expr)
return null; return null;
args.push(<Expression>expr); args.push(expr);
} while (tn.skip(Token.COMMA)); } while (tn.skip(Token.COMMA));
} }
if (!tn.skip(Token.CLOSEPAREN)) { if (!tn.skip(Token.CLOSEPAREN)) {
@ -1277,7 +1294,7 @@ export class Parser extends DiagnosticEmitter {
// ParenthesizedExpression // ParenthesizedExpression
case Token.OPENPAREN: { case Token.OPENPAREN: {
const expr: Expression | null = this.parseExpression(tn); expr = this.parseExpression(tn);
if (!expr) if (!expr)
return null; return null;
if (!tn.skip(Token.CLOSEPAREN)) { if (!tn.skip(Token.CLOSEPAREN)) {
@ -1292,7 +1309,6 @@ export class Parser extends DiagnosticEmitter {
const elementExpressions: (Expression | null)[] = new Array(); const elementExpressions: (Expression | null)[] = new Array();
if (!tn.skip(Token.CLOSEBRACKET)) { if (!tn.skip(Token.CLOSEBRACKET)) {
do { do {
let expr: Expression | null;
if (tn.peek() == Token.COMMA || tn.peek() == Token.CLOSEBRACKET) if (tn.peek() == Token.COMMA || tn.peek() == Token.CLOSEBRACKET)
expr = null; // omitted expr = null; // omitted
else { else {
@ -1319,7 +1335,7 @@ export class Parser extends DiagnosticEmitter {
this.error(DiagnosticCode._0_expected, tn.range(), ">"); this.error(DiagnosticCode._0_expected, tn.range(), ">");
return null; return null;
} }
const expr: Expression | null = this.parseExpressionPrefix(tn); expr = this.parseExpressionPrefix(tn);
if (!expr) if (!expr)
return null; return null;
return Expression.createAssertion(AssertionKind.PREFIX, <Expression>expr, <TypeNode>toType, tn.range(startPos, tn.pos)); return Expression.createAssertion(AssertionKind.PREFIX, <Expression>expr, <TypeNode>toType, tn.range(startPos, tn.pos));
@ -1359,7 +1375,7 @@ export class Parser extends DiagnosticEmitter {
const typeArguments: TypeNode[] = []; const typeArguments: TypeNode[] = [];
do { do {
const type: TypeNode | null = this.parseType(tn); const type: TypeNode | null = this.parseType(tn, true, true);
if (!type) { if (!type) {
tn.reset(); tn.reset();
return null; return null;

View File

@ -0,0 +1,3 @@
do {
;
} while (a != b);

View File

@ -0,0 +1,9 @@
for (let i: i32 = 0; i < 10; ++i) {
;
}
for (i = 0; i < 10; ++i) {
;
}
for (;;) {
;
}

View File

@ -0,0 +1,42 @@
0;
1;
2;
3;
4;
5;
6;
7;
8;
9;
// 0x0;
// 0x1;
// 0x2;
// 0x3;
// 0x4;
// 0x5;
// 0x6;
// 0x7;
// 0x8;
// 0x9;
// 0xA;
// 0xB;
// 0xC;
// 0xD;
// 0xE;
// 0xF;
// 0xa;
// 0xb;
// 0xc;
// 0xd;
// 0xe;
// 0xf;
// 0o0;
// 0o1;
// 0o2;
// 0o3;
// 0o4;
// 0o5;
// 0o6;
// 0o7;
// 0b0;
// 0b1;

View File

@ -0,0 +1,9 @@
while (1) {
;
}
while (true) {
;
}
while ("str") {
;
}

View File

@ -1,12 +1,15 @@
import * as fs from "fs"; import * as fs from "fs";
import * as diff from "diff"; import * as diff from "diff";
import * as chalk from "chalk"; import * as chalk from "chalk";
import * as glob from "glob";
import "../../src/glue/js"; import "../../src/glue/js";
import { NodeKind, ExpressionStatement } from "../../src/ast"; import { NodeKind, ExpressionStatement } from "../../src/ast";
import { Parser } from "../../src/parser"; import { Parser } from "../../src/parser";
const files = fs.readdirSync(__dirname + "/fixtures"); const filter = process.argv.length > 2 ? "*" + process.argv[2] + "*.ts" : "**.ts";
const files = glob.sync(filter, { cwd: __dirname + "/fixtures" });
files.forEach(filename => { files.forEach(filename => {
if (filename.charAt(0) == "_") return; if (filename.charAt(0) == "_") return;
const isTree = filename.indexOf(".tree.") >= 0; const isTree = filename.indexOf(".tree.") >= 0;