Changes to get traditional functions with args. working

This commit is contained in:
rogerl%netscape.com 1999-06-15 00:57:05 +00:00
parent 3c226bb451
commit c52c6e4113
10 changed files with 111 additions and 23 deletions

View File

@ -3,11 +3,19 @@ import java.util.Hashtable;
class Environment {
JSObject scope = new JSObject("globals", null);
JSScope scope = new JSScope("globals");
JSScope globalScope = scope;
void enterNewScope(JSObject newScope)
void enterNewScope(JSScope newScope)
{
newScope.parent = scope;
scope = newScope;
}
void leaveScope()
{
scope = scope.parent;
}
String print()

View File

@ -1,9 +1,27 @@
class FunctionNode extends ExpressionNode {
FunctionNode(JSIdentifier aName, ControlNodeGroup aBody)
FunctionNode(JSIdentifier aName, ControlNodeGroup aBody, ExpressionNode parameterList)
{
fn = new NativeFunction(aBody.getHead());
name = aName;
if (parameterList != null) {
if (parameterList instanceof BinaryNode)
buildParameterVector((BinaryNode)parameterList);
else
fn.parameters.addElement(parameterList);
}
}
void buildParameterVector(BinaryNode x)
{
if (x.left instanceof BinaryNode) {
buildParameterVector((BinaryNode)(x.left));
fn.parameters.addElement(x.right);
}
else {
fn.parameters.addElement(x.left);
fn.parameters.addElement(x.right);
}
}
JSValue eval(Environment theEnv)

View File

@ -81,15 +81,15 @@ primary_expression[boolean initial] returns [ExpressionNode e]
simple_expression returns [ExpressionNode e]
{ e = null; }
: "null" { e = new JSObject("null", null); } // XXX
: "null" { e = new JSObject("null"); }
| "true" { e = JSBoolean.JSTrue; }
| "false" { e = JSBoolean.JSFalse; }
| opN:NUMBER { e = new JSDouble(opN.getText()); }
| opS:STRING { e = new JSString(opS.getText()); }
| "this" { e = new JSObject("this", null); } // XXX
| "super" { e = new JSObject("super", null); } // XXX
| "this" { e = new JSObject("this"); }
| "super" { e = new JSObject("super"); }
| e = qualified_identifier_or_parenthesized_expression[true]
| opR:REGEXP { e = new JSObject(opR.getText(), null); } // XXX
| opR:REGEXP { e = new JSObject(opR.getText()); }
| e = array_literal
;
@ -841,12 +841,12 @@ result_signature
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" "function" id = identifier "(" e = traditional_parameter_list ")" block[BlockScope, c]
{ e = new FunctionNode(id, c, e); }
;
traditional_parameter_list
{ ExpressionNode e = null; ExpressionNode e2 = null; }
traditional_parameter_list returns [ExpressionNode e]
{ e = null; ExpressionNode e2 = null; }
: (e = identifier ("," e2 = identifier { e = new BinaryNode(",", e, e2); } )* )?
;

View File

@ -13,12 +13,26 @@ class JSName extends ExpressionNode {
JSReference evalLHS(Environment theEnv)
{
return new JSReference(theEnv.scope, id);
JSScope scope = theEnv.scope;
while (scope != null) {
if (scope.hasProp(theEnv, id))
return new JSReference(scope, id);
else
scope = scope.parent;
}
return new JSReference(theEnv.globalScope, id);
}
JSValue eval(Environment theEnv)
{
return theEnv.scope.getProp(theEnv, id);
JSScope scope = theEnv.scope;
while (scope != null) {
if (scope.hasProp(theEnv, id))
return scope.getProp(theEnv, id);
else
scope = scope.parent;
}
throw new JSException(new JSString(id.s + " undefined"));
}
JSIdentifier id;

View File

@ -3,21 +3,27 @@ import java.util.Hashtable;
class JSObject extends JSValue {
static JSObject JSUndefined = new JSObject("undefined", null);
static JSObject objectPrototype = new JSObject("Object");
static JSObject JSUndefined = new JSObject("undefined");
JSObject(String aValue, JSObject aPrototype)
JSObject(String aClass)
{
oClass = aClass;
prototype = objectPrototype;
}
void setPrototype(JSObject aPrototype)
{
value = aValue;
prototype = aPrototype;
}
String print(String indent)
{
return indent + "JSObject : " + value + "\n";
return indent + "JSObject : " + oClass + "\n";
}
public String toString() {
return value + contents.toString();
return oClass + contents.toString();
}
JSValue eval(Environment theEnv)
@ -52,6 +58,18 @@ class JSObject extends JSValue {
return (JSValue)v;
}
boolean hasProp(Environment theEnv, JSString id)
{
Object v = contents.get(id.s);
if (v == null)
if (prototype == null)
return false;
else
return prototype.hasProp(theEnv, id);
else
return true;
}
JSValue putProp(Environment theEnv, JSString id, JSValue rV) {
contents.put(id.s, rV);
return rV;
@ -60,7 +78,7 @@ class JSObject extends JSValue {
Hashtable contents = new Hashtable();
String value;
String oClass;
JSObject prototype;
}

10
js/js2/java/JSScope.java Normal file
View File

@ -0,0 +1,10 @@
class JSScope extends JSObject {
JSScope(String s)
{
super(s);
}
JSScope parent;
}

View File

@ -147,6 +147,10 @@ class JSValue extends ExpressionNode {
return toJSObject(theEnv).getProp(theEnv, id);
}
boolean hasProp(Environment theEnv, JSString id) {
return toJSObject(theEnv).hasProp(theEnv, id);
}
JSValue putProp(Environment theEnv, JSString id, JSValue rV) {
return toJSObject(theEnv).putProp(theEnv, id, rV);
}

View File

@ -1,19 +1,35 @@
import java.util.Vector;
class NativeFunction extends JSObject {
NativeFunction(ControlNode aBody)
{
super("Function", null);
super("Function");
body = aBody;
}
JSValue call(Environment theEnv, JSValue rV)
{
JSScope args = new JSScope("Arguments");
theEnv.enterNewScope(args);
for (int i = 0; i < parameters.size(); i++) {
if (rV instanceof JSValueList)
args.putProp(theEnv, (JSString)(parameters.elementAt(i)), (JSValue) ( ((JSValueList)rV).contents.elementAt(i)) );
else
args.putProp(theEnv, (JSString)(parameters.elementAt(i)), rV );
}
ControlNode c = body;
while (c != null) c = c.eval(theEnv);
theEnv.leaveScope();
return theEnv.resultValue;
}
ControlNode body;
Vector parameters = new Vector();
}

View File

@ -1,7 +1,7 @@
class NativeNumber extends JSObject {
NativeNumber(double p) {
super("Number", null);
super("Number");
d = p;
}

View File

@ -30,7 +30,7 @@ class TryNode extends ControlNode {
int count = catchExpr.size();
for (int i = 0; i < count; i++) {
ExpressionNode e = (ExpressionNode)(catchExpr.elementAt(i));
String id = ((JSObject)e).value;
String id = ((JSObject)e).oClass;
theEnv.scope.contents.put(id, x.getValue()); // XXX YAARGH !!!
return (ControlNode)(catchCode.elementAt(i));
}