Пример #1
0
/**
 *  Iterate over all elements in the object and find all elements for which the matching function is true.
 *  The match is called with the following signature:
 *
 *      function match(arrayElement: Object, elementIndex: Number, arr: Array): Boolean
 *
 *  @param match Matching function
 *  @return Returns a new array containing all matching elements.
 */
static EjsVar *findAll(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsVar      *funArgs[3];
    EjsBoolean  *result;
    EjsArray    *elements;
    int         i;

    mprAssert(argc == 1 && ejsIsFunction(argv[0]));

    elements = ejsCreateArray(ejs, 0);
    if (elements == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    for (i = 0; i < ap->length; i++) {
        funArgs[0] = ap->obj.properties.slots[i];               /* Array element */
        funArgs[1] = (EjsVar*) ejsCreateNumber(ejs, i);             /* element index */
        funArgs[2] = (EjsVar*) ap;                                  /* Array */
        result = (EjsBoolean*) ejsRunFunction(ejs, (EjsFunction*) argv[0], 0, 3, funArgs);
        if (result == 0 || !ejsIsBoolean(result) || !result->value) {
            setArrayProperty(ejs, elements, elements->length, ap->obj.properties.slots[i]);
        }
    }
    return (EjsVar*) elements;
}
Пример #2
0
/*
 *  Return an array of table names in the database.
 *  function get tables(): Array
 */
static EjsVar *tables(Ejs *ejs, EjsDb *db, int argc, EjsVar **argv)
{
    EjsArray    *ap;
    char        **data, *error;
    int         rc, rowCount, i;

    ejsSetDbMemoryContext(db->tls, db->arena);

    ap = ejsCreateArray(ejs, 0);

    rc = sqlite3_get_table(db->sdb,
      "SELECT name FROM sqlite_master "
      "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
      "UNION ALL "
      "SELECT name FROM sqlite_temp_master "
      "WHERE type IN ('table','view') "
      "ORDER BY 1",
      &data, &rowCount, 0, &error);

    if (error) {
        ejsThrowIOError(ejs, "%s", error);
        sqlite3_free(error);
    }
    if (rc == SQLITE_OK){
        for (i = 1; i <= rowCount; i++) {
            ejsSetProperty(ejs, (EjsVar*) ap, i - 1, (EjsVar*) ejsCreateString(ejs, data[i]));
        }
    }
    sqlite3_free_table(data);
    return (EjsVar*) ap;
}
Пример #3
0
static EjsVar *makeIntersection(Ejs *ejs, EjsArray *lhs, EjsArray *rhs)
{
    EjsArray    *result;
    EjsVar      **l, **r, **resultSlots;
    int         i, j, k;

    result = ejsCreateArray(ejs, 0);
    l = lhs->data;
    r = rhs->data;

    for (i = 0; i < lhs->length; i++) {
        for (j = 0; j < rhs->length; j++) {
            if (compareArrayElement(ejs, l[i], r[j])) {
                resultSlots = result->data;
                for (k = 0; k < result->length; k++) {
                    if (compareArrayElement(ejs, l[i], resultSlots[k])) {
                        break;
                    }
                }
                if (result->length == 0 || k == result->length) {
                    setArrayProperty(ejs, result, -1, l[i]);
                }
            }
        }
    }
    return (EjsVar*) result;
}
Пример #4
0
EjsArray *ejsCaptureStack(Ejs *ejs, int uplevels)
{
    EjsFrame        *fp;
    EjsState        *state;
    EjsArray        *stack;
    wchar           *source;
    EjsObj          *frame;
    char            *filename;
    int             index, lineNumber;

    assert(ejs);

    stack = ejsCreateArray(ejs, 0);
    index = 0;
    for (state = ejs->state; state; state = state->prev) {
        for (fp = state->fp; fp; fp = fp->caller) {
            if (uplevels-- <= 0) {
                frame = ejsCreateEmptyPot(ejs);
                if (ejsGetDebugInfo(ejs, (EjsFunction*) fp, fp->pc, &filename, &lineNumber, &source) >= 0) {
                    ejsSetPropertyByName(ejs, frame, EN("filename"), ejsCreatePathFromAsc(ejs, filename));
                    ejsSetPropertyByName(ejs, frame, EN("lineno"), ejsCreateNumber(ejs, lineNumber));
                    ejsSetPropertyByName(ejs, frame, EN("code"), ejsCreateString(ejs, source, wlen(source)));
                } else {
                    ejsSetPropertyByName(ejs, frame, EN("filename"), EST(undefined));
                }
                ejsSetPropertyByName(ejs, frame, EN("func"), fp->function.name);
                ejsSetProperty(ejs, stack, index++, frame);
            }
        }
    }
    return stack;
}
Пример #5
0
/*  
    Get the application command line arguments
    static function get args(): Array
 */
static EjsArray *app_args(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsArray    *args;
    int         i;

    args = ejsCreateArray(ejs, ejs->argc);
    for (i = 0; i < ejs->argc; i++) {
        ejsSetProperty(ejs, args, i, ejsCreateStringFromAsc(ejs, ejs->argv[i]));
    }
    return args;
}
Пример #6
0
/*
 *  Get the application command line arguments
 *
 *  static function get args(): String
 */
static EjsVar *getArgs(Ejs *ejs, EjsObject *unused, int argc, EjsVar **argv)
{
    EjsArray    *args;
    int         i;

    args = ejsCreateArray(ejs, ejs->argc);
    for (i = 0; i < ejs->argc; i++) {
        ejsSetProperty(ejs, (EjsVar*) args, i, (EjsVar*) ejsCreateString(ejs, ejs->argv[i]));
    }
    return (EjsVar*) args;
}
Пример #7
0
/*
 *  A header object from a given hash table
 */  
static EjsVar *createHeaderObject(Ejs *ejs, MprHashTable *table)
{
    MprHash     *hp;
    EjsVar      *headers, *header;
    EjsName     qname;
    int         index;
    
    headers = (EjsVar*) ejsCreateArray(ejs, mprGetHashCount(table));
    for (index = 0, hp = 0; (hp = mprGetNextHash(table, hp)) != 0; ) {
        header = (EjsVar*) ejsCreateSimpleObject(ejs);
        ejsSetPropertyByName(ejs, header, ejsName(&qname, "", hp->key), (EjsVar*) ejsCreateString(ejs, hp->data));
        ejsSetProperty(ejs, headers, index++, header);
    }
    return headers;
}
Пример #8
0
/*
 *  Concatenate the supplied elements with the array to create a new array. If any arguments specify an array,
 *  their elements are catenated. This is a one level deep copy.
 *
 *  function concat(...args): Array
 */
static EjsVar *concatArray(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsArray    *args, *newArray, *vpa;
    EjsVar      *vp, **src, **dest;
    int         i, k, next;

    mprAssert(argc == 1 && ejsIsArray(argv[0]));

    args = ((EjsArray*) argv[0]);

    newArray = ejsCreateArray(ejs, ap->length);
    src = ap->data;
    dest = newArray->data;

    /*
     *  Copy the original array
     */
    for (next = 0; next < ap->length; next++) {
        dest[next] = src[next];
    }

    /*
     *  Copy the args. If any element is itself an array, then flatten it and copy its elements.
     */
    for (i = 0; i < args->length; i++) {
        vp = args->data[i];
        if (ejsIsArray(vp)) {
            vpa = (EjsArray*) vp;
            if (growArray(ejs, newArray, next + vpa->length) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
            dest = newArray->data;
            dest = newArray->data;
            for (k = 0; k < vpa->length; k++) {
                dest[next++] = vpa->data[k];
            }
        } else {
            if (growArray(ejs, newArray, next + 1) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
            dest[next++] = vp;
        }
    }
    return (EjsVar*) newArray;
}
Пример #9
0
static EjsArray *makeUnion(Ejs *ejs, EjsArray *lhs, EjsArray *rhs)
{
    EjsArray    *result;
    EjsObj      **l, **r;
    int         i;

    result = ejsCreateArray(ejs, 0);
    l = lhs->data;
    r = rhs->data;

    for (i = 0; i < lhs->length; i++) {
        addUnique(ejs, result, l[i]);
    }
    for (i = 0; i < rhs->length; i++) {
        addUnique(ejs, result, r[i]);
    }
    return result;
}
Пример #10
0
/*
    function get providers(): Array
 */
static EjsArray *http_providers(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    EjsArray    *result;
    int         i;

    result = ejsCreateArray(ejs, 0);
    i = 0;
#if BIT_PACK_EST
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "est"));
#endif
#if BIT_PACK_OPENSSL
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "openssl"));
#endif
#if BIT_PACK_MATRIXSSL
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "matrixssl"));
#endif
#if BIT_PACK_MOCANA
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "mocana"));
#endif
    return result;
}
Пример #11
0
/*
    function exec(str: String, start: Number = 0): Array
 */
