First cut a xml code generation.

git-svn-id: svn://10.0.0.236/trunk@85591 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jeff.dyer%compilercompany.com
2001-01-26 23:55:32 +00:00
parent 358348e69f
commit 50228758c5
34 changed files with 2794 additions and 1394 deletions

View File

@@ -27,7 +27,11 @@ generator:
javac -d classes -classpath classes ../../src/java/generator/*.java
sanity:
java -classpath classes Main -d ../../test/sanity.js
java -classpath classes Main -a ../../test/sanity.js
testgen:
java -classpath classes Main -d ../../test/ecma-e4/02.expressions/primary.1.js
java -classpath classes Main -d ../../test/ecma-e4/06.functions/function.1.js
test:
java -classpath classes Main -d ../../test/ecma-e4/02.expressions/primary.1.js
@@ -49,3 +53,7 @@ test:
java -classpath classes Main -d ../../test/ecma-e4/03.statements/with.1.js
java -classpath classes Main -d ../../test/ecma-e4/04.definitions/definition.1.js
java -classpath classes Main -d ../../test/ecma-e4/04.definitions/definition.2.js
test_functions:
java -classpath classes Main -debug -asm ../../test/ecma-e4/06.functions/function.1.js

View File

@@ -1,14 +1,13 @@
J S C R E A D M E F I L E
Jeff Dyer, Mountain View Compiler Company
Dec-15-2000
Jan-26-2001
OVERVIEW
JSC (JavaScript Compiler) is a stand-alone front-end implementation
of the JS2 language specification. Its purpose is to demonstrate how
JS2 programs are statically prepared for execution by a JS2 interpreter.
Its output is a psuedo intermediate language suitable for reading by
human beings.
Its output is assembly code that is assembled by the JS engine.
BUILDING JSC
@@ -31,7 +30,7 @@ utility, such as:
If all goes well, the sanity test will run and you will see something
like
../../test/sanity.js: 0 errors [120 msec] --> completion( 0, okay, null )
../../test/sanity.js: 0 errors [120 msec]
on the last line of the console output. To run more extensive tests,
use the build command:
@@ -61,22 +60,15 @@ produce a new file given the name of the original source file
with the suffix '.jsil' appended to it. Errors are written to a
file with the suffix '.err' appended to it.
STATUS OF JSC
Dec-1-2000
----------
Signficant portions of the type system, compile-time constant evaluator,
and name management systems are working. Missing are semantics for
using, import, export, and unit parsing. More tests are also needed.
ISSUES
* Intermediate form of references, classes, and interfaces.
CHANGES
Jan-26-2001
-----------
Added first cut at xml icode generation. In particular function definitions,
call and binary expressions are implemented. Object and array literals are
also implemented. Many of the tests used for verifying the parser and semantic
analyzer, are not yet working.
Dec-15-2000
-----------
Removed dependency on sun.tools packages.

File diff suppressed because it is too large Load Diff

View File

@@ -47,6 +47,7 @@ public class Main {
private static boolean traceInput = false;
private static boolean traceLexer = false;
private static boolean traceParser = false;
private static boolean doASM = false;
private static boolean debug = false;
@@ -67,6 +68,8 @@ public class Main {
traceParser = true;
} else if (args[i].equals("-d")||args[i].equals("-debug")) {
debug = true;
} else if (args[i].equals("-a")||args[i].equals("-asm")) {
doASM = true;
} else if (args[i].charAt(0) == '-') {
System.out.println("Unknown.option "+ args[i]);
} else {
@@ -148,7 +151,7 @@ public class Main {
if( traceParser ) {
Debugger.trace("setting parser output to " + input[i]);
JSILGenerator.setOut( input[i]+".par" );
node.evaluate(context,new JSILGenerator());
node.evaluate(context,new JSILGenerator(false));
}
//Evaluator evaluator;
@@ -157,14 +160,14 @@ public class Main {
context.setEvaluator(new BlockEvaluator());
node.evaluate(context, context.getEvaluator());
JSILGenerator.setOut( input[i]+".blocks" );
context.setEvaluator(new JSILGenerator());
node.evaluate(context, context.getEvaluator());
//JSILGenerator.setOut( input[i]+".blocks" );
//context.setEvaluator(new JSILGenerator(false));
//node.evaluate(context, context.getEvaluator());
context.setEvaluator(new ConstantEvaluator());
value = node.evaluate(context, context.getEvaluator());
context.setEvaluator(new JSILGenerator());
context.setEvaluator(new JSILGenerator(doASM));
JSILGenerator.setOut( input[i]+".jsil" );
node.evaluate(context, context.getEvaluator());
errorCount = context.errorCount();
@@ -172,7 +175,7 @@ public class Main {
t = System.currentTimeMillis() - t;
//Debugger.trace(""+global);
System.out.println(input[i] + ": "+ errorCount +" errors [" + Long.toString(t) + " msec] --> " + value.getValue(context) );
System.out.println(input[i] + ": "+ errorCount +" errors [" + Long.toString(t) + " msec]");
} catch( Exception x ) {
x.printStackTrace();

View File

@@ -32,6 +32,7 @@ public class Node {
Block block;
int position;
Store store;
public Node() {
}

View File

@@ -102,9 +102,6 @@ public final class NodeFactory {
static SuperExpressionNode SuperExpression() {
return new SuperExpressionNode();
}
static EvalExpressionNode EvalExpression( Node expr ) {
return new EvalExpressionNode(expr);
}
static ListNode List( Node list, Node item ) {
return new ListNode(list,item,item.pos());
}

View File

@@ -86,6 +86,7 @@ final class AssignmentExpressionNode extends Node implements Tokens {
Node lhs, rhs;
int op;
/*Reference*/Value ref;
AssignmentExpressionNode( Node lhs, int op, Node rhs ) {
this.lhs = lhs;
@@ -139,6 +140,8 @@ final class BinaryExpressionNode extends Node {
protected Node lhs, rhs;
protected int op;
Value lhs_ref,rhs_ref;
Slot lhs_slot,rhs_slot;
BinaryExpressionNode( int op, Node lhs, Node rhs ) {
this.op = op;
@@ -331,6 +334,7 @@ final class ClassofExpressionNode extends Node {
final class CoersionExpressionNode extends Node {
Node expr, type;
String typename;
CoersionExpressionNode( Node expr, Node type, int pos ) {
super(pos);
@@ -427,11 +431,11 @@ final class DoStatementNode extends Node {
final class ElementListNode extends Node {
Node list, expr;
Node list, item;
ElementListNode( Node list, Node expr ) {
ElementListNode( Node list, Node item ) {
this.list = list;
this.expr = expr;
this.item = item;
}
public Value evaluate( Context context, Evaluator evaluator ) throws Exception {
@@ -439,7 +443,7 @@ final class ElementListNode extends Node {
}
public String toString() {
return "elementlist( " + list + ", " + expr + " )";
return "elementlist( " + list + ", " + item + " )";
}
}
@@ -479,27 +483,6 @@ final class ExpressionStatementNode extends Node {
}
}
/**
* EvalExpressionNode
*/
final class EvalExpressionNode extends Node {
Node expr;
EvalExpressionNode( Node expr ) {
this.expr = expr;
}
public Value evaluate( Context context, Evaluator evaluator ) throws Exception {
return evaluator.evaluate( context, this );
}
public String toString() {
return "evalexpression( " + expr + " )";
}
}
/**
* ExportBindingNode
*/
@@ -726,6 +709,7 @@ final class FunctionDeclarationNode extends Node {
Node name, signature;
Slot slot;
/*Reference*/Value ref;
FunctionDeclarationNode( Node name, Node signature ) {
this.name = name;
@@ -748,6 +732,7 @@ final class FunctionDeclarationNode extends Node {
final class FunctionDefinitionNode extends Node {
Node decl, body;
int fixedCount;
FunctionDefinitionNode( Node decl, Node body ) {
this.decl = decl;
@@ -782,7 +767,7 @@ final class FunctionNameNode extends Node {
FunctionNameNode( int kind, Node name ) {
this.kind = kind;
this.name = name;
this.name = (IdentifierNode)name;
}
public Value evaluate( Context context, Evaluator evaluator ) throws Exception {
@@ -802,6 +787,7 @@ final class FunctionSignatureNode extends Node {
Node parameter, result;
Slot slot;
Value ref;
FunctionSignatureNode( Node parameter, Node result ) {
this.parameter = parameter;
@@ -824,6 +810,7 @@ final class FunctionSignatureNode extends Node {
class IdentifierNode extends Node {
String name;
/*Reference*/Value ref;
IdentifierNode( String name, int pos ) {
super(pos);
@@ -1128,6 +1115,7 @@ final class ListNode extends Node {
final class LiteralArrayNode extends Node {
Node elementlist;
/*List*/Value value;
LiteralArrayNode( Node elementlist ) {
this.elementlist = elementlist;
@@ -1171,6 +1159,7 @@ final class LiteralFieldNode extends Node {
Node name;
Node value;
/*Reference*/Value ref;
LiteralFieldNode( Node name, Node value ) {
this.name = name;
@@ -1232,6 +1221,7 @@ final class LiteralNumberNode extends Node {
final class LiteralObjectNode extends Node {
Node fieldlist;
/*Object*/Value value;
LiteralObjectNode( Node fieldlist ) {
this.fieldlist = fieldlist;
@@ -1334,6 +1324,7 @@ final class LiteralUndefinedNode extends Node {
final class MemberExpressionNode extends Node {
Node base, name;
/*Reference*/Value ref;
MemberExpressionNode( Node base, Node name, int pos ) {
super(pos);
@@ -1474,6 +1465,7 @@ final class ParameterNode extends Node {
Node identifier;
Node type;
Slot slot;
String name;
ParameterNode( Node identifier, Node type ) {
this.identifier = identifier;

View File

@@ -31,9 +31,10 @@ public class Slot {
Value type;
Value value;
Block block;
Store store;
public String toString() {
return "{ "+attrs+", "+type+", "+value+" }";
return "{ "+attrs+", "+type+", "+value+", "+store+" }";
}
}

View File

@@ -0,0 +1,45 @@
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mountain View Compiler
* Company. Portions created by Mountain View Compiler Company are
* Copyright (C) 1998-2000 Mountain View Compiler Company. All
* Rights Reserved.
*
* Contributor(s):
* Jeff Dyer <jeff@compilercompany.com>
*/
package com.compilercompany.ecmascript;
/**
* Represents an abstract unit of storage.
*/
public class Store {
Scope scope;
int index;
Store(Scope scope, int index) {
this.scope = scope;
this.index = index;
}
public String toString() {
return "store( " + index + " )";
}
}
/*
* The end.
*/

View File

@@ -95,6 +95,10 @@ abstract public class Value implements Scope {
*/
}
int size() {
return 0;
}
public Value construct(Context context, Value args) throws Exception {
throw new Exception("Constructor object expected in new expression");
}

View File

@@ -44,6 +44,10 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
/**
* IdentifierNode
*
* The reference value serves as a weak alias to the object being
* bound to. It is interpreted by its context (e.g. a member expr
* as a selector for a member of the base activation frame.
*/
Value evaluate( Context context, IdentifierNode node ) throws Exception {
@@ -304,7 +308,7 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace("evaluating LiteralObjectNode = " + node);
}
Value value;
ObjectValue value;
Type type;
type = new ObjectType("");
@@ -316,6 +320,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
context.popScope();
}
node.value = value; // save it for code generation.
return value;
}
@@ -376,17 +382,19 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace("evaluating LiteralArrayNode = " + node);
}
Value value;
ListValue value;
Type type;
type = ArrayType.type;
if( node.elementlist != null ) {
value = node.elementlist.evaluate(context,this);
value = (ListValue)node.elementlist.evaluate(context,this);
} else {
value = NullValue.nullValue;
value = null;
}
node.value = value; // save for code generation.
return type.convert(context,value);
}
@@ -407,6 +415,41 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
testEvaluator("ArrayLiteral",input,expected);
}
/**
* ElementListNode
*/
Value evaluate( Context context, ElementListNode node ) throws Exception {
if( debug ) {
Debugger.trace("evaluating ElementListNode = " + node);
}
ListValue list;
if( node.list != null ) {
if( node.list instanceof ListNode ) {
list = (ListValue) node.list.evaluate(context,this);
} else {
list = new ListValue();
list.push(node.list.evaluate(context,this));
}
}
else {
list = new ListValue();
}
if( node.item != null ) {
list.push(node.item.evaluate(context,this));
}
else {
// do nothing.
}
return list;
}
/**
* PostfixExpressionNode
*
@@ -492,6 +535,10 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
* MemberExpressionNode
*
* { base:NewSubexpressionNode name:IdentifierNode }
*
* A member expression evaluates to a reference value. If the value of the
* reference is a compile-time constant, then return the value as a literal.
* Otherwise return undefined.
*/
Value evaluate( Context context, MemberExpressionNode node ) throws Exception {
@@ -502,17 +549,18 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Value value;
Value base;
ReferenceValue ref;
String name;
base = node.base.evaluate(context,this).getValue(context);
value = node.name.evaluate(context,this);
if( value instanceof ReferenceValue ) {
ref = (ReferenceValue) value;
ref.scope = base;
if( !UndefinedType.type.includes(base) &&
value instanceof ReferenceValue ) {
((ReferenceValue)value).scope = base;
node.ref = value;
} else {
error(context,0,"Expecting reference expression after dot operator.",node.name.pos());
value = UndefinedValue.undefinedValue;
//error(context,0,"Expecting reference expression after dot operator.",node.name.pos());
}
return value;
@@ -665,7 +713,7 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
callee = node.member.evaluate(context,this).getValue(context);
if( node.args != null ) {
args = node.args.evaluate(context,this);
args = node.args.evaluate(context,this);
}
if( !FunctionType.type.includes(callee) ) {
@@ -704,6 +752,27 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
if( debug ) {
Debugger.trace("evaluating BinaryExpressionNode = " + node);
}
// if rhs is a constant, then replace with a literal.
// if it is a local definition, then load it directly.
// otherwise, put result in temporary and use it directly.
Value value;
value = node.lhs.evaluate(context,this);
if( value instanceof ReferenceValue ) {
node.lhs = null;
node.lhs_ref = value;
node.lhs_slot = ((ReferenceValue)value).getSlot(context);
}
value = node.rhs.evaluate(context,this);
if( value instanceof ReferenceValue ) {
node.rhs = null;
node.rhs_ref = value;
node.rhs_slot = ((ReferenceValue)value).getSlot(context);
}
return UndefinedValue.undefinedValue;
}
@@ -735,11 +804,14 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Value value = UndefinedValue.undefinedValue;
if( lref != UndefinedValue.undefinedValue ) {
Slot slot = ((ReferenceValue)lref).getSlot(context);
Debugger.trace("slot " + slot);
Debugger.trace("ConstantEvaluator.evaluat(AssignmentExpression) with slot " + slot);
if( slot != null ) {
Value rref = node.rhs.evaluate(context,this);
slot.value = rref.getValue(context);
}
node.ref = (ReferenceValue)lref;
} else {
throw new Exception("internal error: assignment lhs is not a reference.");
}
return value;
@@ -1079,6 +1151,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace("evaluating ReturnStatementNode = " + node);
}
node.expr.evaluate(context,this);
return new CodeValue(node);
}
@@ -1208,7 +1282,7 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
static {
try {
namespace_parameters = new ObjectValue(new NamespaceType("_parameters_"));
namespace_parameters = new ObjectValue(new TypeValue(new NamespaceType("_parameters_")));
} catch ( Exception x ) {
x.printStackTrace();
Debugger.trace("oops, something is not right.");
@@ -1577,12 +1651,17 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
* 2. Save result in code slot.
*/
private int local_offset;
public Value evaluate( Context context, FunctionDefinitionNode node ) throws Exception {
if( debug ) {
Debugger.trace( "evaluating FunctionDefinitionNode: " + node );
}
local_offset = 0; // start a new activation frame.
used_namespaces.addElement(namespace_parameters);
Value value = node.decl.evaluate(context,this);
if( node.body!=null) {
@@ -1595,6 +1674,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
context.popScope();
}
node.fixedCount = local_offset;
return UndefinedValue.undefinedValue;
}
@@ -1633,7 +1714,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace( "evaluating FunctionDeclarationNode: " + node );
}
ReferenceValue ref = (ReferenceValue) node.name.evaluate(context,this);
ReferenceValue ref;
node.ref = ref = (ReferenceValue) node.name.evaluate(context,this);
String name = ref.getName();
ref.scope = context.getLocal();
@@ -1747,20 +1829,21 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Scope local = context.getLocal();
node.slot = local.add(namespace_parameters,"_result_");
Value result;
Value type;
if( node.result!=null ) {
result = node.result.evaluate(context,this).getValue(context);
node.ref = node.result.evaluate(context,this);
type = node.ref.getValue(context);
} else {
result = ObjectType.type;
type = ObjectType.type;
}
if( !TypeType.type.includes(result) ) {
error(context,"Result type expression does not evaluate to a type. result = " + result.type,node.pos());
if( !TypeType.type.includes(type) ) {
error(context,"Result type expression does not evaluate to a type. result = " + type.type,node.pos());
}
node.slot.type = (TypeValue) result;
node.slot.type = type;
return result;
return type;
}
/**
@@ -1783,8 +1866,9 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
ref = (ReferenceValue) node.identifier.evaluate(context,this);
name = ref.getName();
node.slot = local.add(namespace_parameters,name);
//node.identifier.slot.block = context.getBlock();
node.slot = local.add(namespace_parameters,name);
node.slot.store = new Store(local,local_offset++);
node.name = name; // for code generation.
return ref;
}
@@ -2338,6 +2422,7 @@ class Flow {
}
return preds;
}
}
/*

View File

@@ -176,6 +176,14 @@ public class ObjectValue extends Value implements Attributes, Scope {
return slot;
}
/**
*
*/
int size() {
return slots.size();
}
/**
*
*/

View File

@@ -45,7 +45,7 @@ public class ReferenceValue extends Value {
if( debug ) {
Debugger.trace( "creating reference scope = " + scope +
" name = " + name + " namespaces = " + namespaces );
" name = " + name + " used_namespaces = " + namespaces );
}
this.scope = scope;
@@ -91,6 +91,10 @@ public class ReferenceValue extends Value {
break;
}
}
if( slot==null ) {
slot = scope.get(qualifier/*=null*/,name);
}
}
if( debug ) {
Debugger.trace("leaving getSlotInScope() with slot="+slot);

View File

@@ -60,5 +60,6 @@ function run() {
}
/*
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
* Copyright (c) 1999-2001, Mountain View Compiler Company.
* All rights reserved.
*/

View File

@@ -7,17 +7,18 @@ function title() {
}
function run() {
a.b::c.d[e](f,g)[h].i++;
//a.b::c.d[e](f,g)[h].i++;
delete p;
void 0;
typeof ob;
++a.b--;
--a.b++;
//++a.b--;
//--a.b++;
+a;
-a;
!a;
}
/*
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
* Copyright (c) 1999-2001, Mountain View Compiler Company.
* All rights reserved.
*/

View File

@@ -32,5 +32,5 @@ unit const liter = makeLiter;
showerrors unit const liter = Unit.dm.pow(3);
/*
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
* Copyright (c) 1999-2001, Mountain View Compiler Company. All rights reserved.
*/

View File

@@ -2,18 +2,19 @@
* Sanity test.
*/
const result = 'okay';
function title() {
return "sanity";
}
function run() {
function g(a,b) {
return a+b;
}
result;
function run() {
return g(1,2);
}
/**
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
/*
* Copyright (c) 1999-2001, Mountain View Compiler Company.
* All rights reserved.
*/

View File

@@ -27,7 +27,11 @@ generator:
javac -d classes -classpath classes ../../src/java/generator/*.java
sanity:
java -classpath classes Main -d ../../test/sanity.js
java -classpath classes Main -a ../../test/sanity.js
testgen:
java -classpath classes Main -d ../../test/ecma-e4/02.expressions/primary.1.js
java -classpath classes Main -d ../../test/ecma-e4/06.functions/function.1.js
test:
java -classpath classes Main -d ../../test/ecma-e4/02.expressions/primary.1.js
@@ -49,3 +53,7 @@ test:
java -classpath classes Main -d ../../test/ecma-e4/03.statements/with.1.js
java -classpath classes Main -d ../../test/ecma-e4/04.definitions/definition.1.js
java -classpath classes Main -d ../../test/ecma-e4/04.definitions/definition.2.js
test_functions:
java -classpath classes Main -debug -asm ../../test/ecma-e4/06.functions/function.1.js

View File

@@ -1,14 +1,13 @@
J S C R E A D M E F I L E
Jeff Dyer, Mountain View Compiler Company
Dec-15-2000
Jan-26-2001
OVERVIEW
JSC (JavaScript Compiler) is a stand-alone front-end implementation
of the JS2 language specification. Its purpose is to demonstrate how
JS2 programs are statically prepared for execution by a JS2 interpreter.
Its output is a psuedo intermediate language suitable for reading by
human beings.
Its output is assembly code that is assembled by the JS engine.
BUILDING JSC
@@ -31,7 +30,7 @@ utility, such as:
If all goes well, the sanity test will run and you will see something
like
../../test/sanity.js: 0 errors [120 msec] --> completion( 0, okay, null )
../../test/sanity.js: 0 errors [120 msec]
on the last line of the console output. To run more extensive tests,
use the build command:
@@ -61,22 +60,15 @@ produce a new file given the name of the original source file
with the suffix '.jsil' appended to it. Errors are written to a
file with the suffix '.err' appended to it.
STATUS OF JSC
Dec-1-2000
----------
Signficant portions of the type system, compile-time constant evaluator,
and name management systems are working. Missing are semantics for
using, import, export, and unit parsing. More tests are also needed.
ISSUES
* Intermediate form of references, classes, and interfaces.
CHANGES
Jan-26-2001
-----------
Added first cut at xml icode generation. In particular function definitions,
call and binary expressions are implemented. Object and array literals are
also implemented. Many of the tests used for verifying the parser and semantic
analyzer, are not yet working.
Dec-15-2000
-----------
Removed dependency on sun.tools packages.

File diff suppressed because it is too large Load Diff

View File

@@ -47,6 +47,7 @@ public class Main {
private static boolean traceInput = false;
private static boolean traceLexer = false;
private static boolean traceParser = false;
private static boolean doASM = false;
private static boolean debug = false;
@@ -67,6 +68,8 @@ public class Main {
traceParser = true;
} else if (args[i].equals("-d")||args[i].equals("-debug")) {
debug = true;
} else if (args[i].equals("-a")||args[i].equals("-asm")) {
doASM = true;
} else if (args[i].charAt(0) == '-') {
System.out.println("Unknown.option "+ args[i]);
} else {
@@ -148,7 +151,7 @@ public class Main {
if( traceParser ) {
Debugger.trace("setting parser output to " + input[i]);
JSILGenerator.setOut( input[i]+".par" );
node.evaluate(context,new JSILGenerator());
node.evaluate(context,new JSILGenerator(false));
}
//Evaluator evaluator;
@@ -157,14 +160,14 @@ public class Main {
context.setEvaluator(new BlockEvaluator());
node.evaluate(context, context.getEvaluator());
JSILGenerator.setOut( input[i]+".blocks" );
context.setEvaluator(new JSILGenerator());
node.evaluate(context, context.getEvaluator());
//JSILGenerator.setOut( input[i]+".blocks" );
//context.setEvaluator(new JSILGenerator(false));
//node.evaluate(context, context.getEvaluator());
context.setEvaluator(new ConstantEvaluator());
value = node.evaluate(context, context.getEvaluator());
context.setEvaluator(new JSILGenerator());
context.setEvaluator(new JSILGenerator(doASM));
JSILGenerator.setOut( input[i]+".jsil" );
node.evaluate(context, context.getEvaluator());
errorCount = context.errorCount();
@@ -172,7 +175,7 @@ public class Main {
t = System.currentTimeMillis() - t;
//Debugger.trace(""+global);
System.out.println(input[i] + ": "+ errorCount +" errors [" + Long.toString(t) + " msec] --> " + value.getValue(context) );
System.out.println(input[i] + ": "+ errorCount +" errors [" + Long.toString(t) + " msec]");
} catch( Exception x ) {
x.printStackTrace();

View File

@@ -32,6 +32,7 @@ public class Node {
Block block;
int position;
Store store;
public Node() {
}

View File

@@ -102,9 +102,6 @@ public final class NodeFactory {
static SuperExpressionNode SuperExpression() {
return new SuperExpressionNode();
}
static EvalExpressionNode EvalExpression( Node expr ) {
return new EvalExpressionNode(expr);
}
static ListNode List( Node list, Node item ) {
return new ListNode(list,item,item.pos());
}

View File

@@ -86,6 +86,7 @@ final class AssignmentExpressionNode extends Node implements Tokens {
Node lhs, rhs;
int op;
/*Reference*/Value ref;
AssignmentExpressionNode( Node lhs, int op, Node rhs ) {
this.lhs = lhs;
@@ -139,6 +140,8 @@ final class BinaryExpressionNode extends Node {
protected Node lhs, rhs;
protected int op;
Value lhs_ref,rhs_ref;
Slot lhs_slot,rhs_slot;
BinaryExpressionNode( int op, Node lhs, Node rhs ) {
this.op = op;
@@ -331,6 +334,7 @@ final class ClassofExpressionNode extends Node {
final class CoersionExpressionNode extends Node {
Node expr, type;
String typename;
CoersionExpressionNode( Node expr, Node type, int pos ) {
super(pos);
@@ -427,11 +431,11 @@ final class DoStatementNode extends Node {
final class ElementListNode extends Node {
Node list, expr;
Node list, item;
ElementListNode( Node list, Node expr ) {
ElementListNode( Node list, Node item ) {
this.list = list;
this.expr = expr;
this.item = item;
}
public Value evaluate( Context context, Evaluator evaluator ) throws Exception {
@@ -439,7 +443,7 @@ final class ElementListNode extends Node {
}
public String toString() {
return "elementlist( " + list + ", " + expr + " )";
return "elementlist( " + list + ", " + item + " )";
}
}
@@ -479,27 +483,6 @@ final class ExpressionStatementNode extends Node {
}
}
/**
* EvalExpressionNode
*/
final class EvalExpressionNode extends Node {
Node expr;
EvalExpressionNode( Node expr ) {
this.expr = expr;
}
public Value evaluate( Context context, Evaluator evaluator ) throws Exception {
return evaluator.evaluate( context, this );
}
public String toString() {
return "evalexpression( " + expr + " )";
}
}
/**
* ExportBindingNode
*/
@@ -726,6 +709,7 @@ final class FunctionDeclarationNode extends Node {
Node name, signature;
Slot slot;
/*Reference*/Value ref;
FunctionDeclarationNode( Node name, Node signature ) {
this.name = name;
@@ -748,6 +732,7 @@ final class FunctionDeclarationNode extends Node {
final class FunctionDefinitionNode extends Node {
Node decl, body;
int fixedCount;
FunctionDefinitionNode( Node decl, Node body ) {
this.decl = decl;
@@ -782,7 +767,7 @@ final class FunctionNameNode extends Node {
FunctionNameNode( int kind, Node name ) {
this.kind = kind;
this.name = name;
this.name = (IdentifierNode)name;
}
public Value evaluate( Context context, Evaluator evaluator ) throws Exception {
@@ -802,6 +787,7 @@ final class FunctionSignatureNode extends Node {
Node parameter, result;
Slot slot;
Value ref;
FunctionSignatureNode( Node parameter, Node result ) {
this.parameter = parameter;
@@ -824,6 +810,7 @@ final class FunctionSignatureNode extends Node {
class IdentifierNode extends Node {
String name;
/*Reference*/Value ref;
IdentifierNode( String name, int pos ) {
super(pos);
@@ -1128,6 +1115,7 @@ final class ListNode extends Node {
final class LiteralArrayNode extends Node {
Node elementlist;
/*List*/Value value;
LiteralArrayNode( Node elementlist ) {
this.elementlist = elementlist;
@@ -1171,6 +1159,7 @@ final class LiteralFieldNode extends Node {
Node name;
Node value;
/*Reference*/Value ref;
LiteralFieldNode( Node name, Node value ) {
this.name = name;
@@ -1232,6 +1221,7 @@ final class LiteralNumberNode extends Node {
final class LiteralObjectNode extends Node {
Node fieldlist;
/*Object*/Value value;
LiteralObjectNode( Node fieldlist ) {
this.fieldlist = fieldlist;
@@ -1334,6 +1324,7 @@ final class LiteralUndefinedNode extends Node {
final class MemberExpressionNode extends Node {
Node base, name;
/*Reference*/Value ref;
MemberExpressionNode( Node base, Node name, int pos ) {
super(pos);
@@ -1474,6 +1465,7 @@ final class ParameterNode extends Node {
Node identifier;
Node type;
Slot slot;
String name;
ParameterNode( Node identifier, Node type ) {
this.identifier = identifier;

View File

@@ -31,9 +31,10 @@ public class Slot {
Value type;
Value value;
Block block;
Store store;
public String toString() {
return "{ "+attrs+", "+type+", "+value+" }";
return "{ "+attrs+", "+type+", "+value+", "+store+" }";
}
}

View File

@@ -0,0 +1,45 @@
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mountain View Compiler
* Company. Portions created by Mountain View Compiler Company are
* Copyright (C) 1998-2000 Mountain View Compiler Company. All
* Rights Reserved.
*
* Contributor(s):
* Jeff Dyer <jeff@compilercompany.com>
*/
package com.compilercompany.ecmascript;
/**
* Represents an abstract unit of storage.
*/
public class Store {
Scope scope;
int index;
Store(Scope scope, int index) {
this.scope = scope;
this.index = index;
}
public String toString() {
return "store( " + index + " )";
}
}
/*
* The end.
*/

View File

@@ -95,6 +95,10 @@ abstract public class Value implements Scope {
*/
}
int size() {
return 0;
}
public Value construct(Context context, Value args) throws Exception {
throw new Exception("Constructor object expected in new expression");
}

View File

@@ -44,6 +44,10 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
/**
* IdentifierNode
*
* The reference value serves as a weak alias to the object being
* bound to. It is interpreted by its context (e.g. a member expr
* as a selector for a member of the base activation frame.
*/
Value evaluate( Context context, IdentifierNode node ) throws Exception {
@@ -304,7 +308,7 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace("evaluating LiteralObjectNode = " + node);
}
Value value;
ObjectValue value;
Type type;
type = new ObjectType("");
@@ -316,6 +320,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
context.popScope();
}
node.value = value; // save it for code generation.
return value;
}
@@ -376,17 +382,19 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace("evaluating LiteralArrayNode = " + node);
}
Value value;
ListValue value;
Type type;
type = ArrayType.type;
if( node.elementlist != null ) {
value = node.elementlist.evaluate(context,this);
value = (ListValue)node.elementlist.evaluate(context,this);
} else {
value = NullValue.nullValue;
value = null;
}
node.value = value; // save for code generation.
return type.convert(context,value);
}
@@ -407,6 +415,41 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
testEvaluator("ArrayLiteral",input,expected);
}
/**
* ElementListNode
*/
Value evaluate( Context context, ElementListNode node ) throws Exception {
if( debug ) {
Debugger.trace("evaluating ElementListNode = " + node);
}
ListValue list;
if( node.list != null ) {
if( node.list instanceof ListNode ) {
list = (ListValue) node.list.evaluate(context,this);
} else {
list = new ListValue();
list.push(node.list.evaluate(context,this));
}
}
else {
list = new ListValue();
}
if( node.item != null ) {
list.push(node.item.evaluate(context,this));
}
else {
// do nothing.
}
return list;
}
/**
* PostfixExpressionNode
*
@@ -492,6 +535,10 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
* MemberExpressionNode
*
* { base:NewSubexpressionNode name:IdentifierNode }
*
* A member expression evaluates to a reference value. If the value of the
* reference is a compile-time constant, then return the value as a literal.
* Otherwise return undefined.
*/
Value evaluate( Context context, MemberExpressionNode node ) throws Exception {
@@ -502,17 +549,18 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Value value;
Value base;
ReferenceValue ref;
String name;
base = node.base.evaluate(context,this).getValue(context);
value = node.name.evaluate(context,this);
if( value instanceof ReferenceValue ) {
ref = (ReferenceValue) value;
ref.scope = base;
if( !UndefinedType.type.includes(base) &&
value instanceof ReferenceValue ) {
((ReferenceValue)value).scope = base;
node.ref = value;
} else {
error(context,0,"Expecting reference expression after dot operator.",node.name.pos());
value = UndefinedValue.undefinedValue;
//error(context,0,"Expecting reference expression after dot operator.",node.name.pos());
}
return value;
@@ -665,7 +713,7 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
callee = node.member.evaluate(context,this).getValue(context);
if( node.args != null ) {
args = node.args.evaluate(context,this);
args = node.args.evaluate(context,this);
}
if( !FunctionType.type.includes(callee) ) {
@@ -704,6 +752,27 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
if( debug ) {
Debugger.trace("evaluating BinaryExpressionNode = " + node);
}
// if rhs is a constant, then replace with a literal.
// if it is a local definition, then load it directly.
// otherwise, put result in temporary and use it directly.
Value value;
value = node.lhs.evaluate(context,this);
if( value instanceof ReferenceValue ) {
node.lhs = null;
node.lhs_ref = value;
node.lhs_slot = ((ReferenceValue)value).getSlot(context);
}
value = node.rhs.evaluate(context,this);
if( value instanceof ReferenceValue ) {
node.rhs = null;
node.rhs_ref = value;
node.rhs_slot = ((ReferenceValue)value).getSlot(context);
}
return UndefinedValue.undefinedValue;
}
@@ -735,11 +804,14 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Value value = UndefinedValue.undefinedValue;
if( lref != UndefinedValue.undefinedValue ) {
Slot slot = ((ReferenceValue)lref).getSlot(context);
Debugger.trace("slot " + slot);
Debugger.trace("ConstantEvaluator.evaluat(AssignmentExpression) with slot " + slot);
if( slot != null ) {
Value rref = node.rhs.evaluate(context,this);
slot.value = rref.getValue(context);
}
node.ref = (ReferenceValue)lref;
} else {
throw new Exception("internal error: assignment lhs is not a reference.");
}
return value;
@@ -1079,6 +1151,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace("evaluating ReturnStatementNode = " + node);
}
node.expr.evaluate(context,this);
return new CodeValue(node);
}
@@ -1208,7 +1282,7 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
static {
try {
namespace_parameters = new ObjectValue(new NamespaceType("_parameters_"));
namespace_parameters = new ObjectValue(new TypeValue(new NamespaceType("_parameters_")));
} catch ( Exception x ) {
x.printStackTrace();
Debugger.trace("oops, something is not right.");
@@ -1577,12 +1651,17 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
* 2. Save result in code slot.
*/
private int local_offset;
public Value evaluate( Context context, FunctionDefinitionNode node ) throws Exception {
if( debug ) {
Debugger.trace( "evaluating FunctionDefinitionNode: " + node );
}
local_offset = 0; // start a new activation frame.
used_namespaces.addElement(namespace_parameters);
Value value = node.decl.evaluate(context,this);
if( node.body!=null) {
@@ -1595,6 +1674,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
context.popScope();
}
node.fixedCount = local_offset;
return UndefinedValue.undefinedValue;
}
@@ -1633,7 +1714,8 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Debugger.trace( "evaluating FunctionDeclarationNode: " + node );
}
ReferenceValue ref = (ReferenceValue) node.name.evaluate(context,this);
ReferenceValue ref;
node.ref = ref = (ReferenceValue) node.name.evaluate(context,this);
String name = ref.getName();
ref.scope = context.getLocal();
@@ -1747,20 +1829,21 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
Scope local = context.getLocal();
node.slot = local.add(namespace_parameters,"_result_");
Value result;
Value type;
if( node.result!=null ) {
result = node.result.evaluate(context,this).getValue(context);
node.ref = node.result.evaluate(context,this);
type = node.ref.getValue(context);
} else {
result = ObjectType.type;
type = ObjectType.type;
}
if( !TypeType.type.includes(result) ) {
error(context,"Result type expression does not evaluate to a type. result = " + result.type,node.pos());
if( !TypeType.type.includes(type) ) {
error(context,"Result type expression does not evaluate to a type. result = " + type.type,node.pos());
}
node.slot.type = (TypeValue) result;
node.slot.type = type;
return result;
return type;
}
/**
@@ -1783,8 +1866,9 @@ public class ConstantEvaluator extends Evaluator implements Tokens, Attributes {
ref = (ReferenceValue) node.identifier.evaluate(context,this);
name = ref.getName();
node.slot = local.add(namespace_parameters,name);
//node.identifier.slot.block = context.getBlock();
node.slot = local.add(namespace_parameters,name);
node.slot.store = new Store(local,local_offset++);
node.name = name; // for code generation.
return ref;
}
@@ -2338,6 +2422,7 @@ class Flow {
}
return preds;
}
}
/*

View File

@@ -176,6 +176,14 @@ public class ObjectValue extends Value implements Attributes, Scope {
return slot;
}
/**
*
*/
int size() {
return slots.size();
}
/**
*
*/

View File

@@ -45,7 +45,7 @@ public class ReferenceValue extends Value {
if( debug ) {
Debugger.trace( "creating reference scope = " + scope +
" name = " + name + " namespaces = " + namespaces );
" name = " + name + " used_namespaces = " + namespaces );
}
this.scope = scope;
@@ -91,6 +91,10 @@ public class ReferenceValue extends Value {
break;
}
}
if( slot==null ) {
slot = scope.get(qualifier/*=null*/,name);
}
}
if( debug ) {
Debugger.trace("leaving getSlotInScope() with slot="+slot);

View File

@@ -60,5 +60,6 @@ function run() {
}
/*
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
* Copyright (c) 1999-2001, Mountain View Compiler Company.
* All rights reserved.
*/

View File

@@ -7,17 +7,18 @@ function title() {
}
function run() {
a.b::c.d[e](f,g)[h].i++;
//a.b::c.d[e](f,g)[h].i++;
delete p;
void 0;
typeof ob;
++a.b--;
--a.b++;
//++a.b--;
//--a.b++;
+a;
-a;
!a;
}
/*
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
* Copyright (c) 1999-2001, Mountain View Compiler Company.
* All rights reserved.
*/

View File

@@ -32,5 +32,5 @@ unit const liter = makeLiter;
showerrors unit const liter = Unit.dm.pow(3);
/*
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
* Copyright (c) 1999-2001, Mountain View Compiler Company. All rights reserved.
*/

View File

@@ -2,18 +2,19 @@
* Sanity test.
*/
const result = 'okay';
function title() {
return "sanity";
}
function run() {
function g(a,b) {
return a+b;
}
result;
function run() {
return g(1,2);
}
/**
* Copyright (c) 1999, Mountain View Compiler Company. All rights reserved.
/*
* Copyright (c) 1999-2001, Mountain View Compiler Company.
* All rights reserved.
*/