Latest changes

This commit is contained in:
rogerl%netscape.com 1999-05-07 22:07:22 +00:00
parent e554277ef1
commit 8cf3d6ffe7
8 changed files with 165 additions and 52 deletions

View File

@ -4,4 +4,19 @@ class ArithmeticNode extends BinaryNode {
{
super(aOp, aLeft, aRight);
}
void eval(Environment theEnv)
{
super.eval(theEnv);
double dR = theEnv.theStack.pop().d;
double dL = theEnv.theStack.pop().d;
if (op == "+")
theEnv.theStack.push(new StackValue(dL + dR));
else
if (op == "-")
theEnv.theStack.push(new StackValue(dL - dR));
else
System.out.println("missing arithmetic op " + op);
}
}

View File

@ -6,6 +6,12 @@ class BinaryNode extends ExpressionNode {
right = aRight;
op = aOp;
}
void eval(Environment theEnv)
{
left.eval(theEnv);
right.eval(theEnv);
}
String print(String indent)
{
@ -28,7 +34,7 @@ class BinaryNode extends ExpressionNode {
else
result.append(right.print(indent));
return result.toString();
}
}
protected ExpressionNode left;
protected ExpressionNode right;

View File

@ -6,8 +6,15 @@ class Brenda {
try {
JSLexer lexer = new JSLexer((args != null) ? new DataInputStream(new FileInputStream(args[0])) : new DataInputStream(System.in));
JSParser parser = new JSParser(lexer);
ControlNode tree = parser.statements(0);
ControlNodeGroup tree = parser.statements(0);
System.out.println(ControlNode.printAll());
Environment theEnv = new Environment();
ControlNode c = tree.getHead();
while (c != null) c = c.eval(theEnv);
System.out.println("After eval :\n" + theEnv.print());
} catch(Exception e) {
System.err.println("exception: "+e);
}

View File

@ -6,7 +6,17 @@ class ExpressionNode {
String print(String indent)
{
return indent + "ExpressionNode" + "\n";
return indent + "ExpressionNode(" + getClass().toString() + ")\n";
}
void evalLHS(Environment theEnv)
{
System.out.println("Unimplemented evalLHS for " + print(""));
}
void eval(Environment theEnv)
{
System.out.println("Unimplemented eval for " + print(""));
}
}

View File

@ -371,22 +371,22 @@ type_expression[boolean initial, boolean allowIn]
// ********* Statements **********
statement[int scope, boolean non_empty] returns [ControlNode c]
statement[int scope, boolean non_empty, ControlNodeGroup prev] returns [ControlNodeGroup c]
{ c = null; }
: c = code_statement[non_empty]
: c = code_statement[non_empty, prev]
| definition[scope]
;
code_statement[boolean non_empty] returns [ControlNode c]
code_statement[boolean non_empty, ControlNodeGroup prev] returns [ControlNodeGroup c]
{ c = null; }
: empty_statement[non_empty]
| (identifier ":") => labeled_statement[non_empty]
| c = expression_statement semicolon
| (identifier ":") => labeled_statement[non_empty, prev]
| c = expression_statement[prev] semicolon
| block[BlockScope]
| c = if_statement[non_empty]
| c = if_statement[non_empty, prev]
| switch_statement
| do_statement semicolon
| while_statement[non_empty]
| c = while_statement[non_empty, prev]
| for_statement[non_empty]
| with_statement[non_empty]
| continue_statement semicolon
@ -410,37 +410,65 @@ empty_statement[boolean non_empty]returns [ControlNode c]
;
// ********* Expression Statement **********
expression_statement returns [ControlNode c]
{ c = null; ExpressionNode e = null; }
: e = expression[true, true] { c = new ControlNode(e); }
expression_statement[ControlNodeGroup prev] returns [ControlNodeGroup c]
{ c = null; ControlNode t = null; ExpressionNode e = null; }
: e = expression[true, true]
{
t = new ControlNode(e);
if (prev == null) {
c = new ControlNodeGroup(t);
c.addTail(t);
}
else {
prev.fixTails(t);
prev.addTail(t);
c = prev;
}
}
;
// ********* Block **********
block[int scope] returns [ControlNode c]
block[int scope] returns [ControlNodeGroup c]
{ c = null; }
: "{" c = statements[scope] "}"
;
// FIXME
statements[int scope] returns [ControlNode c]
{ c = null; ControlNode t = null; ControlNode n = null; }
: c = statement[scope, false] { t = c; }
( n = statement[scope, false] { t.setNext(n); t = n; } )*
statements[int scope] returns [ControlNodeGroup c]
{ c = null; ControlNodeGroup c2 = null; }
: c = statement[scope, false, null]
( c = statement[scope, false, c] )*
;
// ********* Labeled Statements **********
labeled_statement[boolean non_empty]
: identifier ":" code_statement[non_empty]
labeled_statement[boolean non_empty, ControlNodeGroup prev]
: identifier ":" code_statement[non_empty, prev]
;
if_statement[boolean non_empty] returns [ConditionalNode c]
{ c = null; ControlNode t = null; ControlNode f = null; ExpressionNode e = null; }
: "if" e = parenthesized_expression t = code_statement[non_empty] { c = new ConditionalNode(e, t); }
(
// Standard if/else ambiguity
options { warnWhenFollowAmbig=false; }:
"else" t = code_statement[non_empty] { c.setFalse(t); }
)?
if_statement[boolean non_empty, ControlNodeGroup prev] returns [ControlNodeGroup c]
{ c = null; ControlNodeGroup c2 = null; ConditionalNode t = null; ExpressionNode e = null; }
: "if" e = parenthesized_expression c = code_statement[non_empty, null]
{
t = new ConditionalNode(e, c.getHead());
if (prev != null) {
prev.fixTails(t);
c.setHead(prev.getHead());
}
else
c.setHead(t);
c.addTail(t);
}
(
// Standard if/else ambiguity
options { warnWhenFollowAmbig=false; }:
"else" c2 = code_statement[non_empty, null]
{
t.setNext(c2.getHead());
c.removeTail(t);
c.addTails(c2);
}
)?
;
// ********* Switch statement **********
@ -453,7 +481,7 @@ case_groups
;
case_group
: (case_guard)+ (code_statement[true])+
: (case_guard)+ (code_statement[true, null])+
;
case_guard
@ -463,17 +491,18 @@ case_guard
// FIXME
case_statements
: (code_statement[false])+
: (code_statement[false, null])+
;
// ********* Do-While statement **********
do_statement
: "do" code_statement[true] "while" parenthesized_expression
: "do" code_statement[true, null] "while" parenthesized_expression
;
// ********* While statement **********
while_statement[boolean non_empty]
: "while" parenthesized_expression code_statement[non_empty]
while_statement[boolean non_empty, ControlNodeGroup prev] returns [ControlNodeGroup c]
{ c = null; }
: "while" parenthesized_expression code_statement[non_empty, null]
;
// ********* For statement **********
@ -484,7 +513,7 @@ for_statement[boolean non_empty]
| for_in_binding "in" expression[false, true]
)
")"
code_statement[non_empty]
code_statement[non_empty, null]
;
for_initializer
@ -503,7 +532,7 @@ for_in_binding
// ********* With statement **********
with_statement[boolean non_empty]
: "with" parenthesized_expression code_statement[non_empty]
: "with" parenthesized_expression code_statement[non_empty, null]
;
// ********* Continue and Break statement **********
@ -539,7 +568,7 @@ import_statement[boolean non_empty]
: "import" import_list
(
";"
| block[BlockScope] ("else" code_statement[non_empty])
| block[BlockScope] ("else" code_statement[non_empty, null])
)
;

