homunculus
Advanced tools
Comparing version 0.1.8 to 0.1.9
var gulp = require('gulp'); | ||
var clean = require('gulp-clean'); | ||
var util = require('gulp-util'); | ||
var es = require('event-stream'); | ||
@@ -6,78 +9,33 @@ var fs = require('fs'); | ||
function clean(dir, includeSelf) { | ||
function mkdir(dir) { | ||
if(!fs.existsSync(dir)) { | ||
return; | ||
var parent = path.dirname(dir); | ||
mkdir(parent); | ||
fs.mkdirSync(dir); | ||
} | ||
fs.readdirSync(dir).forEach(function(f) { | ||
f = dir + path.sep + f; | ||
if(!fs.existsSync(f)) { | ||
return; | ||
} | ||
var stat = fs.statSync(f); | ||
if(stat.isDirectory()) { | ||
clean(f, true); | ||
} | ||
else if(stat.isFile()) { | ||
fs.unlinkSync(f); | ||
} | ||
}); | ||
if(includeSelf) { | ||
fs.rmdirSync(dir); | ||
} | ||
} | ||
function web2src(dir) { | ||
fs.readdirSync(dir).forEach(function(f) { | ||
f = dir + path.sep + f; | ||
var stat = fs.statSync(f); | ||
var target = f.replace('web', 'src'); | ||
if(stat.isDirectory()) { | ||
if(!fs.existsSync(target)) { | ||
fs.mkdirSync(target); | ||
} | ||
web2src(f); | ||
} | ||
else if(stat.isFile()) { | ||
console.log(f, '->', target); | ||
var s = fs.readFileSync(f, { encoding: 'utf-8' }); | ||
s = s.replace(/^define[^\n]*\n\t?/, ''); | ||
s = s.replace(/\n\t/g, '\n'); | ||
s = s.replace(/\t/g, ' '); | ||
s = s.replace(/[\s]*\}\)\;[\s]*$/, ''); | ||
fs.writeFileSync(target, s, { encoding: 'utf-8' }); | ||
} | ||
}); | ||
} | ||
function src2web(dir) { | ||
fs.readdirSync(dir).forEach(function(f) { | ||
f = dir + path.sep + f; | ||
var stat = fs.statSync(f); | ||
var target = f.replace('src', 'web'); | ||
if(stat.isDirectory()) { | ||
if(!fs.existsSync(target)) { | ||
fs.mkdirSync(target); | ||
} | ||
src2web(f); | ||
} | ||
else if(stat.isFile()) { | ||
console.log(f, '->', target); | ||
var s = fs.readFileSync(f, { encoding: 'utf-8' }); | ||
s = 'define(function(require, exports, module) {\n ' + s.replace(/\n/g, '\n ') + '\n});'; | ||
fs.writeFileSync(target, s, { encoding: 'utf-8' }); | ||
} | ||
}); | ||
} | ||
gulp.task('src2web', ['clean-web'], function() { | ||
src2web('./src'); | ||
}); | ||
gulp.task('web2src', ['clean-src'], function() { | ||
web2src('./web'); | ||
}); | ||
gulp.task('clean-web', function() { | ||
clean('./web'); | ||
return gulp.src('./web/*') | ||
.pipe(clean()); | ||
}); | ||
gulp.task('clean-src', function() { | ||
clean('./src'); | ||
return gulp.src('./src/*') | ||
.pipe(clean()); | ||
}); | ||
gulp.task('default', ['src2web']); | ||
gulp.task('default', ['clean-web'], function() { | ||
gulp.src('./src/**/*.js') | ||
.pipe(function() { | ||
return es.map(function (file, cb) { | ||
var target = file.path.replace('/src/', '/web/'); | ||
mkdir(path.dirname(target)); | ||
util.log(path.relative(file.cwd, file.path), '->', path.relative(file.cwd, target)); | ||
var content = file._contents; | ||
content = content.toString('utf-8', 0, content.length); | ||
content = 'define(function(require, exports, module) {\n ' + content.replace(/\n/g, '\n ') + '\n});'; | ||
fs.writeFileSync(target, content, { encoding: 'utf-8' }); | ||
cb(null, file); | ||
}); | ||
}()); | ||
}); |
{ | ||
"name": "homunculus", | ||
"version": "0.1.8", | ||
"version": "0.1.9", | ||
"description": "A lexer&parser by Javascript", | ||
@@ -16,3 +16,4 @@ "maintainers": [ | ||
"blanket": { | ||
"pattern": ["src/lexer/Lexer", | ||
"pattern": [ | ||
"src/lexer/Lexer", | ||
"src/lexer/Token", | ||
@@ -23,3 +24,4 @@ "src/lexer/match", | ||
"src/parser/js", | ||
"src/util"] | ||
"src/util" | ||
] | ||
} | ||
@@ -45,9 +47,12 @@ }, | ||
"devDependencies": { | ||
"mocha": "^1.18.2", | ||
"gulp": "^3.6.0", | ||
"expect.js": "^0.3.1", | ||
"blanket": "^1.1.6", | ||
"coveralls": "^2.10.0", | ||
"event-stream": "^3.1.5", | ||
"expect.js": "^0.3.1", | ||
"gulp": "^3.6.0", | ||
"gulp-clean": "^0.2.4", | ||
"gulp-util": "^2.2.14", | ||
"mocha": "^1.18.2", | ||
"mocha-lcov-reporter": "0.0.1" | ||
} | ||
} |
@@ -12,1 +12,16 @@ # A lexer&parser by Javascript | ||
``` | ||
## API | ||
* getClass(type:String, lan:String):class | ||
* tyep: lexer parser node context token | ||
* lan: js javascript es ecmascript as actionscript css | ||
* getLexer(lan:String):object | ||
* lan: js javascript es ecmascript as actionscript css java c++ cpp cplusplus | ||
* getParser(lan:String):object | ||
* lan: js javascript es ecmascript css | ||
* getContext(lan:String):object | ||
* lan: js javascript es ecmascript | ||
## AST | ||
当调用语法分析器解析后,会返回生成ast,这是一个树状数据结构,每个节点都是对应语法解析器下地Node.js的实例。<br/> | ||
demo目录下是一个用js的parser分析输入js代码并画出ast形状的页面。 |
@@ -54,4 +54,4 @@ var Rule = require('./Rule'); | ||
}).statics({ | ||
KEYWORDS: 'boolean break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import in instanceof interface let new null package private protected public return static super switch this throw true try typeof var void while with yield'.split(' ') | ||
KEYWORDS: 'break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import in instanceof interface let new null package private protected public return static super switch this throw true try typeof var void while with yield'.split(' ') | ||
}); | ||
module.exports = EcmascriptRule; |
@@ -319,3 +319,3 @@ var Class = require('../../util/Class'); | ||
} | ||
//支持es6 | ||
function addParam(params, child) { | ||
@@ -326,5 +326,2 @@ params.leaves().forEach(function(leaf, i) { | ||
} | ||
else if(leaf.name() == JsNode.RESTPARAM) { | ||
child.addParam(leaf.leaves()[1].token().content()); | ||
} | ||
}); | ||
@@ -331,0 +328,0 @@ } |
@@ -24,2 +24,8 @@ var Class = require('../../util/Class'); | ||
}, | ||
leaf: function(i) { | ||
return this.children[i]; | ||
}, | ||
number: function() { | ||
return this.children.length; | ||
}, | ||
add: function() { | ||
@@ -132,2 +138,12 @@ var self = this; | ||
CALLEXPR: 'callexpr', | ||
ARRBINDPAT: 'arrbindpat', | ||
OBJBINDPAT: 'objbindpat', | ||
BINDPROPT: 'bindpropt', | ||
SINGLENAME: 'singlename', | ||
BINDELEM: 'bindelem', | ||
BINDREST: 'bindrest', | ||
BINDID: 'bindid', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
getKey: function(s) { | ||
@@ -134,0 +150,0 @@ if(!s) { |
@@ -58,5 +58,2 @@ var Class = require('../../util/Class'); | ||
} | ||
else if(this.look.content() == 'class') { | ||
return this.classdecl(); | ||
} | ||
else { | ||
@@ -71,6 +68,2 @@ return this.stmt(allowSuper); | ||
switch(this.look.content()) { | ||
case 'let': | ||
return this.letstmt(); | ||
case 'const': | ||
return this.cststmt(); | ||
case 'var': | ||
@@ -104,9 +97,2 @@ return this.varstmt(); | ||
return this.debstmt(); | ||
case 'super': | ||
if(!allowSuper) { | ||
this.error('super must in a class'); | ||
} | ||
return this.superstmt(); | ||
case 'import': | ||
return this.imptstmt(); | ||
default: | ||
@@ -134,36 +120,2 @@ if(this.look.type() == Token.ID) { | ||
}, | ||
cststmt: function(noSem) { | ||
var node = new Node(Node.CSTSTMT); | ||
node.add( | ||
this.match('const'), | ||
this.vardecl() | ||
); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
} | ||
return node; | ||
}, | ||
letstmt: function(noSem) { | ||
var node = new Node(Node.LETSTMT); | ||
node.add( | ||
this.match('let'), | ||
this.vardecl() | ||
); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
} | ||
return node; | ||
}, | ||
varstmt: function(noSem) { | ||
@@ -191,8 +143,3 @@ var node = new Node(Node.VARSTMT); | ||
} | ||
if(this.look.content() == '[') { | ||
node.add(this.arrltr()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID, 'missing variable name')); | ||
} | ||
node.add(this.match(Token.ID, 'missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
@@ -516,38 +463,2 @@ node.add(this.assign()); | ||
}, | ||
superstmt: function() { | ||
var node = new Node(Node.SUPERSTMT); | ||
node.add(this.match('super')); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == '.') { | ||
while(this.look && this.look.content() == '.') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == 'super') { | ||
node.add(this.match()); | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
if(this.look.content() != '(') { | ||
node.add(this.match(Token.ID)); | ||
while(this.look && this.look.content() == '.') { | ||
node.add(this.match(), this.match(Token.ID)); | ||
} | ||
} | ||
} | ||
node.add( | ||
this.args(), | ||
this.match(';') | ||
); | ||
return node; | ||
}, | ||
imptstmt: function() { | ||
var node = new Node(Node.IMPTSTMT); | ||
return node; | ||
}, | ||
fndecl: function() { | ||
@@ -600,33 +511,10 @@ var node = new Node(Node.FNDECL); | ||
var node = new Node(Node.FNPARAMS); | ||
node.add(this.match(Token.ID, 'missing formal parameter')); | ||
while(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error('missing formal parameter'); | ||
} | ||
if(this.look.type() == Token.ID) { | ||
while(this.look && this.look.content() != ')') { | ||
node.add(this.match(Token.ID, 'missing formal parameter')); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.bindelement()); | ||
} | ||
} | ||
else if(this.look.content() == '...') { | ||
node.add(this.restparam()); | ||
} | ||
else { | ||
this.error('missing formal parameter'); | ||
} | ||
} | ||
return node; | ||
}, | ||
bindelement: function() { | ||
var node = new Node(Node.BINDELEMENT); | ||
node.add(this.match('='), this.assignexpr()); | ||
return node; | ||
}, | ||
restparam: function() { | ||
var node = new Node(Node.RESTPARAM); | ||
node.add(this.match('...'), this.match(Token.ID)); | ||
return node; | ||
}, | ||
fnbody: function(allowSuper) { | ||
@@ -639,72 +527,2 @@ var node = new Node(Node.FNBODY); | ||
}, | ||
classdecl: function() { | ||
var node = new Node(Node.CLASSDECL); | ||
node.add(this.match('class'), this.match(Token.ID)); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == 'extends') { | ||
node.add(this.heratige()); | ||
} | ||
node.add( | ||
this.match('{'), | ||
this.classbody(), | ||
this.match('}') | ||
); | ||
return node; | ||
}, | ||
heratige: function() { | ||
var node = new Node(Node.HERITAGE); | ||
node.add(this.match('extends'), this.match(Token.ID)); | ||
return node; | ||
}, | ||
classbody: function() { | ||
var node = new Node(Node.CLASSBODY), | ||
methods = {}, | ||
hasStatic = false; | ||
while(this.look && this.look.content() != '}') { | ||
if(this.look.content() == ';') { | ||
node.add(this.match()); | ||
continue; | ||
} | ||
hasStatic = false; | ||
if(this.look.content() == 'static') { | ||
node.add(this.match()); | ||
hasStatic = true; | ||
} | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
node.add(this.method(hasStatic, methods)); | ||
} | ||
return node; | ||
}, | ||
method: function(hasStatic, methods, statics) { | ||
var node = new Node(Node.METHOD); | ||
if(this.look.content() == 'get') { | ||
node.add(this.match(), this.getfn()); | ||
} | ||
else if(this.look.content() == 'set') { | ||
node.add(this.match(), this.setfn()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID)); | ||
var id = node.leaves()[0].token().content(); | ||
if(methods.hasOwnProperty(id)) { | ||
this.error('duplicate method decl in class'); | ||
} | ||
methods[id] = true; | ||
node.add(this.match('(')); | ||
if(this.look.content() != ')') { | ||
node.add(this.fnparams()); | ||
} | ||
node.add( | ||
this.match(')'), | ||
this.match('{'), | ||
this.fnbody(true), | ||
this.match('}', 'missing } in compound statement') | ||
); | ||
} | ||
return node; | ||
}, | ||
expr: function(noIn) { | ||
@@ -1165,3 +983,3 @@ var node = new Node(Node.EXPR), | ||
} | ||
node.add(this.match(']')); | ||
node.add(this.match(']', 'missing ] after element list')); | ||
return node; | ||
@@ -1178,3 +996,3 @@ }, | ||
} | ||
node.add(this.match('}')); | ||
node.add(this.match('}', 'missing } after property list')); | ||
return node; | ||
@@ -1184,91 +1002,17 @@ }, | ||
var node = new Node(Node.PROPTASSIGN); | ||
if(!this.look) { | ||
this.error(); | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.STRING: | ||
case Token.NUMBER: | ||
node.add( | ||
this.match(), | ||
this.match(':', 'missing : after property id'), | ||
this.assignexpr() | ||
); | ||
break; | ||
default: | ||
this.error('invalid property id'); | ||
} | ||
if(this.look.content() == 'get') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == ':') { | ||
node.add(this.match(), this.assignexpr()); | ||
} | ||
else { | ||
node.add(this.getfn()); | ||
} | ||
} | ||
else if(this.look.content() == 'set') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == ':') { | ||
node.add(this.match(), this.assignexpr()); | ||
} | ||
else { | ||
node.add(this.setfn()); | ||
} | ||
} | ||
else { | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.STRING: | ||
case Token.NUMBER: | ||
node.add( | ||
this.match(), | ||
this.match(':'), | ||
this.assignexpr() | ||
); | ||
break; | ||
default: | ||
this.error('invalid property id'); | ||
} | ||
} | ||
return node; | ||
}, | ||
getfn: function() { | ||
var node = new Node(Node.GETFN); | ||
node.add( | ||
this.proptname(), | ||
this.match('('), | ||
this.match(')'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}') | ||
); | ||
return node; | ||
}, | ||
setfn: function() { | ||
var node = new Node(Node.SETFN); | ||
node.add( | ||
this.proptname(), | ||
this.match('('), | ||
this.propsets(), | ||
this.match(')'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}') | ||
); | ||
return node; | ||
}, | ||
proptname: function() { | ||
var node = new Node(Node.PROPTNAME); | ||
if(this.look) { | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.NUMBER: | ||
case Token.STRING: | ||
node.add(this.match()); | ||
break; | ||
default: | ||
this.error('missing name after . operator'); | ||
} | ||
} | ||
return node; | ||
}, | ||
propsets: function() { | ||
var node = new Node(Node.PROPTSETS); | ||
node.add(this.match(Token.ID, 'setter functions must have one argument')); | ||
return node; | ||
}, | ||
args: function() { | ||
@@ -1288,5 +1032,7 @@ var node = new Node(Node.ARGS); | ||
var node = new Node(Node.ARGLIST); | ||
node.add(this.assignexpr()); | ||
while(this.look && this.look.content() == ',') { | ||
node.add(this.match(), this.assignexpr()); | ||
while(this.look && this.look.content() != ')') { | ||
node.add(this.assignexpr()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
} | ||
@@ -1293,0 +1039,0 @@ return node; |
@@ -61,3 +61,3 @@ var homunculus = require('../'); | ||
var context = homunculus.getContext('js'); | ||
context.parse('function a(b, c = 1, ...d){}'); | ||
context.parse('function a(b, c, d){}'); | ||
var a = context.getChild('a'); | ||
@@ -64,0 +64,0 @@ expect(a.hasParam('b')).to.be(true); |
@@ -179,5 +179,20 @@ var homunculus = require('../'); | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('function a(b, c = 1, ...d) {}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM, [JsNode.FNDECL, ['function', 'a', '(', JsNode.FNPARAMS, ['b', ',', 'c', JsNode.BINDELEMENT, ['=', JsNode.PRMREXPR, ['1']], ',', JsNode.RESTPARAM, ['...', 'd']], ')', '{', JsNode.FNBODY, [], '}']]]); | ||
var node = parser.parse('function a(b,c) {}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.FNDECL,["function","a","(",JsNode.FNPARAMS,["b",",","c"],")","{",JsNode.FNBODY,[],"}"]]]); | ||
}); | ||
// it('fndecl bindelem', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('function a(b, c = 1, ...d){}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.FNDECL,["function","a","(",JsNode.FNPARAMS,["b",",","c",JsNode.BINDELEMENT,["=",JsNode.PRMREXPR,["1"]],",",JsNode.RESTPARAM,["...","d"]],")","{",JsNode.FNBODY,[],"}"]]]); | ||
// }); | ||
// it('fndecl bindelem 2', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('function a(b, c = fn(...c)){}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.FNDECL,["function","a","(",JsNode.FNPARAMS,["b",",","c",JsNode.BINDELEMENT,["=",JsNode.CALLEXPR,[JsNode.PRMREXPR,["fn"],JsNode.ARGS,["(",JsNode.ARGLIST,[JsNode.BINDID,["...",JsNode.PRMREXPR,["c"]]],")"]]]],")","{",JsNode.FNBODY,[],"}"]]]); | ||
// }); | ||
// it('fndecl rest', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('function a(...b){}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.FNDECL,["function","a","(",JsNode.FNPARAMS,[JsNode.RESTPARAM,["...","b"]],")","{",JsNode.FNBODY,[],"}"]]]) | ||
// }); | ||
it('fndecl error 1', function() { | ||
@@ -269,2 +284,29 @@ var parser = homunculus.getParser('js'); | ||
}); | ||
// it('array spread in prmrexpr', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('[1, 2, ...gen()]'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.PRMREXPR,["1"],",",JsNode.PRMREXPR,["2"],",",JsNode.SPREAD,["...",JsNode.CALLEXPR,[JsNode.PRMREXPR,["gen"],JsNode.ARGS,["(",")"]]],"]"]]]]]); | ||
// }); | ||
it('arrltr', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('[,,,2,3,]'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRLTR,["[",",",",",",",JsNode.PRMREXPR,["2"],",",JsNode.PRMREXPR,["3"],",","]"]]]]]); | ||
}); | ||
it('arrltr error', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('[,,,2,3,'); | ||
}).to.throwError(); | ||
}); | ||
it('objltr', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('var o = {a: [], "b": 3, 5: {}}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.VARSTMT,["var",JsNode.VARDECL,["o",JsNode.ASSIGN,["=",JsNode.PRMREXPR,[JsNode.OBJLTR,["{",JsNode.PROPTASSIGN,["a",":",JsNode.PRMREXPR,[JsNode.ARRLTR,["[","]"]]],",",JsNode.PROPTASSIGN,["\"b\"",":",JsNode.PRMREXPR,["3"]],",",JsNode.PROPTASSIGN,["5",":",JsNode.PRMREXPR,[JsNode.OBJLTR,["{","}"]]],"}"]]]]]]]); | ||
}); | ||
it('objltr error', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('var o = {+'); | ||
}).to.throwError(); | ||
}); | ||
it('mmbexpr 1', function() { | ||
@@ -661,7 +703,2 @@ var parser = homunculus.getParser('js'); | ||
}); | ||
it('fndecl', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('function a(b, c = 1, ...d){}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.FNDECL,["function","a","(",JsNode.FNPARAMS,["b",",","c",JsNode.BINDELEMENT,["=",JsNode.PRMREXPR,["1"]],",",JsNode.RESTPARAM,["...","d"]],")","{",JsNode.FNBODY,[],"}"]]]); | ||
}); | ||
it('empty 1', function() { | ||
@@ -677,92 +714,152 @@ var parser = homunculus.getParser('js'); | ||
}); | ||
it('letstmt 1', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('let a'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.LETSTMT,["let",JsNode.VARDECL,["a"]]]]); | ||
}); | ||
it('letstmt 2', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('let a, b = 1'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.LETSTMT,["let",JsNode.VARDECL,["a"],",",JsNode.VARDECL,["b",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["1"]]]]]]); | ||
}); | ||
it('cststmt 1', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('const a'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CSTSTMT,["const",JsNode.VARDECL,["a"]]]]); | ||
}); | ||
it('cststmt 2', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('const a, b = 1'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CSTSTMT,["const",JsNode.VARDECL,["a"],",",JsNode.VARDECL,["b",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["1"]]]]]]); | ||
}); | ||
it('class decl', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A{;}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[';'],"}"]]]); | ||
}); | ||
it('class extend', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A{}class B extends A{}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[],"}"],JsNode.CLASSDECL,["class","B",JsNode.HERITAGE,["extends","A"],"{",JsNode.CLASSBODY,[],"}"]]]); | ||
}); | ||
it('class method', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A{ method(param){} }'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[JsNode.METHOD,["method","(",JsNode.FNPARAMS,["param"],")","{",JsNode.FNBODY,[],"}"]],"}"]]]); | ||
}); | ||
it('class static method', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A{ static method(){} }'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,["static",JsNode.METHOD,["method","(",")","{",JsNode.FNBODY,[],"}"]],"}"]]]); | ||
}); | ||
it('class error', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('class A'); | ||
}).to.throwError(); | ||
}); | ||
it('class method error', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('class A{ method'); | ||
}).to.throwError(); | ||
}); | ||
it('class method duplicate error', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('class A{ A(){} A(){} }'); | ||
}).to.throwError(); | ||
}); | ||
it('class static error', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('class A{ static'); | ||
}).to.throwError(); | ||
}); | ||
it('super in class', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A extends B{constructor(){super()}}') | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A",JsNode.HERITAGE,["extends","B"],"{",JsNode.CLASSBODY,[JsNode.METHOD,["constructor","(",")","{",JsNode.FNBODY,[JsNode.SUPERSTMT,["super",JsNode.ARGS,["(",")"]]],"}"]],"}"]]]); | ||
}); | ||
it('super recursion', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A extends B{method(){super.super.a()}}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A",JsNode.HERITAGE,["extends","B"],"{",JsNode.CLASSBODY,[JsNode.METHOD,["method","(",")","{",JsNode.FNBODY,[JsNode.SUPERSTMT,["super",".","super",".","a",JsNode.ARGS,["(",")"]]],"}"]],"}"]]]); | ||
}); | ||
it('super out class', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('super()'); | ||
}).to.throwError(); | ||
}); | ||
it('set', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A{set a(p){}}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[JsNode.METHOD,["set",JsNode.SETFN,[JsNode.PROPTNAME,["a"],"(",JsNode.PROPTSETS,["p"],")","{",JsNode.FNBODY,[],"}"]]],"}"]]]); | ||
}); | ||
it('get', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('class A{get a(){}}'); | ||
expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[JsNode.METHOD,["get",JsNode.GETFN,[JsNode.PROPTNAME,["a"],"(",")","{",JsNode.FNBODY,[],"}"]]],"}"]]]); | ||
}); | ||
// it('letstmt 1', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('let a'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.LETSTMT,["let",JsNode.VARDECL,["a"]]]]); | ||
// }); | ||
// it('letstmt 2', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('let a, b = 1'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.LETSTMT,["let",JsNode.VARDECL,["a"],",",JsNode.VARDECL,["b",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["1"]]]]]]); | ||
// }); | ||
// it('cststmt 1', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('const a'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CSTSTMT,["const",JsNode.VARDECL,["a"]]]]); | ||
// }); | ||
// it('cststmt 2', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('const a, b = 1'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CSTSTMT,["const",JsNode.VARDECL,["a"],",",JsNode.VARDECL,["b",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["1"]]]]]]); | ||
// }); | ||
// it('class decl', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A{;}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[';'],"}"]]]); | ||
// }); | ||
// it('class extend', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A{}class B extends A{}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[],"}"],JsNode.CLASSDECL,["class","B",JsNode.HERITAGE,["extends","A"],"{",JsNode.CLASSBODY,[],"}"]]]); | ||
// }); | ||
// it('class method', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A{ method(param){} }'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[JsNode.METHOD,["method","(",JsNode.FNPARAMS,["param"],")","{",JsNode.FNBODY,[],"}"]],"}"]]]); | ||
// }); | ||
// it('class static method', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A{ static method(){} }'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,["static",JsNode.METHOD,["method","(",")","{",JsNode.FNBODY,[],"}"]],"}"]]]); | ||
// }); | ||
// it('class error', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('class A'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('class method error', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('class A{ method'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('class method duplicate error', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('class A{ A(){} A(){} }'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('class static error', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('class A{ static'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('super in class', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A extends B{constructor(){super()}}') | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A",JsNode.HERITAGE,["extends","B"],"{",JsNode.CLASSBODY,[JsNode.METHOD,["constructor","(",")","{",JsNode.FNBODY,[JsNode.SUPERSTMT,["super",JsNode.ARGS,["(",")"]]],"}"]],"}"]]]); | ||
// }); | ||
// it('super recursion', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A extends B{method(){super.super.a()}}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A",JsNode.HERITAGE,["extends","B"],"{",JsNode.CLASSBODY,[JsNode.METHOD,["method","(",")","{",JsNode.FNBODY,[JsNode.SUPERSTMT,["super",".","super",".","a",JsNode.ARGS,["(",")"]]],"}"]],"}"]]]); | ||
// }); | ||
// it('super out class', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('super()'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('set', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A{set a(p){}}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[JsNode.METHOD,["set",JsNode.SETFN,[JsNode.PROPTNAME,["a"],"(",JsNode.PROPTSETS,["p"],")","{",JsNode.FNBODY,[],"}"]]],"}"]]]); | ||
// }); | ||
// it('get', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('class A{get a(){}}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CLASSDECL,["class","A","{",JsNode.CLASSBODY,[JsNode.METHOD,["get",JsNode.GETFN,[JsNode.PROPTNAME,["a"],"(",")","{",JsNode.FNBODY,[],"}"]]],"}"]]]); | ||
// }); | ||
// it('destructuring array', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('var [a] = [1]'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,["a"],"]"],JsNode.ASSIGN,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.PRMREXPR,["1"],"]"]]]]]]]); | ||
// }); | ||
// it('destructuring with restparam', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('let [a, ...b] = [1, 2, 3]'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM, [JsNode.LETSTMT, ["let", JsNode.VARDECL, [JsNode.ARRBINDPAT, ["[", JsNode.SINGLENAME, ["a"], ",", JsNode.RESTPARAM, ["...", "b"], "]"], JsNode.ASSIGN, ["=", JsNode.PRMREXPR, [JsNode.ARRLTR, ["[", JsNode.PRMREXPR, ["1"], ",", JsNode.PRMREXPR, ["2"], ",", JsNode.PRMREXPR, ["3"], "]"]]]]]]]); | ||
// }); | ||
// it('destructuring with default value', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('const [a = 1, [b] = [2]] = [, []]'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.CSTSTMT,["const",JsNode.VARDECL,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,["a",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["1"]]],",",JsNode.BINDELEM,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,["b"],"]"],JsNode.ASSIGN,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.PRMREXPR,["2"],"]"]]]],"]"],JsNode.ASSIGN,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",",",JsNode.PRMREXPR,[JsNode.ARRLTR,["[","]"]],"]"]]]]]]]); | ||
// }); | ||
// it('destructuring object', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('var {x, y = 1, "f": [z]} = {}'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.OBJBINDPAT,["{",JsNode.BINDPROPT,[JsNode.SINGLENAME,["x"]],",",JsNode.BINDPROPT,[JsNode.SINGLENAME,["y",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["1"]]]],",",JsNode.BINDPROPT,["\"f\"",":",JsNode.BINDELEM,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,["z"],"]"]]],"}"],JsNode.ASSIGN,["=",JsNode.PRMREXPR,[JsNode.OBJLTR,["{","}"]]]]]]]); | ||
// }); | ||
// it('destructuring complex', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('var [x, {"a":[y=1,{z=2},...o]}] = []'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,["x"],",",JsNode.BINDELEM,[JsNode.OBJBINDPAT,["{",JsNode.BINDPROPT,["\"a\"",":",JsNode.BINDELEM,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,["y",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["1"]]],",",JsNode.BINDELEM,[JsNode.OBJBINDPAT,["{",JsNode.BINDPROPT,[JsNode.SINGLENAME,["z",JsNode.ASSIGN,["=",JsNode.PRMREXPR,["2"]]]],"}"]],",",JsNode.RESTPARAM,["...","o"],"]"]]],"}"]],"]"],JsNode.ASSIGN,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[","]"]]]]]]]); | ||
// }); | ||
// it('destructuring without assign should throw error', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('var [a];'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('destructuring object error 1', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('var {'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('destructuring object error 2', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('var {a'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('destructuring object error 3', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('var {!'); | ||
// }).to.throwError(); | ||
// }); | ||
// it('destructuring object error 4', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// expect(function() { | ||
// parser.parse('var {a '); | ||
// }).to.throwError(); | ||
// }); | ||
// it('binding id in call', function() { | ||
// var parser = homunculus.getParser('js'); | ||
// var node = parser.parse('Math.max(...[1, 2])'); | ||
// expect(tree(node)).to.eql([JsNode.PROGRAM,[JsNode.EXPRSTMT,[JsNode.CALLEXPR,[JsNode.MMBEXPR,[JsNode.PRMREXPR,["Math"],".","max"],JsNode.ARGS,["(",JsNode.ARGLIST,[JsNode.BINDID,["...",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.PRMREXPR,["1"],",",JsNode.PRMREXPR,["2"],"]"]]]],")"]]]]]); | ||
// }); | ||
}); | ||
@@ -836,3 +933,3 @@ describe('js lib exec test', function() { | ||
describe('other test', function() { | ||
it('node parent,prev,next', function() { | ||
it('node #parent,#prev,#next', function() { | ||
var parser = homunculus.getParser('js'); | ||
@@ -851,2 +948,9 @@ var node = parser.parse('var a, b;'); | ||
}); | ||
it('node #leaf,#number,#leaves', function() { | ||
var parser = homunculus.getParser('js'); | ||
var node = parser.parse('var a'); | ||
var varstmt = node.leaf(0); | ||
expect(varstmt.name()).to.be(JsNode.VARSTMT); | ||
expect(varstmt.number()).to.be(3); | ||
}); | ||
it('#ast should return as parse return', function() { | ||
@@ -853,0 +957,0 @@ var parser = homunculus.getParser('js'); |
@@ -103,3 +103,3 @@ define(function(require, exports, module) { | ||
} | ||
//如果有未匹配的,说明规则不完整,加入other类型并抛出警告 | ||
//如果有未匹配的,说明规则不完整,抛出错误 | ||
this.error('unknow token'); | ||
@@ -106,0 +106,0 @@ } |
@@ -55,5 +55,5 @@ define(function(require, exports, module) { | ||
}).statics({ | ||
KEYWORDS: 'boolean break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import in instanceof interface let new null package private protected public return static super switch this throw throws true try typeof var void while with'.split(' ') | ||
KEYWORDS: 'break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import in instanceof interface let new null package private protected public return static super switch this throw true try typeof var void while with yield'.split(' ') | ||
}); | ||
module.exports = EcmascriptRule; | ||
}); |
@@ -25,2 +25,8 @@ define(function(require, exports, module) { | ||
}, | ||
leaf: function(i) { | ||
return this.children[i]; | ||
}, | ||
number: function() { | ||
return this.children.length; | ||
}, | ||
add: function() { | ||
@@ -133,2 +139,12 @@ var self = this; | ||
CALLEXPR: 'callexpr', | ||
ARRBINDPAT: 'arrbindpat', | ||
OBJBINDPAT: 'objbindpat', | ||
BINDPROPT: 'bindpropt', | ||
SINGLENAME: 'singlename', | ||
BINDELEM: 'bindelem', | ||
BINDREST: 'bindrest', | ||
BINDID: 'bindid', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
getKey: function(s) { | ||
@@ -135,0 +151,0 @@ if(!s) { |
@@ -59,5 +59,2 @@ define(function(require, exports, module) { | ||
} | ||
else if(this.look.content() == 'class') { | ||
return this.classdecl(); | ||
} | ||
else { | ||
@@ -72,6 +69,2 @@ return this.stmt(allowSuper); | ||
switch(this.look.content()) { | ||
case 'let': | ||
return this.letstmt(); | ||
case 'const': | ||
return this.cststmt(); | ||
case 'var': | ||
@@ -105,9 +98,2 @@ return this.varstmt(); | ||
return this.debstmt(); | ||
case 'super': | ||
if(!allowSuper) { | ||
this.error('super must in a class'); | ||
} | ||
return this.superstmt(); | ||
case 'import': | ||
return this.imptstmt(); | ||
default: | ||
@@ -135,36 +121,2 @@ if(this.look.type() == Token.ID) { | ||
}, | ||
cststmt: function(noSem) { | ||
var node = new Node(Node.CSTSTMT); | ||
node.add( | ||
this.match('const'), | ||
this.vardecl() | ||
); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
} | ||
return node; | ||
}, | ||
letstmt: function(noSem) { | ||
var node = new Node(Node.LETSTMT); | ||
node.add( | ||
this.match('let'), | ||
this.vardecl() | ||
); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
} | ||
return node; | ||
}, | ||
varstmt: function(noSem) { | ||
@@ -192,11 +144,15 @@ var node = new Node(Node.VARSTMT); | ||
} | ||
if(this.look.content() == '[') { | ||
node.add(this.arrltr()); | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
if(!this.look || this.look.content() != '=') { | ||
this.error('missing = in destructuring declaration'); | ||
} | ||
node.add(this.assign()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID, 'missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
} | ||
} | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
} | ||
return node; | ||
@@ -517,38 +473,2 @@ }, | ||
}, | ||
superstmt: function() { | ||
var node = new Node(Node.SUPERSTMT); | ||
node.add(this.match('super')); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == '.') { | ||
while(this.look && this.look.content() == '.') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == 'super') { | ||
node.add(this.match()); | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
if(this.look.content() != '(') { | ||
node.add(this.match(Token.ID)); | ||
while(this.look && this.look.content() == '.') { | ||
node.add(this.match(), this.match(Token.ID)); | ||
} | ||
} | ||
} | ||
node.add( | ||
this.args(), | ||
this.match(';') | ||
); | ||
return node; | ||
}, | ||
imptstmt: function() { | ||
var node = new Node(Node.IMPTSTMT); | ||
return node; | ||
}, | ||
fndecl: function() { | ||
@@ -601,33 +521,10 @@ var node = new Node(Node.FNDECL); | ||
var node = new Node(Node.FNPARAMS); | ||
node.add(this.match(Token.ID, 'missing formal parameter')); | ||
while(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error('missing formal parameter'); | ||
} | ||
if(this.look.type() == Token.ID) { | ||
while(this.look && this.look.content() != ')') { | ||
node.add(this.match(Token.ID, 'missing formal parameter')); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.bindelement()); | ||
} | ||
} | ||
else if(this.look.content() == '...') { | ||
node.add(this.restparam()); | ||
} | ||
else { | ||
this.error('missing formal parameter'); | ||
} | ||
} | ||
return node; | ||
}, | ||
bindelement: function() { | ||
var node = new Node(Node.BINDELEMENT); | ||
node.add(this.match('='), this.assignexpr()); | ||
return node; | ||
}, | ||
restparam: function() { | ||
var node = new Node(Node.RESTPARAM); | ||
node.add(this.match('...'), this.match(Token.ID)); | ||
return node; | ||
}, | ||
fnbody: function(allowSuper) { | ||
@@ -640,72 +537,2 @@ var node = new Node(Node.FNBODY); | ||
}, | ||
classdecl: function() { | ||
var node = new Node(Node.CLASSDECL); | ||
node.add(this.match('class'), this.match(Token.ID)); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == 'extends') { | ||
node.add(this.heratige()); | ||
} | ||
node.add( | ||
this.match('{'), | ||
this.classbody(), | ||
this.match('}') | ||
); | ||
return node; | ||
}, | ||
heratige: function() { | ||
var node = new Node(Node.HERITAGE); | ||
node.add(this.match('extends'), this.match(Token.ID)); | ||
return node; | ||
}, | ||
classbody: function() { | ||
var node = new Node(Node.CLASSBODY), | ||
methods = {}, | ||
hasStatic = false; | ||
while(this.look && this.look.content() != '}') { | ||
if(this.look.content() == ';') { | ||
node.add(this.match()); | ||
continue; | ||
} | ||
hasStatic = false; | ||
if(this.look.content() == 'static') { | ||
node.add(this.match()); | ||
hasStatic = true; | ||
} | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
node.add(this.method(hasStatic, methods)); | ||
} | ||
return node; | ||
}, | ||
method: function(hasStatic, methods, statics) { | ||
var node = new Node(Node.METHOD); | ||
if(this.look.content() == 'get') { | ||
node.add(this.match(), this.getfn()); | ||
} | ||
else if(this.look.content() == 'set') { | ||
node.add(this.match(), this.setfn()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID)); | ||
var id = node.leaves()[0].token().content(); | ||
if(methods.hasOwnProperty(id)) { | ||
this.error('duplicate method decl in class'); | ||
} | ||
methods[id] = true; | ||
node.add(this.match('(')); | ||
if(this.look.content() != ')') { | ||
node.add(this.fnparams()); | ||
} | ||
node.add( | ||
this.match(')'), | ||
this.match('{'), | ||
this.fnbody(true), | ||
this.match('}', 'missing } in compound statement') | ||
); | ||
} | ||
return node; | ||
}, | ||
expr: function(noIn) { | ||
@@ -1158,3 +985,3 @@ var node = new Node(Node.EXPR), | ||
node.add(this.match('[')); | ||
while(this.look && this.look.content() != ']') { | ||
while(this.look && this.look.content() != ']' && this.look.content() != '...') { | ||
if(this.look.content() == ',') { | ||
@@ -1165,5 +992,11 @@ node.add(this.match()); | ||
node.add(this.assignexpr()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
} | ||
} | ||
node.add(this.match(']')); | ||
if(this.look.content() == '...') { | ||
node.add(this.spread()); | ||
} | ||
node.add(this.match(']', 'missing ] after element list')); | ||
return node; | ||
@@ -1180,3 +1013,3 @@ }, | ||
} | ||
node.add(this.match('}')); | ||
node.add(this.match('}', 'missing } after property list')); | ||
return node; | ||
@@ -1220,3 +1053,3 @@ }, | ||
this.match(), | ||
this.match(':'), | ||
this.match(':', 'missing : after property id'), | ||
this.assignexpr() | ||
@@ -1231,47 +1064,2 @@ ); | ||
}, | ||
getfn: function() { | ||
var node = new Node(Node.GETFN); | ||
node.add( | ||
this.proptname(), | ||
this.match('('), | ||
this.match(')'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}') | ||
); | ||
return node; | ||
}, | ||
setfn: function() { | ||
var node = new Node(Node.SETFN); | ||
node.add( | ||
this.proptname(), | ||
this.match('('), | ||
this.propsets(), | ||
this.match(')'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}') | ||
); | ||
return node; | ||
}, | ||
proptname: function() { | ||
var node = new Node(Node.PROPTNAME); | ||
if(this.look) { | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.NUMBER: | ||
case Token.STRING: | ||
node.add(this.match()); | ||
break; | ||
default: | ||
this.error('missing name after . operator'); | ||
} | ||
} | ||
return node; | ||
}, | ||
propsets: function() { | ||
var node = new Node(Node.PROPTSETS); | ||
node.add(this.match(Token.ID, 'setter functions must have one argument')); | ||
return node; | ||
}, | ||
args: function() { | ||
@@ -1291,5 +1079,7 @@ var node = new Node(Node.ARGS); | ||
var node = new Node(Node.ARGLIST); | ||
node.add(this.assignexpr()); | ||
while(this.look && this.look.content() == ',') { | ||
node.add(this.match(), this.assignexpr()); | ||
while(this.look && this.look.content() != ')') { | ||
node.add(this.assignexpr()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
} | ||
@@ -1296,0 +1086,0 @@ return node; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1439232
83
29433
26
9
11