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:
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -32,6 +32,7 @@ public class Node {
|
||||
|
||||
Block block;
|
||||
int position;
|
||||
Store store;
|
||||
|
||||
public Node() {
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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+" }";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
mozilla/js/js2/jsc/src/java/parser/Store.java
Normal file
45
mozilla/js/js2/jsc/src/java/parser/Store.java
Normal 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.
|
||||
*/
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -176,6 +176,14 @@ public class ObjectValue extends Value implements Attributes, Scope {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
int size() {
|
||||
return slots.size();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -32,6 +32,7 @@ public class Node {
|
||||
|
||||
Block block;
|
||||
int position;
|
||||
Store store;
|
||||
|
||||
public Node() {
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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+" }";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
mozilla/js2/jsc/src/java/parser/Store.java
Normal file
45
mozilla/js2/jsc/src/java/parser/Store.java
Normal 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.
|
||||
*/
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -176,6 +176,14 @@ public class ObjectValue extends Value implements Attributes, Scope {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
int size() {
|
||||
return slots.size();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user