static EjsArray *regex_exec(Ejs *ejs, EjsRegExp *rp, int argc, EjsObj **argv)
{
    EjsArray    *results;
    EjsString   *match, *str;
    int         matches[BIT_MAX_REGEX_MATCHES * 3];
    int         count, start, len, i, index;

    str = (EjsString*) argv[0];
    if (argc == 2) {
        start = (int) ejsGetNumber(ejs, argv[1]);
    } else {
        start = rp->endLastMatch;
    }
    rp->matched = 0;
    assert(rp->compiled);
    count = pcre_exec(rp->compiled, NULL, str->value, (int) str->length, start, 0, matches, sizeof(matches) / sizeof(int));
    if (count < 0) {
        rp->endLastMatch = 0;
        return ESV(null);
    }
    results = ejsCreateArray(ejs, count);
    for (index = 0, i = 0; i < count; i++, index += 2) {
        len = matches[index + 1] - matches[index];
        match = ejsCreateString(ejs, &str->value[matches[index]], len);
        ejsSetProperty(ejs, results, i, match);
        if (index == 0) {
            rp->matched = match;
        }
    }
    if (rp->global) {
        /* Only save if global flag used as per spec */
        rp->startLastMatch = matches[0];
        rp->endLastMatch = matches[1];
    }
    return results;
}
Пример #12
0
/*
 *  function sql(cmd: String): Array
 *
 *  Will support multiple sql cmds but will only return one result table.
 */
