Fixed JSArray for 1.5 semantics stuff. Changed readEvalFile to stop
doing line at a time nonsense. Fixed ExprNode::Index cases to use InvokeExprNode instead of Binary. git-svn-id: svn://10.0.0.236/trunk@82119 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1219,9 +1219,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (i->op->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(i->op);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
ret = call(getElement(base, genExpr(b->op2)), base, args);
|
||||
InvokeExprNode *ii = static_cast<InvokeExprNode *>(i->op);
|
||||
TypedRegister base = genExpr(ii->op);
|
||||
ret = call(getElement(base, genExpr(ii->pairs->value)), base, args); // FIXME, only taking first index
|
||||
}
|
||||
else
|
||||
ASSERT("WAH!");
|
||||
@@ -1229,13 +1229,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
break;
|
||||
case ExprNode::index :
|
||||
{
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
JSClass *clazz = dynamic_cast<JSClass*>(base.second);
|
||||
if (clazz) {
|
||||
// look for operator [] and invoke it
|
||||
}
|
||||
TypedRegister index = genExpr(b->op2);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
ret = getElement(base, index);
|
||||
}
|
||||
break;
|
||||
@@ -1275,9 +1275,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (u->op->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
TypedRegister index = genExpr(b->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
ret = getElement(base, index);
|
||||
ret = binaryOp(xcrementOp, ret, loadImmediate(1.0));
|
||||
setElement(base, index, ret);
|
||||
@@ -1300,9 +1300,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (u->op->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
TypedRegister index = genExpr(b->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
ret = elementXcr(base, index, xcrementOp);
|
||||
}
|
||||
else
|
||||
@@ -1351,9 +1351,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(lb->op1);
|
||||
TypedRegister index = genExpr(lb->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
setElement(base, index, ret);
|
||||
}
|
||||
else
|
||||
@@ -1384,9 +1384,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(lb->op1);
|
||||
TypedRegister index = genExpr(lb->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
TypedRegister v = getElement(base, index);
|
||||
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
setElement(base, index, ret);
|
||||
@@ -1442,7 +1442,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
TypedRegister r1 = genExpr(b->op1);
|
||||
TypedRegister r2 = genExpr(b->op2);
|
||||
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r1, r2);
|
||||
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r2, r1);
|
||||
if (trueBranch || falseBranch) {
|
||||
if (trueBranch == NULL)
|
||||
branchFalse(falseBranch, ret);
|
||||
|
||||
@@ -176,8 +176,10 @@ ICodeModule* Context::compileFunction(const String &source)
|
||||
JSValue Context::readEvalFile(FILE* in, const String& fileName)
|
||||
{
|
||||
String buffer;
|
||||
string line;
|
||||
LineReader inReader(in);
|
||||
int ch;
|
||||
while ((ch = getc(in)) != EOF)
|
||||
buffer += static_cast<char>(ch);
|
||||
|
||||
JSValues emptyArgs;
|
||||
JSValue result;
|
||||
|
||||
@@ -187,45 +189,34 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName)
|
||||
autosaver<Linkage*> linkage(mLinkage, 0);
|
||||
autosaver<InstructionIterator> pc(mPC);
|
||||
|
||||
while (inReader.readLine(line) != 0) {
|
||||
appendChars(buffer, line.data(), line.size());
|
||||
try {
|
||||
Arena a;
|
||||
Parser p(getWorld(), a, buffer, fileName);
|
||||
StmtNode *parsedStatements = p.parseProgram();
|
||||
ASSERT(p.lexer.peek(true).hasKind(Token::end));
|
||||
try {
|
||||
Arena a;
|
||||
Parser p(getWorld(), a, buffer, fileName);
|
||||
StmtNode *parsedStatements = p.parseProgram();
|
||||
/*******/
|
||||
ASSERT(p.lexer.peek(true).hasKind(Token::end));
|
||||
{
|
||||
PrettyPrinter f(stdOut, 30);
|
||||
{
|
||||
PrettyPrinter f(stdOut, 30);
|
||||
{
|
||||
PrettyPrinter::Block b(f, 2);
|
||||
f << "Program =";
|
||||
f.linearBreak(1);
|
||||
StmtNode::printStatements(f, parsedStatements);
|
||||
}
|
||||
f.end();
|
||||
PrettyPrinter::Block b(f, 2);
|
||||
f << "Program =";
|
||||
f.linearBreak(1);
|
||||
StmtNode::printStatements(f, parsedStatements);
|
||||
}
|
||||
stdOut << '\n';
|
||||
f.end();
|
||||
}
|
||||
stdOut << '\n';
|
||||
/*******/
|
||||
|
||||
// Generate code for parsedStatements, which is a linked
|
||||
// list of zero or more statements
|
||||
ICodeModule* icm = genCode(parsedStatements, fileName);
|
||||
if (icm) {
|
||||
result = interpret(icm, emptyArgs);
|
||||
delete icm;
|
||||
}
|
||||
|
||||
clear(buffer);
|
||||
} catch (Exception &e) {
|
||||
/* If we got a syntax error on the end of input,
|
||||
* then wait for a continuation
|
||||
* of input rather than printing the error message. */
|
||||
if (!(e.hasKind(Exception::syntaxError) &&
|
||||
e.lineNum && e.pos == buffer.size() &&
|
||||
e.sourceFile == fileName)) {
|
||||
stdOut << '\n' << e.fullMessage();
|
||||
clear(buffer);
|
||||
}
|
||||
// list of zero or more statements
|
||||
ICodeModule* icm = genCode(parsedStatements, fileName);
|
||||
if (icm) {
|
||||
result = interpret(icm, emptyArgs);
|
||||
delete icm;
|
||||
}
|
||||
} catch (Exception &e) {
|
||||
throw new JSException(e.fullMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -566,7 +557,7 @@ void Context::initContext()
|
||||
|
||||
// the 'Math' object just has some useful properties
|
||||
JSMath::initMathObject(mGlobal);
|
||||
|
||||
JSArray::initArrayObject(mGlobal);
|
||||
|
||||
// This initializes the state of the binary operator overload mechanism.
|
||||
// One could argue that it is unneccessary to do this until the 'Operators'
|
||||
@@ -1037,6 +1028,7 @@ using JSString throughout.
|
||||
JSArray* array = value.array;
|
||||
(*registers)[dst(ge).first] = (*array)[(*registers)[src2(ge).first]];
|
||||
}
|
||||
// FIXME - else case does what/? GET_PROPERTY of toString(index) ?
|
||||
}
|
||||
break;
|
||||
case SET_ELEMENT:
|
||||
@@ -1047,6 +1039,7 @@ using JSString throughout.
|
||||
JSArray* array = value.array;
|
||||
(*array)[(*registers)[src1(se).first]] = (*registers)[src2(se).first];
|
||||
}
|
||||
// FIXME - else case does what/? SET_PROPERTY of toString(index) ?
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -92,9 +92,6 @@ void JSObject::initObjectObject(JSScope *)
|
||||
{
|
||||
// The ObjectPrototypeObject has already been constructed by static initialization.
|
||||
|
||||
// JSNativeFunction *objCon = new JSNativeFunction(objectConstructor);
|
||||
// objCon->setProperty(widenCString("prototype"), JSValue(ObjectPrototypeObject));
|
||||
// g->setProperty(*ObjectString, JSValue(objCon));
|
||||
}
|
||||
|
||||
|
||||
@@ -251,6 +248,67 @@ static JSValue date_invokor(Context *, const JSValues&)
|
||||
return JSValue(new JSString("now"));
|
||||
}
|
||||
|
||||
/********** Array Object Stuff **************************/
|
||||
|
||||
JSString* JSArray::ArrayString = new JSString("Array");
|
||||
|
||||
JSObject *JSArray::ArrayPrototypeObject = NULL;
|
||||
|
||||
static JSValue array_constructor(Context *, const JSValues& argv)
|
||||
{
|
||||
// argv[0] will be NULL
|
||||
int argCount = argv.size();
|
||||
if (argCount > 1)
|
||||
if (argCount > 2) { // then it's a bunch of elements
|
||||
JSArray *result = new JSArray(argCount - 1);
|
||||
for (uint32 i = 1; i < argCount; i++) {
|
||||
(*result)[i - 1] = argv[i];
|
||||
}
|
||||
return JSValue(result);
|
||||
}
|
||||
else
|
||||
return JSValue(new JSArray(JSValue::valueToInteger(argv[1]).i32));
|
||||
else
|
||||
return JSValue(new JSArray());
|
||||
}
|
||||
|
||||
static JSValue array_toString(Context *, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSValue theThis = argv[0];
|
||||
if (theThis.isArray()) {
|
||||
StringFormatter f;
|
||||
f << theThis;
|
||||
return JSValue(new JSString(f));
|
||||
}
|
||||
else
|
||||
throw new JSException("TypeError : Array::toString called on non array object");
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
struct ArrayFunctionEntry {
|
||||
char *name;
|
||||
JSNativeFunction::JSCode fn;
|
||||
} ArrayFunctions[] = {
|
||||
{ "constructor", array_constructor },
|
||||
{ "toString", array_toString }
|
||||
// splice, join etc etc
|
||||
};
|
||||
|
||||
|
||||
void JSArray::initArrayObject(JSScope *g)
|
||||
{
|
||||
ArrayPrototypeObject = new JSObject();
|
||||
ArrayPrototypeObject->setClass(new JSString(ArrayString));
|
||||
|
||||
for (uint i = 0; i < sizeof(ArrayFunctions) / sizeof(ArrayFunctionEntry); i++)
|
||||
ArrayPrototypeObject->setProperty(widenCString(ArrayFunctions[i].name), JSValue(new JSNativeFunction(ArrayFunctions[i].fn) ) );
|
||||
|
||||
ASSERT(g->getProperty(*ArrayString).isObject());
|
||||
JSObject *arrayVariable = g->getProperty(*ArrayString).object;
|
||||
arrayVariable->setProperty(widenCString("prototype"), JSValue(ArrayPrototypeObject)); // should be DontEnum, DontDelete, ReadOnly
|
||||
}
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
@@ -260,7 +318,7 @@ JSType Number_Type = JSType(widenCString("Number"), &Integer_Type);
|
||||
JSType Character_Type = JSType(widenCString("Character"), &Any_Type);
|
||||
JSType String_Type = JSType(widenCString("String"), &Character_Type);
|
||||
JSType Function_Type = JSType(widenCString("Function"), &Any_Type, new JSNativeFunction(function_constructor), new JSNativeFunction(function_constructor));
|
||||
JSType Array_Type = JSType(widenCString("Array"), &Any_Type);
|
||||
JSType Array_Type = JSType(widenCString("Array"), &Any_Type, new JSNativeFunction(array_constructor), new JSNativeFunction(array_constructor));
|
||||
JSType Type_Type = JSType(widenCString("Type"), &Any_Type);
|
||||
JSType Boolean_Type = JSType(widenCString("Boolean"), &Any_Type, new JSNativeFunction(boolean_constructor), new JSNativeFunction(boolean_constructor));
|
||||
JSType Null_Type = JSType(widenCString("Null"), &Any_Type);
|
||||
|
||||
@@ -133,6 +133,7 @@ namespace JSTypes {
|
||||
JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); }
|
||||
|
||||
bool isFunction() const { return (tag == function_tag); }
|
||||
bool isArray() const { return (tag == array_tag); }
|
||||
bool isObject() const { return ((tag == object_tag) || (tag == function_tag) || (tag == array_tag) || (tag == type_tag)); }
|
||||
bool isString() const { return (tag == string_tag); }
|
||||
bool isBoolean() const { return (tag == boolean_tag); }
|
||||
@@ -381,12 +382,18 @@ namespace JSTypes {
|
||||
* Private representation of a JavaScript array.
|
||||
*/
|
||||
class JSArray : public JSObject {
|
||||
static JSObject* ArrayPrototypeObject;
|
||||
static JSString* ArrayString;
|
||||
|
||||
JSValues elements;
|
||||
uint32 top;
|
||||
public:
|
||||
JSArray() : elements(1) { top = 0; }
|
||||
JSArray(uint32 size) : elements(size) { top = size; }
|
||||
JSArray(const JSValues &v) : elements(v) {}
|
||||
|
||||
static void initArrayObject(JSScope *g);
|
||||
|
||||
JSArray() : JSObject(ArrayPrototypeObject), elements(1) { setClass(ArrayString); top = 0; }
|
||||
JSArray(uint32 size) : JSObject(ArrayPrototypeObject), elements(size) { setClass(ArrayString); top = size; }
|
||||
JSArray(const JSValues &v) : JSObject(ArrayPrototypeObject), elements(v) { setClass(ArrayString); }
|
||||
|
||||
uint32 length()
|
||||
{
|
||||
@@ -466,6 +473,7 @@ namespace JSTypes {
|
||||
|
||||
class JSException : public gc_base {
|
||||
public:
|
||||
JSException(String &mess) : value(JSValue(new JSString(mess))) { }
|
||||
JSException(char *mess) : value(JSValue(new JSString(mess))) { }
|
||||
JSException(JSValue v) : value(v) { }
|
||||
JSValue value;
|
||||
@@ -669,6 +677,7 @@ namespace JSTypes {
|
||||
bool getValue() { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
||||
@@ -1219,9 +1219,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (i->op->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(i->op);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
ret = call(getElement(base, genExpr(b->op2)), base, args);
|
||||
InvokeExprNode *ii = static_cast<InvokeExprNode *>(i->op);
|
||||
TypedRegister base = genExpr(ii->op);
|
||||
ret = call(getElement(base, genExpr(ii->pairs->value)), base, args); // FIXME, only taking first index
|
||||
}
|
||||
else
|
||||
ASSERT("WAH!");
|
||||
@@ -1229,13 +1229,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
break;
|
||||
case ExprNode::index :
|
||||
{
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
JSClass *clazz = dynamic_cast<JSClass*>(base.second);
|
||||
if (clazz) {
|
||||
// look for operator [] and invoke it
|
||||
}
|
||||
TypedRegister index = genExpr(b->op2);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
ret = getElement(base, index);
|
||||
}
|
||||
break;
|
||||
@@ -1275,9 +1275,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (u->op->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
TypedRegister index = genExpr(b->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
ret = getElement(base, index);
|
||||
ret = binaryOp(xcrementOp, ret, loadImmediate(1.0));
|
||||
setElement(base, index, ret);
|
||||
@@ -1300,9 +1300,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (u->op->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(b->op1);
|
||||
TypedRegister index = genExpr(b->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
ret = elementXcr(base, index, xcrementOp);
|
||||
}
|
||||
else
|
||||
@@ -1351,9 +1351,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(lb->op1);
|
||||
TypedRegister index = genExpr(lb->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
setElement(base, index, ret);
|
||||
}
|
||||
else
|
||||
@@ -1384,9 +1384,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::index) {
|
||||
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(lb->op1);
|
||||
TypedRegister index = genExpr(lb->op2);
|
||||
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
|
||||
TypedRegister base = genExpr(i->op);
|
||||
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
|
||||
TypedRegister v = getElement(base, index);
|
||||
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
setElement(base, index, ret);
|
||||
@@ -1442,7 +1442,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
TypedRegister r1 = genExpr(b->op1);
|
||||
TypedRegister r2 = genExpr(b->op2);
|
||||
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r1, r2);
|
||||
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r2, r1);
|
||||
if (trueBranch || falseBranch) {
|
||||
if (trueBranch == NULL)
|
||||
branchFalse(falseBranch, ret);
|
||||
|
||||
@@ -176,8 +176,10 @@ ICodeModule* Context::compileFunction(const String &source)
|
||||
JSValue Context::readEvalFile(FILE* in, const String& fileName)
|
||||
{
|
||||
String buffer;
|
||||
string line;
|
||||
LineReader inReader(in);
|
||||
int ch;
|
||||
while ((ch = getc(in)) != EOF)
|
||||
buffer += static_cast<char>(ch);
|
||||
|
||||
JSValues emptyArgs;
|
||||
JSValue result;
|
||||
|
||||
@@ -187,45 +189,34 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName)
|
||||
autosaver<Linkage*> linkage(mLinkage, 0);
|
||||
autosaver<InstructionIterator> pc(mPC);
|
||||
|
||||
while (inReader.readLine(line) != 0) {
|
||||
appendChars(buffer, line.data(), line.size());
|
||||
try {
|
||||
Arena a;
|
||||
Parser p(getWorld(), a, buffer, fileName);
|
||||
StmtNode *parsedStatements = p.parseProgram();
|
||||
ASSERT(p.lexer.peek(true).hasKind(Token::end));
|
||||
try {
|
||||
Arena a;
|
||||
Parser p(getWorld(), a, buffer, fileName);
|
||||
StmtNode *parsedStatements = p.parseProgram();
|
||||
/*******/
|
||||
ASSERT(p.lexer.peek(true).hasKind(Token::end));
|
||||
{
|
||||
PrettyPrinter f(stdOut, 30);
|
||||
{
|
||||
PrettyPrinter f(stdOut, 30);
|
||||
{
|
||||
PrettyPrinter::Block b(f, 2);
|
||||
f << "Program =";
|
||||
f.linearBreak(1);
|
||||
StmtNode::printStatements(f, parsedStatements);
|
||||
}
|
||||
f.end();
|
||||
PrettyPrinter::Block b(f, 2);
|
||||
f << "Program =";
|
||||
f.linearBreak(1);
|
||||
StmtNode::printStatements(f, parsedStatements);
|
||||
}
|
||||
stdOut << '\n';
|
||||
f.end();
|
||||
}
|
||||
stdOut << '\n';
|
||||
/*******/
|
||||
|
||||
// Generate code for parsedStatements, which is a linked
|
||||
// list of zero or more statements
|
||||
ICodeModule* icm = genCode(parsedStatements, fileName);
|
||||
if (icm) {
|
||||
result = interpret(icm, emptyArgs);
|
||||
delete icm;
|
||||
}
|
||||
|
||||
clear(buffer);
|
||||
} catch (Exception &e) {
|
||||
/* If we got a syntax error on the end of input,
|
||||
* then wait for a continuation
|
||||
* of input rather than printing the error message. */
|
||||
if (!(e.hasKind(Exception::syntaxError) &&
|
||||
e.lineNum && e.pos == buffer.size() &&
|
||||
e.sourceFile == fileName)) {
|
||||
stdOut << '\n' << e.fullMessage();
|
||||
clear(buffer);
|
||||
}
|
||||
// list of zero or more statements
|
||||
ICodeModule* icm = genCode(parsedStatements, fileName);
|
||||
if (icm) {
|
||||
result = interpret(icm, emptyArgs);
|
||||
delete icm;
|
||||
}
|
||||
} catch (Exception &e) {
|
||||
throw new JSException(e.fullMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -566,7 +557,7 @@ void Context::initContext()
|
||||
|
||||
// the 'Math' object just has some useful properties
|
||||
JSMath::initMathObject(mGlobal);
|
||||
|
||||
JSArray::initArrayObject(mGlobal);
|
||||
|
||||
// This initializes the state of the binary operator overload mechanism.
|
||||
// One could argue that it is unneccessary to do this until the 'Operators'
|
||||
@@ -1037,6 +1028,7 @@ using JSString throughout.
|
||||
JSArray* array = value.array;
|
||||
(*registers)[dst(ge).first] = (*array)[(*registers)[src2(ge).first]];
|
||||
}
|
||||
// FIXME - else case does what/? GET_PROPERTY of toString(index) ?
|
||||
}
|
||||
break;
|
||||
case SET_ELEMENT:
|
||||
@@ -1047,6 +1039,7 @@ using JSString throughout.
|
||||
JSArray* array = value.array;
|
||||
(*array)[(*registers)[src1(se).first]] = (*registers)[src2(se).first];
|
||||
}
|
||||
// FIXME - else case does what/? SET_PROPERTY of toString(index) ?
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -92,9 +92,6 @@ void JSObject::initObjectObject(JSScope *)
|
||||
{
|
||||
// The ObjectPrototypeObject has already been constructed by static initialization.
|
||||
|
||||
// JSNativeFunction *objCon = new JSNativeFunction(objectConstructor);
|
||||
// objCon->setProperty(widenCString("prototype"), JSValue(ObjectPrototypeObject));
|
||||
// g->setProperty(*ObjectString, JSValue(objCon));
|
||||
}
|
||||
|
||||
|
||||
@@ -251,6 +248,67 @@ static JSValue date_invokor(Context *, const JSValues&)
|
||||
return JSValue(new JSString("now"));
|
||||
}
|
||||
|
||||
/********** Array Object Stuff **************************/
|
||||
|
||||
JSString* JSArray::ArrayString = new JSString("Array");
|
||||
|
||||
JSObject *JSArray::ArrayPrototypeObject = NULL;
|
||||
|
||||
static JSValue array_constructor(Context *, const JSValues& argv)
|
||||
{
|
||||
// argv[0] will be NULL
|
||||
int argCount = argv.size();
|
||||
if (argCount > 1)
|
||||
if (argCount > 2) { // then it's a bunch of elements
|
||||
JSArray *result = new JSArray(argCount - 1);
|
||||
for (uint32 i = 1; i < argCount; i++) {
|
||||
(*result)[i - 1] = argv[i];
|
||||
}
|
||||
return JSValue(result);
|
||||
}
|
||||
else
|
||||
return JSValue(new JSArray(JSValue::valueToInteger(argv[1]).i32));
|
||||
else
|
||||
return JSValue(new JSArray());
|
||||
}
|
||||
|
||||
static JSValue array_toString(Context *, const JSValues& argv)
|
||||
{
|
||||
if (argv.size() > 0) {
|
||||
JSValue theThis = argv[0];
|
||||
if (theThis.isArray()) {
|
||||
StringFormatter f;
|
||||
f << theThis;
|
||||
return JSValue(new JSString(f));
|
||||
}
|
||||
else
|
||||
throw new JSException("TypeError : Array::toString called on non array object");
|
||||
}
|
||||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
struct ArrayFunctionEntry {
|
||||
char *name;
|
||||
JSNativeFunction::JSCode fn;
|
||||
} ArrayFunctions[] = {
|
||||
{ "constructor", array_constructor },
|
||||
{ "toString", array_toString }
|
||||
// splice, join etc etc
|
||||
};
|
||||
|
||||
|
||||
void JSArray::initArrayObject(JSScope *g)
|
||||
{
|
||||
ArrayPrototypeObject = new JSObject();
|
||||
ArrayPrototypeObject->setClass(new JSString(ArrayString));
|
||||
|
||||
for (uint i = 0; i < sizeof(ArrayFunctions) / sizeof(ArrayFunctionEntry); i++)
|
||||
ArrayPrototypeObject->setProperty(widenCString(ArrayFunctions[i].name), JSValue(new JSNativeFunction(ArrayFunctions[i].fn) ) );
|
||||
|
||||
ASSERT(g->getProperty(*ArrayString).isObject());
|
||||
JSObject *arrayVariable = g->getProperty(*ArrayString).object;
|
||||
arrayVariable->setProperty(widenCString("prototype"), JSValue(ArrayPrototypeObject)); // should be DontEnum, DontDelete, ReadOnly
|
||||
}
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
@@ -260,7 +318,7 @@ JSType Number_Type = JSType(widenCString("Number"), &Integer_Type);
|
||||
JSType Character_Type = JSType(widenCString("Character"), &Any_Type);
|
||||
JSType String_Type = JSType(widenCString("String"), &Character_Type);
|
||||
JSType Function_Type = JSType(widenCString("Function"), &Any_Type, new JSNativeFunction(function_constructor), new JSNativeFunction(function_constructor));
|
||||
JSType Array_Type = JSType(widenCString("Array"), &Any_Type);
|
||||
JSType Array_Type = JSType(widenCString("Array"), &Any_Type, new JSNativeFunction(array_constructor), new JSNativeFunction(array_constructor));
|
||||
JSType Type_Type = JSType(widenCString("Type"), &Any_Type);
|
||||
JSType Boolean_Type = JSType(widenCString("Boolean"), &Any_Type, new JSNativeFunction(boolean_constructor), new JSNativeFunction(boolean_constructor));
|
||||
JSType Null_Type = JSType(widenCString("Null"), &Any_Type);
|
||||
|
||||
@@ -133,6 +133,7 @@ namespace JSTypes {
|
||||
JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); }
|
||||
|
||||
bool isFunction() const { return (tag == function_tag); }
|
||||
bool isArray() const { return (tag == array_tag); }
|
||||
bool isObject() const { return ((tag == object_tag) || (tag == function_tag) || (tag == array_tag) || (tag == type_tag)); }
|
||||
bool isString() const { return (tag == string_tag); }
|
||||
bool isBoolean() const { return (tag == boolean_tag); }
|
||||
@@ -381,12 +382,18 @@ namespace JSTypes {
|
||||
* Private representation of a JavaScript array.
|
||||
*/
|
||||
class JSArray : public JSObject {
|
||||
static JSObject* ArrayPrototypeObject;
|
||||
static JSString* ArrayString;
|
||||
|
||||
JSValues elements;
|
||||
uint32 top;
|
||||
public:
|
||||
JSArray() : elements(1) { top = 0; }
|
||||
JSArray(uint32 size) : elements(size) { top = size; }
|
||||
JSArray(const JSValues &v) : elements(v) {}
|
||||
|
||||
static void initArrayObject(JSScope *g);
|
||||
|
||||
JSArray() : JSObject(ArrayPrototypeObject), elements(1) { setClass(ArrayString); top = 0; }
|
||||
JSArray(uint32 size) : JSObject(ArrayPrototypeObject), elements(size) { setClass(ArrayString); top = size; }
|
||||
JSArray(const JSValues &v) : JSObject(ArrayPrototypeObject), elements(v) { setClass(ArrayString); }
|
||||
|
||||
uint32 length()
|
||||
{
|
||||
@@ -466,6 +473,7 @@ namespace JSTypes {
|
||||
|
||||
class JSException : public gc_base {
|
||||
public:
|
||||
JSException(String &mess) : value(JSValue(new JSString(mess))) { }
|
||||
JSException(char *mess) : value(JSValue(new JSString(mess))) { }
|
||||
JSException(JSValue v) : value(v) { }
|
||||
JSValue value;
|
||||
@@ -669,6 +677,7 @@ namespace JSTypes {
|
||||
bool getValue() { return mValue; }
|
||||
};
|
||||
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user