wmls.c

来自「WAP browser is based on the Wireless App」· C语言 代码 · 共 1,474 行 · 第 1/3 页

C
1,474
字号
            }

            SLOT_POP(gP->sp);
            break;

        case SUB_ASG:
	    tp = bp - *(++ip);
	    if ((gP->sp->type == scriptTypeInteger) && (tp->type == scriptTypeInteger)) {
            	SLOT_TO_INTEGER(gP->sp);
            	SLOT_TO_INTEGER(tp);
            	xp->value.n -= gP->sp->value.n;
	    } else {
            	SLOT_TO_FLOAT(gP->sp);
            	SLOT_TO_FLOAT(tp);
            	//xp->value.f -= gP->sp->value.f;
		flpArg1.d = xp->value.f;
		flpArg2.d = gP->sp->value.f;
		FlpBufferCorrectedSub(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy); 
		xp->value.f = theCompFloat.d;
	    }
            SLOT_FREE(gP->sp);
            break;

        case UMINUS:
	    if (gP->sp->type == scriptTypeInteger) {
            	SLOT_TO_INTEGER(gP->sp);
            	gP->sp->value.n = -gP->sp->value.n;
	    } else {
            	SLOT_TO_FLOAT(gP->sp);
            	gP->sp->value.f = -gP->sp->value.f;
	    }
            break;

        case ADD:
            switch(SlotMixedOp(xp = gP->sp + 1, gP->sp))
            {
            case scriptTypeString:
                SlotStrAppend(xp, gP->sp->value.s, StrLen(gP->sp->value.s));
                break;

            case scriptTypeInteger:
                xp->value.n += gP->sp->value.n;
                break;

            case scriptTypeFloat:
                //xp->value.f += gP->sp->value.f;
		flpArg1.d = xp->value.f;
		flpArg2.d = gP->sp->value.f;
		FlpBufferCorrectedAdd(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy); 
		xp->value.f = theCompFloat.d;
                break;
            }

            SLOT_POP(gP->sp);
            break;

        case SUB:
	    tp = gP->sp + 1;
	    if ((gP->sp->type == scriptTypeInteger) && (tp->type == scriptTypeInteger)) {
            	SLOT_TO_INTEGER_OP(gP->sp);
            	xp->value.n -= gP->sp->value.n;
	    } else {
            	SLOT_TO_FLOAT_OP(gP->sp);
            	//xp->value.f -= gP->sp->value.f;
		flpArg1.d = xp->value.f;
		flpArg2.d = gP->sp->value.f;
		FlpBufferCorrectedSub(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy); 
		xp->value.f = theCompFloat.d;
	    }
            SLOT_FREE(gP->sp);
            break;

        case MUL:
	    tp = gP->sp + 1;
	    if ((gP->sp->type == scriptTypeInteger) && (tp->type == scriptTypeInteger)) {
            	SLOT_TO_INTEGER_OP(gP->sp);
            	xp->value.n *= gP->sp->value.n;
	    } else {
            	SLOT_TO_FLOAT_OP(gP->sp);
            	xp->value.f = gP->sp->value.f * xp->value.f;
	    }
            SLOT_FREE(gP->sp);
            break;

        case DIV:
	    tp = gP->sp + 1;
	    if ((gP->sp->type == scriptTypeInteger) && (tp->type == scriptTypeInteger)) {
            	SLOT_TO_INTEGER_OP(gP->sp);
            	xp->value.n /= gP->sp->value.n;
	    } else {
            	SLOT_TO_FLOAT_OP(gP->sp);
            	xp->value.f = gP->sp->value.f / xp->value.f;
	    }
            SLOT_FREE(gP->sp);
            break;

        case IDIV:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n /= gP->sp->value.n;
	    break;

        case REM:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n %= gP->sp->value.n;
            SLOT_FREE(gP->sp);
            break;

        case B_AND:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n &= gP->sp->value.n;
            SLOT_FREE(gP->sp);
            break;

        case B_OR:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n |= gP->sp->value.n;
            SLOT_FREE(gP->sp);
            break;

        case B_XOR:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n ^= gP->sp->value.n;
            SLOT_FREE(gP->sp);
            break;

        case B_NOT:
            SLOT_TO_INTEGER(gP->sp);
            xp->value.n = ~xp->value.n;
            break;

        case B_LSHIFT:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n <<= gP->sp->value.n;
            SLOT_FREE(gP->sp);
            break;

        case B_RSSHIFT:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n >>= gP->sp->value.n;
            SLOT_FREE(gP->sp);
            break;

        case B_RSZSHIFT:
            SLOT_TO_INTEGER_OP(gP->sp);
            xp->value.n >>= gP->sp->value.n;
            xp->value.n &= 0x7FFFFFFF;
            SLOT_FREE(gP->sp);
            break;

        case EQ:
            switch(SlotMixedOp(xp = gP->sp + 1, gP->sp))
            {
            case scriptTypeString:
                SlotReplace(xp, scriptTypeBoolean, ScriptStrCompare(xp->value.s, gP->sp->value.s) == 0);
                break;

            case scriptTypeInteger:
                SlotReplace(xp, scriptTypeBoolean, xp->value.n == gP->sp->value.n);
                break;

            case scriptTypeFloat:
                SlotReplace(xp, scriptTypeBoolean, xp->value.f == gP->sp->value.f);
                break;
            }

            SLOT_POP(gP->sp);
            break;

        case LE:
            switch(SlotMixedOp(xp = gP->sp + 1, gP->sp))
            {
            case scriptTypeString:
                SlotReplace(xp, scriptTypeBoolean, ScriptStrCompare(xp->value.s, gP->sp->value.s) <= 0);
                break;

            case scriptTypeInteger:
                SlotReplace(xp, scriptTypeBoolean, xp->value.n <= gP->sp->value.n);
                break;

            case scriptTypeFloat:
                SlotReplace(xp, scriptTypeBoolean, xp->value.f <= gP->sp->value.f);
                break;
            }

            SLOT_POP(gP->sp);
            break;

        case LT:
            switch(SlotMixedOp(xp = gP->sp + 1, gP->sp))
            {
            case scriptTypeString:
                SlotReplace(xp, scriptTypeBoolean, ScriptStrCompare(xp->value.s, gP->sp->value.s) < 0);
                break;

            case scriptTypeInteger:
                SlotReplace(xp, scriptTypeBoolean, xp->value.n < gP->sp->value.n);
                break;

            case scriptTypeFloat:
                SlotReplace(xp, scriptTypeBoolean, xp->value.f < gP->sp->value.f);
                break;
            }

            SLOT_POP(gP->sp);
            break;

        case GE:
            switch(SlotMixedOp(xp = gP->sp + 1, gP->sp))
            {
            case scriptTypeString:
                SlotReplace(xp, scriptTypeBoolean, ScriptStrCompare(xp->value.s, gP->sp->value.s) >= 0);
                break;

            case scriptTypeInteger:
                SlotReplace(xp, scriptTypeBoolean, xp->value.n >= gP->sp->value.n);
                break;

            case scriptTypeFloat:
                SlotReplace(xp, scriptTypeBoolean, xp->value.f >= gP->sp->value.f);
                break;
            }

            SLOT_POP(gP->sp);
            break;

        case GT:
            switch(SlotMixedOp(xp = gP->sp + 1, gP->sp))
            {
            case scriptTypeString:
                SlotReplace(xp, scriptTypeBoolean, ScriptStrCompare(xp->value.s, gP->sp->value.s) > 0);
                break;

            case scriptTypeInteger:
                SlotReplace(xp, scriptTypeBoolean, xp->value.n > gP->sp->value.n);
                break;

            case scriptTypeFloat:
                SlotReplace(xp, scriptTypeBoolean, xp->value.f > gP->sp->value.f);
                break;
            }

            SLOT_POP(gP->sp);
            break;

        case NE:
            switch(SlotMixedOp(xp = gP->sp + 1, gP->sp))
            {
            case scriptTypeString:
                SlotReplace(xp, scriptTypeBoolean, ScriptStrCompare(xp->value.s, gP->sp->value.s) != 0);
                break;

            case scriptTypeInteger:
                SlotReplace(xp, scriptTypeBoolean, xp->value.n != gP->sp->value.n);
                break;

            case scriptTypeFloat:
                SlotReplace(xp, scriptTypeBoolean, xp->value.f != gP->sp->value.f);
                break;
            }

            SLOT_POP(gP->sp);
            break;

        case NOT:
            SLOT_TO_BOOLEAN(gP->sp);
            gP->sp->value.n = !gP->sp->value.n;
            break;

        case SCAND:
            if(SLOT_IS_FALSE(gP->sp))
            {
                SLOT_PUSH_FALSE(gP->sp);
            }
            break;

        case SCOR:
            SLOT_TO_BOOLEAN(gP->sp);
            if(gP->sp->type != scriptTypeBoolean || gP->sp->value.n)
            {
                SLOT_PUSH_FALSE(gP->sp);
            }
            else
                gP->sp->value.n = WMLS_TRUE;
            break;

        case TOBOOL:
            SLOT_TO_BOOLEAN(gP->sp);
            break;

        case POP:
            SLOT_POP(gP->sp);
            break;

        case TYPEOF:
	    SlotReplace(gP->sp, scriptTypeInteger, gP->sp->type);
            break;

        case ISVALID:
            SlotFree(gP->sp);
            gP->sp->value.n = (gP->sp->type == scriptTypeInvalid) ? WMLS_TRUE : WMLS_FALSE;
            gP->sp->type = scriptTypeBoolean;
            break;

        case RETURN:
            goto __cleanup_vars;

        case RETURN_ES:
            SLOT_PUSH_STRING(gP->sp, NULL);
            goto __cleanup_vars;

        case DBG:
        case RESERVED_3D:
        case RESERVED_3E:
        case RESERVED_3F:
            goto __illegal_instruction;

        case STORE_VAR_0:       case STORE_VAR_1:       case STORE_VAR_2:       case STORE_VAR_3:
        case STORE_VAR_4:       case STORE_VAR_5:       case STORE_VAR_6:       case STORE_VAR_7:
        case STORE_VAR_8:       case STORE_VAR_9:       case STORE_VAR_10:      case STORE_VAR_11:
        case STORE_VAR_12:      case STORE_VAR_13:      case STORE_VAR_14:      case STORE_VAR_15:
            SLOT_SAVE_VAR(gP->sp, bp - (0x0F & *ip));
            break;

        case LOAD_CONST_0:      case LOAD_CONST_1:      case LOAD_CONST_2:      case LOAD_CONST_3:
        case LOAD_CONST_4:      case LOAD_CONST_5:      case LOAD_CONST_6:      case LOAD_CONST_7:
        case LOAD_CONST_8:      case LOAD_CONST_9:      case LOAD_CONST_10:     case LOAD_CONST_11:
        case LOAD_CONST_12:     case LOAD_CONST_13:     case LOAD_CONST_14:     case LOAD_CONST_15:
            SLOT_PUSH_VAR(gP->sp, m->const_pool + (0x0F & *ip));
            break;

        case CALL_0:            case CALL_1:            case CALL_2:            case CALL_3:
        case CALL_4:            case CALL_5:            case CALL_6:            case CALL_7:
            err = ScriptFuncCall(gP, m, 0x07 & *ip);
            if(err) return err;
            break;

        case CALL_LIB_0:        case CALL_LIB_1:        case CALL_LIB_2:        case CALL_LIB_3:
        case CALL_LIB_4:        case CALL_LIB_5:        case CALL_LIB_6:        case CALL_LIB_7:
            err = ScriptLibFuncCall(gP, *(++ip), 0x07 & *ip);
            if(err) return err;

            break;

        case INCR_VAR_0:        case INCR_VAR_1:        case INCR_VAR_2:        case INCR_VAR_3:
        case INCR_VAR_4:        case INCR_VAR_5:        case INCR_VAR_6:        case INCR_VAR_7:
            //SLOT_TO_INTEGER(bp - (0x07 & *ip));
            //xp->value.n++;
	    tp = bp - (0x07 & *ip);
	    if (tp->type == scriptTypeInteger) {
            	SLOT_TO_INTEGER(tp);
            	xp->value.n++;
	    }
	    else {
            	SLOT_TO_FLOAT(tp);
	    	//xp->value.f++;
		flpArg1.d = xp->value.f;
		flpArg2.d = 1.0;
		FlpBufferCorrectedAdd(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy); 
		xp->value.f = theCompFloat.d;
	    }
            break;

        case RESERVED_78:       case RESERVED_79:       case RESERVED_7A:       case RESERVED_7B:
        case RESERVED_7C:       case RESERVED_7D:       case RESERVED_7E:       case RESERVED_7F:
            goto __illegal_instruction;

        case JUMP_FW_0:         case JUMP_FW_1:         case JUMP_FW_2:         case JUMP_FW_3:
        case JUMP_FW_4:         case JUMP_FW_5:         case JUMP_FW_6:         case JUMP_FW_7:
        case JUMP_FW_8:         case JUMP_FW_9:         case JUMP_FW_10:        case JUMP_FW_11:
        case JUMP_FW_12:        case JUMP_FW_13:        case JUMP_FW_14:        case JUMP_FW_15:
        case JUMP_FW_16:        case JUMP_FW_17:        case JUMP_FW_18:        case JUMP_FW_19:
        case JUMP_FW_20:        case JUMP_FW_21:        case JUMP_FW_22:        case JUMP_FW_23:
        case JUMP_FW_24:        case JUMP_FW_25:        case JUMP_FW_26:        case JUMP_FW_27:
        case JUMP_FW_28:        case JUMP_FW_29:        case JUMP_FW_30:        case JUMP_FW_31:
            ip += (0x1F & *ip);
            break;

        case JUMP_BW_0:         case JUMP_BW_1:         case JUMP_BW_2:         case JUMP_BW_3:
        case JUMP_BW_4:         case JUMP_BW_5:         case JUMP_BW_6:         case JUMP_BW_7:
        case JUMP_BW_8:         case JUMP_BW_9:         case JUMP_BW_10:        case JUMP_BW_11:
        case JUMP_BW_12:        case JUMP_BW_13:        case JUMP_BW_14:        case JUMP_BW_15:
        case JUMP_BW_16:        case JUMP_BW_17:        case JUMP_BW_18:        case JUMP_BW_19:
        case JUMP_BW_20:        case JUMP_BW_21:        case JUMP_BW_22:        case JUMP_BW_23:
        case JUMP_BW_24:        case JUMP_BW_25:        case JUMP_BW_26:        case JUMP_BW_27:
        case JUMP_BW_28:        case JUMP_BW_29:        case JUMP_BW_30:        case JUMP_BW_31:
            ip -= (0x1F & *ip);
            continue;

        case TJUMP_FW_0:        case TJUMP_FW_1:        case TJUMP_FW_2:        case TJUMP_FW_3:
        case TJUMP_FW_4:        case TJUMP_FW_5:        case TJUMP_FW_6:        case TJUMP_FW_7:
        case TJUMP_FW_8:        case TJUMP_FW_9:        case TJUMP_FW_10:       case TJUMP_FW_11:
        case TJUMP_FW_12:       case TJUMP_FW_13:       case TJUMP_FW_14:       case TJUMP_FW_15:
        case TJUMP_FW_16:       case TJUMP_FW_17:       case TJUMP_FW_18:       case TJUMP_FW_19:
        case TJUMP_FW_20:       case TJUMP_FW_21:       case TJUMP_FW_22:       case TJUMP_FW_23:
        case TJUMP_FW_24:       case TJUMP_FW_25:       case TJUMP_FW_26:       case TJUMP_FW_27:
        case TJUMP_FW_28:       case TJUMP_FW_29:       case TJUMP_FW_30:       case TJUMP_FW_31:
            if(SLOT_IS_FALSE(gP->sp)) ip += (0x1F & *ip);
            SLOT_POP(gP->sp);
            break;

        case LOAD_VAR_0:        case LOAD_VAR_1:        case LOAD_VAR_2:        case LOAD_VAR_3:
        case LOAD_VAR_4:        case LOAD_VAR_5:        case LOAD_VAR_6:        case LOAD_VAR_7:
        case LOAD_VAR_8:        case LOAD_VAR_9:        case LOAD_VAR_10:       case LOAD_VAR_11:
        case LOAD_VAR_12:       case LOAD_VAR_13:       case LOAD_VAR_14:       case LOAD_VAR_15:
        case LOAD_VAR_16:       case LOAD_VAR_17:       case LOAD_VAR_18:       case LOAD_VAR_19:
        case LOAD_VAR_20:       case LOAD_VAR_21:       case LOAD_VAR_22:       case LOAD_VAR_23:
        case LOAD_VAR_24:       case LOAD_VAR_25:       case LOAD_VAR_26:       case LOAD_VAR_27:
        case LOAD_VAR_28:       case LOAD_VAR_29:       case LOAD_VAR_30:       case LOAD_VAR_31:
            SLOT_PUSH_VAR(gP->sp, bp - (0x1F & *ip));
            break;
        }
        
        ip++;
    }

    SLOT_PUSH_STRING(gP->sp, NULL);