static EjsVar *sql(Ejs *ejs, EjsDb *db, int argc, EjsVar **argv)
{
    sqlite3         *sdb;
    sqlite3_stmt    *stmt;
    EjsArray        *result;
    EjsVar          *row, *svalue;
    EjsName         qname;
    cchar           *tail, *colName, *cmd, *value;
    int             i, ncol, rc, retries, rowNum;

    mprAssert(ejs);
    mprAssert(db);

    cmd = ejsGetString(argv[0]);
    
    ejsSetDbMemoryContext(db->tls, db->arena);

    rc = SQLITE_OK;
    retries = 0;
    sdb = db->sdb;

    if (sdb == 0) {
        ejsThrowIOError(ejs, "Database is closed");
        return 0;
    }
    mprAssert(sdb);

    result = ejsCreateArray(ejs, 0);
    if (result == 0) {
        return 0;
    }

    while (cmd && *cmd && (rc == SQLITE_OK || (rc == SQLITE_SCHEMA && ++retries < 2))) {

        stmt = 0;
        rc = sqlite3_prepare_v2(sdb, cmd, -1, &stmt, &tail);
        if (rc != SQLITE_OK) {
            continue;
        }
        if (stmt == 0) {
            /* Comment or white space */
            cmd = tail;
            continue;
        }

        ncol = sqlite3_column_count(stmt);

        for (rowNum = 0; ; rowNum++) {

            rc = sqlite3_step(stmt);

            if (rc == SQLITE_ROW) {

                row = (EjsVar*) ejsCreateSimpleObject(ejs);
                if (row == 0) {
                    sqlite3_finalize(stmt);
                    return 0;
                }
                if (ejsSetProperty(ejs, (EjsVar*) result, rowNum, row) < 0) {
                    /* TODO rc */
                }
                for (i = 0; i < ncol; i++) {
                    colName = sqlite3_column_name(stmt, i);
                    value = (cchar*) sqlite3_column_text(stmt, i);
                    ejsName(&qname, EJS_EMPTY_NAMESPACE, mprStrdup(row, colName));
                    if (ejsLookupProperty(ejs, row, &qname) < 0) {
                        svalue = (EjsVar*) ejsCreateString(ejs, mprStrdup(row, value));
                        if (ejsSetPropertyByName(ejs, row, &qname, svalue) < 0) {
                            /* TODO */
                        }
                    }
                }
            } else {
                rc = sqlite3_finalize(stmt);
                stmt = 0;

                if (rc != SQLITE_SCHEMA) {
                    //  TODO - what is this?
                    retries = 0;
                    for (cmd = tail; isspace(*cmd); cmd++) {
                        ;
                    }
                }
                break;
            }
#if UNUSED
            /* TODO -- should we be doing this */
            cmd = tail;
#endif
        }
    }

    if (stmt) {
        rc = sqlite3_finalize(stmt);
    }

    if (rc != SQLITE_OK) {
        if (rc == sqlite3_errcode(sdb)) {
            ejsThrowIOError(ejs, "SQL error: %s", sqlite3_errmsg(sdb));
        } else {
            ejsThrowIOError(ejs, "Unspecified SQL error");
        }
        return 0;
    }

    return (EjsVar*) result;
}
Пример #13
0
/*
  return a empty mpr array
*/
struct MprVar mprArray(const char *name)
{
	return ejsCreateArray(name && *name?name:"(NULL)", 0);
}
Пример #14
0
/*
    Parse an object literal string pointed to by js->next into the given buffer. Update js->next to point
    to the next input token in the object literal. Supports nested object literals.
 */
