Function calling begun.

This commit is contained in:
rogerl%netscape.com 1999-06-11 00:21:26 +00:00
parent 720eb07f7f
commit 18b3c93221
8 changed files with 104 additions and 13 deletions

View File

@ -29,6 +29,12 @@ class BinaryNode extends ExpressionNode {
if (op == ".")
return lV.getProp(theEnv, rV.toJSString(theEnv));
else
if (op == "()")
return lV.call(theEnv, rV);
else
if (op == ",")
return JSValueList.buildList(lV, rV);
else {
System.out.println("missing binary op " + op);
return null;

View File

@ -33,7 +33,7 @@ class ControlNode {
ControlNode eval(Environment theEnv)
{
if (expr != null) expr.eval(theEnv);
if (expr != null) theEnv.resultValue = expr.eval(theEnv);
return next;
}

View File

@ -12,5 +12,6 @@ class Environment {
return result.toString();
}
JSValue resultValue;
}

View File

@ -0,0 +1,18 @@
class FunctionNode extends ExpressionNode {
FunctionNode(JSIdentifier aName, ControlNodeGroup aBody)
{
fn = new NativeFunction(aBody.getHead());
name = aName;
}
JSValue eval(Environment theEnv)
{
theEnv.scope.putProp(theEnv, name, fn);
return fn;
}
JSString name;
NativeFunction fn;
}

View File

@ -387,7 +387,7 @@ type_expression[boolean initial, boolean allowIn]
// ********* Statements **********
statement[int scope, boolean non_empty, ControlNodeGroup container]
: (definition[scope]) => definition[scope]
: (definition[scope, container]) => definition[scope, container]
| code_statement[non_empty, container, null]
;
@ -692,28 +692,29 @@ import_source
;
// ********* Definitions **********
definition[int scope]
: visibility global_definition
| local_definition[scope]
definition[int scope, ControlNodeGroup container]
: visibility global_definition[container]
| local_definition[scope, container]
;
global_definition
global_definition[ControlNodeGroup container]
{ ExpressionNode e = null; }
: version_definition semicolon
| variable_definition semicolon
// Syntactic predicate is required to disambiguate between getter/setter methods
// and getter/setter functions
| ("traditional" | "function" | (("getter" | "setter") "function")) => e = function_definition
| ("traditional" | "function" | (("getter" | "setter") "function"))
=> e = function_definition { container.add(new ControlNode(e)); }
| member_definition
| class_definition
;
local_definition[int scope]
local_definition[int scope, ControlNodeGroup container]
{ ExpressionNode e = null; }
: {scope == TopLevelScope || scope == ClassScope}? (class_definition | member_definition)
| variable_definition semicolon
| e = function_definition
| e = function_definition { container.add(new ControlNode(e)); }
;
// ********* Visibility Specifications **********
@ -780,7 +781,7 @@ function_definition returns [ExpressionNode e]
: e = named_function
| "getter" e = named_function
| "setter" e = named_function
| traditional_function
| e = traditional_function
;
anonymous_function returns [ExpressionNode e]
@ -838,9 +839,10 @@ result_signature
)?
;
traditional_function
{ ExpressionNode e = null; ControlNodeGroup c = new ControlNodeGroup(); }
: "traditional" "function" e = identifier "(" traditional_parameter_list ")" block[BlockScope, c]
traditional_function returns [ExpressionNode e]
{ e = null; JSIdentifier id = null; ControlNodeGroup c = new ControlNodeGroup(); }
: "traditional" "function" id = identifier "(" traditional_parameter_list ")" block[BlockScope, c]
{ e = new FunctionNode(id, c); }
;
traditional_parameter_list

View File

@ -151,6 +151,10 @@ class JSValue extends ExpressionNode {
return toJSObject(theEnv).putProp(theEnv, id, rV);
}
JSValue call(Environment theEnv, JSValue rV) {
throw new JSException(new JSString("[[call]] not implemented"));
}
JSValue defaultValue(Environment theEnv, String hint) {
/*
When the [[DefaultValue]] method of O is called with hint String, the following steps are taken:

View File

@ -0,0 +1,40 @@
import java.util.Vector;
class JSValueList extends JSValue {
static JSValueList buildList(JSValue left, JSValue right)
{
JSValueList theList;
if (left instanceof JSValueList) {
theList = (JSValueList)left;
theList.add(right);
}
else
if (right instanceof JSValueList) {
theList = (JSValueList)right;
theList.add(left);
}
else {
theList = new JSValueList();
theList.add(left);
theList.add(right);
}
return theList;
}
void add(JSValue v)
{
if (v instanceof JSValueList) {
JSValueList vl = (JSValueList)v;
for (int i = 0; i < vl.contents.size(); i++)
contents.addElement((JSValue)(vl.contents.elementAt(i)));
}
else
contents.addElement(v);
}
Vector contents = new Vector();
}

View File

@ -0,0 +1,20 @@
class NativeFunction extends JSObject {
NativeFunction(ControlNode aBody)
{
super("Function");
body = aBody;
}
JSValue call(Environment theEnv, JSValue rV)
{
ControlNode c = body;
while (c != null) c = c.eval(theEnv);
return theEnv.resultValue;
}
ControlNode body;
}