}, AST_Scope);
var AST_Accessor = DEFNODE("Accessor", null, {
- $documentation: "A setter/getter function"
+ $documentation: "A setter/getter function. The `name` property is always null."
}, AST_Lambda);
var AST_Function = DEFNODE("Function", null, {
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
$documentation: "Base class for literal object properties",
$propdoc: {
- key: "[string] the property name; it's always a plain string in our AST, no matter if it was a string, number or identifier in original code",
+ key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
value: "[AST_Node] property value. For setters and getters this is an AST_Function."
},
_walk: function(visitor) {
});
DEFPRINT(AST_ObjectSetter, function(self, output){
output.print("set");
+ output.space();
+ self.key.print(output);
self.value._do_print(output, true);
});
DEFPRINT(AST_ObjectGetter, function(self, output){
output.print("get");
+ output.space();
+ self.key.print(output);
self.value._do_print(output, true);
});
DEFPRINT(AST_Symbol, function(self, output){
return for_();
case "function":
- return function_(true);
+ return function_(AST_Defun);
case "if":
return if_();
});
};
- var function_ = function(in_statement, ctor) {
- var is_accessor = ctor === AST_Accessor;
- var name = (is("name") ? as_symbol(in_statement
- ? AST_SymbolDefun
- : is_accessor
- ? AST_SymbolAccessor
- : AST_SymbolLambda)
- : is_accessor && (is("string") || is("num")) ? as_atom_node()
- : null);
+ var function_ = function(ctor) {
+ var in_statement = ctor === AST_Defun;
+ var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
if (in_statement && !name)
unexpected();
expect("(");
- if (!ctor) ctor = in_statement ? AST_Defun : AST_Function;
return new ctor({
name: name,
argnames: (function(first, a){
var tok = S.token, ret;
switch (tok.type) {
case "name":
- return as_symbol(AST_SymbolRef);
+ case "keyword":
+ ret = _make_symbol(AST_SymbolRef);
+ break;
case "num":
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
break;
}
if (is("keyword", "function")) {
next();
- var func = function_(false);
+ var func = function_(AST_Function);
func.start = start;
func.end = prev();
return subscripts(func, allow_calls);
if (name == "get") {
a.push(new AST_ObjectGetter({
start : start,
- key : name,
- value : function_(false, AST_Accessor),
+ key : as_atom_node(),
+ value : function_(AST_Accessor),
end : prev()
}));
continue;
if (name == "set") {
a.push(new AST_ObjectSetter({
start : start,
- key : name,
- value : function_(false, AST_Accessor),
+ key : as_atom_node(),
+ value : function_(AST_Accessor),
end : prev()
}));
continue;
}
};
+ function _make_symbol(type) {
+ var name = S.token.value;
+ return new (name == "this" ? AST_This : type)({
+ name : String(name),
+ start : S.token,
+ end : S.token
+ });
+ };
+
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 : type)({
- name : String(S.token.value),
- start : S.token,
- end : S.token
- });
+ var sym = _make_symbol(type);
next();
return sym;
};