static EjsObj *parseLiteralInner(Ejs *ejs, MprBuf *buf, JsonState *js)
{
    EjsAny      *obj, *vp;
    MprBuf      *valueBuf;
    wchar       *token, *key, *value;
    int         tid, isArray;

    isArray = 0;

    tid = getNextJsonToken(buf, &token, js);
    if (tid == TOK_ERR || tid == TOK_EOF) {
        return 0;
    }
    if (tid == TOK_LBRACKET) {
        isArray = 1;
        obj = (EjsObj*) ejsCreateArray(ejs, 0);
    } else if (tid == TOK_LBRACE) {
        obj = ejsCreateEmptyPot(ejs);
    } else {
        return ejsParse(ejs, token, S_String);
    }
    if (obj == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    while (1) {
        vp = 0;
        tid = peekNextJsonToken(js);
        if (tid == TOK_ERR) {
            return 0;
        } else if (tid == TOK_EOF) {
            break;
        } else if (tid == TOK_RBRACE || tid == TOK_RBRACKET) {
            getNextJsonToken(buf, &key, js);
            break;
        }
        if (tid == TOK_LBRACKET) {
            /* For array values */
            vp = parseLiteral(ejs, js);
            assert(vp);
            
        } else if (tid == TOK_LBRACE) {
            /* For object values */
            vp = parseLiteral(ejs, js);
            assert(vp);
            
        } else if (isArray) {
            tid = getNextJsonToken(buf, &value, js);
            vp = ejsParse(ejs, value, (tid == TOK_QID) ? S_String: -1);
            assert(vp);
            
        } else {
            getNextJsonToken(buf, &key, js);
            tid = peekNextJsonToken(js);
            if (tid == TOK_ERR) {
                return 0;
            } else if (tid == TOK_EOF) {
                break;
            } else if (tid == TOK_LBRACE || tid == TOK_LBRACKET) {
                vp = parseLiteral(ejs, js);

            } else if (tid == TOK_ID || tid == TOK_QID) {
                valueBuf = mprCreateBuf(0, 0);
                getNextJsonToken(valueBuf, &value, js);
                if (tid == TOK_QID) {
                    vp = ejsCreateString(ejs, value, strlen(value));
                } else {
                    if (mcmp(value, "null") == 0) {
                        vp = ESV(null);
                    } else if (mcmp(value, "undefined") == 0) {
                        vp = ESV(undefined);
                    } else {
                        vp = ejsParse(ejs, value, -1);
                    }
                }
                assert(vp);
            } else {
                getNextJsonToken(buf, &value, js);
                js->error = js->next;
                return 0;
            }
        }
        if (vp == 0) {
            js->error = js->next;
            return 0;
        }
        if (isArray) {
            if (ejsSetProperty(ejs, obj, -1, vp) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
        } else {
            if (ejsSetPropertyByName(ejs, obj, WEN(key), vp) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
        }
    }
    return obj;
}
Пример #15
0
MprVar espCreateArrayVar(char *name, int size)
{
	return ejsCreateArray(name, size);
}
Пример #16
0
/*
 *  Create a new array by taking a slice from an array.
 *
 *  function slice(start: Number, end: Number, step: Number = 1): Array
 */
static EjsVar *sliceArray(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsArray    *result;
    EjsVar      **src, **dest;
    int         start, end, step, i, j, len, size;

    mprAssert(1 <= argc && argc <= 3);

    start = ejsGetInt(argv[0]);
    if (argc >= 2) {
        end = ejsGetInt(argv[1]);
    } else {
        end = ap->length;
    }
    if (argc == 3) {
        step = ejsGetInt(argv[2]);
    } else {
        step = 1;
    }
    if (step == 0) {
        step = 1;
    }

    if (start < 0) {
        start += ap->length;
    }
    if (start < 0) {
        start = 0;
    } else if (start >= ap->length) {
        start = ap->length;
    }

    if (end < 0) {
        end += ap->length;
    }
    if (end < 0) {
        end = 0;
    } else if (end >= ap->length) {
        end = ap->length;
    }
    size = (start < end) ? end - start : start - end;

    /*
     *  This may allocate too many elements if abs(step) is > 1, but length will still be correct.
     */
    result = ejsCreateArray(ejs, size);
    if (result == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    src = ap->data;
    dest = result->data;

    len = 0;
    if (step > 0) {
        for (i = start, j = 0; i < end; i += step, j++) {
            dest[j] = src[i];
            len++;
        }

    } else {
        for (i = start, j = 0; i > end; i += step, j++) {
            dest[j] = src[i];
            len++;
        }
    }
    result->length = len;
    return (EjsVar*) result;
}
Пример #17
0
static EjsAny *invokeArrayOperator(Ejs *ejs, EjsAny *lhs, int opcode, EjsAny *rhs)
{
    EjsAny  *result;

    if (rhs == 0 || TYPE(lhs) != TYPE(rhs)) {
        if ((result = coerceArrayOperands(ejs, lhs, opcode, rhs)) != 0) {
            return result;
        }
    }

    switch (opcode) {

    case EJS_OP_COMPARE_EQ: case EJS_OP_COMPARE_STRICTLY_EQ:
    case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_GE:
        return ejsCreateBoolean(ejs, (lhs == rhs));

    case EJS_OP_COMPARE_NE: case EJS_OP_COMPARE_STRICTLY_NE:
    case EJS_OP_COMPARE_LT: case EJS_OP_COMPARE_GT:
        return ejsCreateBoolean(ejs, !(lhs == rhs));

    /*
        Unary operators
     */
    case EJS_OP_COMPARE_NOT_ZERO:
        return ESV(true);

    case EJS_OP_COMPARE_UNDEFINED:
    case EJS_OP_COMPARE_NULL:
    case EJS_OP_COMPARE_FALSE:
    case EJS_OP_COMPARE_TRUE:
    case EJS_OP_COMPARE_ZERO:
        return ESV(false);

    case EJS_OP_LOGICAL_NOT: case EJS_OP_NOT: case EJS_OP_NEG:
        return ESV(one);

    /*
        Binary operators
     */
    case EJS_OP_DIV: case EJS_OP_MUL: case EJS_OP_REM:
    case EJS_OP_SHR: case EJS_OP_USHR: case EJS_OP_XOR:
        return ESV(zero);

    /*
        Operator overload
     */
    case EJS_OP_ADD:
        result = ejsCreateArray(ejs, 0);
        pushArray(ejs, result, 1, &lhs);
        pushArray(ejs, result, 1, &rhs);
        return result;

    case EJS_OP_AND:
        return makeIntersection(ejs, lhs, rhs);

    case EJS_OP_OR:
        return makeUnion(ejs, lhs, rhs);

    case EJS_OP_SHL:
        return pushArray(ejs, lhs, 1, &rhs);

    case EJS_OP_SUB:
        return ejsRemoveItems(ejs, lhs, rhs);

    default:
        ejsThrowTypeError(ejs, "Opcode %d not implemented for type %@", opcode, TYPE(lhs)->qname.name);
        return 0;
    }
    assert(0);
}
Пример #18
0
/*
 *  Insert, remove or replace array elements. Return the removed elements.
 *
 *  function splice(start: Number, deleteCount: Number, ...values): Array
 *
 */
static EjsVar *spliceArray(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsArray    *result, *values;
    EjsVar      **data, **dest, **items;
    int         start, deleteCount, i, delta, endInsert, oldLen;

    mprAssert(1 <= argc && argc <= 3);
    
    start = ejsGetInt(argv[0]);
    deleteCount = ejsGetInt(argv[1]);
    values = (EjsArray*) argv[2];

    if (ap->length == 0) {
        if (deleteCount <= 0) {
            return (EjsVar*) ap;
        }
        ejsThrowArgError(ejs, "Array is empty");
        return 0;
    }
    if (start < 0) {
        start += ap->length;
    }
    if (start < 0) {
        start = 0;
    }
    if (start >= ap->length) {
        start = ap->length - 1;
    }

    if (deleteCount < 0) {
        deleteCount = ap->length - start + 1;
    }
    if (deleteCount > ap->length) {
        deleteCount = ap->length;
    }

    result = ejsCreateArray(ejs, deleteCount);
    if (result == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    data = ap->data;
    dest = result->data;
    items = values->data;

    /*
     *  Copy removed items to the result
     */
    for (i = 0; i < deleteCount; i++) {
        dest[i] = data[i + start];
    }

    oldLen = ap->length;
    delta = values->length - deleteCount;
    
    if (delta > 0) {
        /*
         *  Make room for items to insert
         */
        if (growArray(ejs, ap, ap->length + delta) < 0) {
            return 0;
        }
        data = ap->data;
        endInsert = start + delta;
        for (i = ap->length - 1; i >= endInsert; i--) {
            data[i] = data[i - delta];
        }
        
    } else {
        ap->length += delta;
    }

    /*
     *  Copy in new values
     */
    for (i = 0; i < values->length; i++) {
        data[start + i] = items[i];
    }

    /*
     *  Remove holes
     */
    if (delta < 0) {
        for (i = start + values->length; i < oldLen; i++) {
            data[i] = data[i - delta];
        }
    }
    return (EjsVar*) result;
}
Пример #19
0
static EjsVar *invokeArrayOperator(Ejs *ejs, EjsVar *lhs, int opcode,  EjsVar *rhs)
{
    EjsVar      *result;

    if (rhs == 0 || lhs->type != rhs->type) {
        if ((result = coerceArrayOperands(ejs, lhs, opcode, rhs)) != 0) {
            return result;
        }
    }

    switch (opcode) {

    case EJS_OP_COMPARE_EQ: case EJS_OP_COMPARE_STRICTLY_EQ:
    case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_GE:
        return (EjsVar*) ejsCreateBoolean(ejs, (lhs == rhs));

    case EJS_OP_COMPARE_NE: case EJS_OP_COMPARE_STRICTLY_NE:
    case EJS_OP_COMPARE_LT: case EJS_OP_COMPARE_GT:
        return (EjsVar*) ejsCreateBoolean(ejs, !(lhs == rhs));

    /*
     *  Unary operators
     */
    case EJS_OP_COMPARE_NOT_ZERO:
        return (EjsVar*) ejs->trueValue;

    case EJS_OP_COMPARE_UNDEFINED:
    case EJS_OP_COMPARE_NULL:
    case EJS_OP_COMPARE_FALSE:
    case EJS_OP_COMPARE_TRUE:
    case EJS_OP_COMPARE_ZERO:
        return (EjsVar*) ejs->falseValue;

    case EJS_OP_LOGICAL_NOT: case EJS_OP_NOT: case EJS_OP_NEG:
        return (EjsVar*) ejs->oneValue;

    /*
     *  Binary operators
     */
    case EJS_OP_DIV: case EJS_OP_MUL: case EJS_OP_REM:
    case EJS_OP_SHR: case EJS_OP_USHR: case EJS_OP_XOR:
        return (EjsVar*) ejs->zeroValue;

#if BLD_FEATURE_EJS_LANG >= EJS_SPEC_PLUS
    /*
     *  Operator overload
     */
    case EJS_OP_ADD:
        result = (EjsVar*) ejsCreateArray(ejs, 0);
        pushArray(ejs, (EjsArray*) result, 1, (EjsVar**) &lhs);
        pushArray(ejs, (EjsArray*) result, 1, (EjsVar**) &rhs);
        return result;

    case EJS_OP_AND:
        return (EjsVar*) makeIntersection(ejs, (EjsArray*) lhs, (EjsArray*) rhs);

    case EJS_OP_OR:
        return (EjsVar*) makeUnion(ejs, (EjsArray*) lhs, (EjsArray*) rhs);

    case EJS_OP_SHL:
        return pushArray(ejs, (EjsArray*) lhs, 1, &rhs);

    case EJS_OP_SUB:
        return (EjsVar*) removeArrayElements(ejs, (EjsArray*) lhs, (EjsArray*) rhs);
#endif

    default:
        ejsThrowTypeError(ejs, "Opcode %d not implemented for type %s", opcode, lhs->type->qname.name);
        return 0;
    }

    mprAssert(0);
}