__cleanup_vars:
    xp = gP->sp++; // save stack top value
    while(gP->sp <= bp) { SLOT_POP(gP->sp); }
    
    *bp = *xp, gP->sp = bp;
    return errNone;

__illegal_instruction:
    return scriptErrIllegalInstruction;

__verification_failed:
    return scriptErrVerificationFailed;
}

static Err ScriptLibFuncCall(ScriptLibGlobals *gP, UInt16 lindex, UInt8 findex)
{
    Err err;
    UInt16 argc = 0;
    ScriptSlot result;

    // prepare result slot
    result.type = scriptTypeString;
    result.value.s = NULL;

    // invoke library function
    if(lindex >= STDLIB_COUNT)
        err = gP->hostP->LibraryCall(lindex, findex, &argc, gP->sp, &result);
    else
        err = ScriptStdFuncCall(gP, lindex, findex, &argc, gP->sp, &result);

    // clean up parameters in the stack
    while(argc-- > 0) { SLOT_POP(gP->sp); }

    // place result on the top of the stack
    SLOT_ALLOC(gP->sp);
    gP->sp->type    = result.type;
    gP->sp->value.a = result.value.a;

    return err;
}

static Err ScriptUrlFuncCall(ScriptLibGlobals *gP, UInt16 uindex, UInt8 findex)
{
    // TODO: implement me!!!
    return scriptErrNotImplemented;
}

/////////////////////////////////////////////////////////////////////////////////////////

Char *ScriptStrCopy(const Char *str)
{
    return ScriptStrCopyEx(str, str ? StrLen(str) : 0);
}

Char *ScriptStrCopyEx(const Char *str, UInt16 len)
{
    Char *res;

    if(!str) return NULL;

    res = MemPtrNew(len + 1);
    if(!res) return NULL;

    StrNCopy(res, str, len);
    *(res + len) = 0;
    return res;
}

void ScriptStrFree(Char *str)
{
    if(str) MemPtrFree(str);
}

Int16 ScriptStrCompare(Char *s1, Char *s2)
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?