simple visitor API and code to figure out scope and references
This commit is contained in:
51
lib/parse.js
51
lib/parse.js
@@ -836,7 +836,14 @@ function parse($TEXT, exigent_mode) {
|
||||
});
|
||||
|
||||
function labeled_statement() {
|
||||
var label = as_symbol(true);
|
||||
var label = as_symbol(AST_Label);
|
||||
if (find_if(function(l){ return l.name == label.name }, S.labels)) {
|
||||
// ECMA-262, 12.12: An ECMAScript program is considered
|
||||
// syntactically incorrect if it contains a
|
||||
// LabelledStatement that is enclosed by a
|
||||
// LabelledStatement with the same Identifier as label.
|
||||
croak("Label " + label.name + " defined twice");
|
||||
}
|
||||
expect(":");
|
||||
S.labels.push(label);
|
||||
var start = S.token, stat = statement();
|
||||
@@ -849,16 +856,13 @@ function parse($TEXT, exigent_mode) {
|
||||
};
|
||||
|
||||
function break_cont(type) {
|
||||
var name = null, label = null;
|
||||
var label = null;
|
||||
if (!can_insert_semicolon()) {
|
||||
name = is("name") ? S.token.value : null;
|
||||
label = as_symbol(AST_LabelRef, true);
|
||||
}
|
||||
if (name != null) {
|
||||
next();
|
||||
label = find_if(function(l){ return l.name == name }, S.labels);
|
||||
if (!label)
|
||||
croak("Label " + name + " without matching loop or statement");
|
||||
label = new AST_Label({ name: name, symbol: label });
|
||||
if (label != null) {
|
||||
if (!find_if(function(l){ return l.name == label.name }, S.labels))
|
||||
croak("Undefined label " + label.name);
|
||||
}
|
||||
else if (S.in_loop == 0)
|
||||
croak(type.TYPE + " not inside a loop or switch");
|
||||
@@ -910,7 +914,9 @@ function parse($TEXT, exigent_mode) {
|
||||
};
|
||||
|
||||
var function_ = function(in_statement) {
|
||||
var name = is("name") ? as_symbol(true) : null;
|
||||
var name = is("name") ? as_symbol(in_statement
|
||||
? AST_SymbolDefun
|
||||
: AST_SymbolLambda) : null;
|
||||
if (in_statement && !name)
|
||||
unexpected();
|
||||
expect("(");
|
||||
@@ -920,7 +926,7 @@ function parse($TEXT, exigent_mode) {
|
||||
argnames: (function(first, a){
|
||||
while (!is("punc", ")")) {
|
||||
if (first) first = false; else expect(",");
|
||||
a.push(as_symbol(true));
|
||||
a.push(as_symbol(AST_SymbolFunarg));
|
||||
}
|
||||
next();
|
||||
return a;
|
||||
@@ -1010,7 +1016,7 @@ function parse($TEXT, exigent_mode) {
|
||||
var start = S.token;
|
||||
next();
|
||||
expect("(");
|
||||
var name = as_symbol(true);
|
||||
var name = as_symbol(AST_SymbolCatch);
|
||||
expect(")");
|
||||
bcatch = new AST_Catch({
|
||||
start : start,
|
||||
@@ -1050,7 +1056,7 @@ function parse($TEXT, exigent_mode) {
|
||||
for (;;) {
|
||||
a.push(new AST_VarDef({
|
||||
start : S.token,
|
||||
name : as_symbol(true),
|
||||
name : as_symbol(AST_SymbolVar),
|
||||
value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
|
||||
end : prev()
|
||||
}));
|
||||
@@ -1099,7 +1105,7 @@ function parse($TEXT, exigent_mode) {
|
||||
var tok = S.token, ret;
|
||||
switch (tok.type) {
|
||||
case "name":
|
||||
return as_symbol();
|
||||
return as_symbol(AST_SymbolRef);
|
||||
case "num":
|
||||
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
|
||||
break;
|
||||
@@ -1198,8 +1204,8 @@ function parse($TEXT, exigent_mode) {
|
||||
if (name == "get") {
|
||||
a.push(new AST_ObjectGetter({
|
||||
start : start,
|
||||
name : name,
|
||||
func : function_(false),
|
||||
key : name,
|
||||
value : function_(false),
|
||||
end : prev()
|
||||
}));
|
||||
continue;
|
||||
@@ -1207,8 +1213,8 @@ function parse($TEXT, exigent_mode) {
|
||||
if (name == "set") {
|
||||
a.push(new AST_ObjectSetter({
|
||||
start : start,
|
||||
name : name,
|
||||
func : function_(false),
|
||||
key : name,
|
||||
value : function_(false),
|
||||
end : prev()
|
||||
}));
|
||||
continue;
|
||||
@@ -1252,10 +1258,13 @@ function parse($TEXT, exigent_mode) {
|
||||
}
|
||||
};
|
||||
|
||||
function as_symbol(def) {
|
||||
if (!is("name")) croak("Name expected");
|
||||
function as_symbol(type, noerror) {
|
||||
if (!is("name")) {
|
||||
if (!noerror) croak("Name expected");
|
||||
return null;
|
||||
}
|
||||
var name = S.token.value;
|
||||
var sym = new (name == "this" ? AST_This : def ? AST_Symbol : AST_SymbolRef)({
|
||||
var sym = new (name == "this" ? AST_This : type)({
|
||||
name : String(S.token.value),
|
||||
start : S.token,
|
||||
end : S.token
|
||||
|
||||
Reference in New Issue
Block a user