View File

@ -4,22 +4,6 @@ import java.util.Stack;
class JSStack {
Stack stack = new Stack();
int frameTop;
void newFrame(StackValue returnAddress)
{
stack.push(returnAddress);
stack.push(new StackValue(frameTop));
frameTop = stack.size();
}
StackValue popFrame()
{
stack.setSize(frameTop);
StackValue oldFrame = (StackValue)(stack.pop());
frameTop = oldFrame.i;
return (StackValue)stack.pop();
}
void push(StackValue v)
{
@ -35,5 +19,10 @@ class JSStack {
{
return (StackValue)stack.pop();
}
int size()
{
return stack.size();
}
}

View File

@ -10,6 +10,37 @@ class JSValue extends ExpressionNode {
{
return indent + "JSValue " + type + " : " + value + "\n";
}
void evalLHS(Environment theEnv)
{
if (type == "object") {
// if (!theEnv.theGlobals.containsKey(value))
// theEnv.theGlobals.put(value, new Double(0.0));
theEnv.theStack.push(new StackValue(value));
}
else {
System.out.println("EvalLHS on non-object");
}
}
void eval(Environment theEnv)
{
if (type == "object") {
Double d = (Double)(theEnv.theGlobals.get(value));
if (d == null) {
System.out.println("Accessed undefined : " + value);
theEnv.theStack.push(new StackValue(0.0));
}
else
theEnv.theStack.push(new StackValue(d.doubleValue()));
}
else {
if (type == "number") {
Double d = new Double(value);
theEnv.theStack.push(new StackValue(d.doubleValue()));
}
}
}
String type;
String value;

View File

@ -4,4 +4,30 @@ class RelationalNode extends BinaryNode {
{
super(aOp, aLeft, aRight);
}
void eval(Environment theEnv)
{
super.eval(theEnv);
double dR = theEnv.theStack.pop().d;
double dL = theEnv.theStack.pop().d;
if (op == ">")
theEnv.theStack.push(new StackValue((dL > dR) ? 1 : 0));
else
if (op == ">=")
theEnv.theStack.push(new StackValue((dL >= dR) ? 1 : 0));
else
if (op == "<")
theEnv.theStack.push(new StackValue((dL < dR) ? 1 : 0));
else
if (op == "<=")
theEnv.theStack.push(new StackValue((dL <= dR) ? 1 : 0));
else
if (op == "==")
theEnv.theStack.push(new StackValue((dL == dR) ? 1 : 0));
else
if (op == "!=")
theEnv.theStack.push(new StackValue((dL != dR) ? 1 : 0));
else
System.out.println("missing relational op");
}
}