Esempio n. 1
0
void DoShift( void )
{
    stack_entry *left;
    int          shift;

    left = StkEntry( 1 );
    RValue( ExprSP );
    ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 0 );
    shift = I32FetchTrunc( ExprSP->v.sint );
    RValue( left );
    switch( left->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        if( shift >= 0 ) {
            U64ShiftL( &left->v.uint, shift, &left->v.uint );
        } else if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) {
            U64ShiftR( &left->v.uint, -shift, &left->v.uint );
        } else {
            I64ShiftR( &left->v.sint, -shift, &left->v.sint );
        }
        break;
    default:
        Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) );
        break;
    }
    CombineEntries( left, left, ExprSP );
}
Esempio n. 2
0
RValue Inst::Deref(CodeContext& context, RValue value, bool recursive)
{
	auto retVal = RValue(value.value(), value.stype());
	while (retVal.stype()->isPointer()) {
		retVal = RValue(new LoadInst(retVal, "", context), retVal.stype()->subType());
		if (!recursive)
			break;
	}
	return retVal;
}
Esempio n. 3
0
/* ApplyBinary - apply a binary operator to operands */
static void ApplyBinary(EvalState *c, int op, PVAL *left, PVAL *right)
{
    RValue(c, right);
    if (op == '=') {
        if (left->type != TYPE_VARIABLE)
            Error(c, "expecting a variable to the left of '='");
        left->v.var->value = right->v.value;
        left->v.var->bound = TRUE;
        left->type = TYPE_NUMBER;
        left->v.value = right->v.value;
    }
    else {
        RValue(c, left);
        switch (op) {
        case '|':
            left->v.value = (VALUE)((int)left->v.value | (int)right->v.value);
            break;
        case '^':
            left->v.value = (VALUE)((int)left->v.value ^ (int)right->v.value);
            break;
        case '&':
            left->v.value = (VALUE)((int)left->v.value & (int)right->v.value);
            break;
        case TKN_SHL:
            left->v.value = (VALUE)((int)left->v.value << (int)right->v.value);
            break;
        case TKN_SHR:
            left->v.value = (VALUE)((int)left->v.value >> (int)right->v.value);
            break;
        case '+':
            left->v.value += right->v.value;
            break;
        case '-':
            left->v.value -= right->v.value;
            break;
        case '*':
            left->v.value *= right->v.value;
            break;
        case '/':
            if ((int)right->v.value == 0)
                Error(c, "division by zero");
            left->v.value /= right->v.value;
            break;
        case '%':
            if ((int)left->v.value == 0)
                Error(c, "division by zero");
            left->v.value = (VALUE)((int)left->v.value % (int)right->v.value);
            break;
        default:
            Error(c, "internal error in ApplyFunction -- '%c' (%d)", op, op);
            break;
        }
    }
}
Esempio n. 4
0
RValue Inst::Cmp(int type, RValue lhs, RValue rhs, CodeContext& context)
{
	if (CastMatch(context, lhs, rhs))
		return RValue();
	auto pred = getPredicate(type, lhs.stype(), context);
	auto cmpType = lhs.stype()->isVec()? lhs.stype()->subType() : lhs.stype();
	auto op = cmpType->isFloating()? Instruction::FCmp : Instruction::ICmp;
	auto cmp = CmpInst::Create(op, pred, lhs, rhs, "", context);
	auto retType = lhs.stype()->isVec()?
		SType::getVec(context, SType::getBool(context), lhs.stype()->size()) :
		SType::getBool(context);
	return RValue(cmp, retType);
}
Esempio n. 5
0
RValue Inst::SizeOf(CodeContext& context, SType* type)
{
	if (!type) {
		return RValue();
	} else if (type->isAuto()) {
		context.addError("size of auto is invalid");
		return RValue();
	} else if (type->isVoid()) {
		context.addError("size of void is invalid");
		return RValue();
	}
	auto itype = SType::getInt(context, 64, true);
	auto size = ConstantInt::get(*itype, SType::allocSize(context, type));
	return RValue(size, itype);
}
Esempio n. 6
0
void Pdb::Explorer()
{
	VectorMap<String, Value> prev = DataMap(explorer);
	explorer.Clear();
	try {
		String x = ~expexp;
		if(!IsNull(x)) {
			CParser p(x);
			Val v = Exp(p);
			Vis(explorer, "=", prev, Visualise(v));
			if(v.type >= 0 && v.ref == 0 && !v.rvalue)
				Explore(v, prev);
			if(v.ref > 0 && GetRVal(v).address)
				for(int i = 0; i < 20; i++)
					Vis(explorer, Format("[%d]", i), prev, Visualise(DeRef(Compute(v, RValue(i), '+'))));
		}
	}
	catch(CParser::Error e) {
		Visual v;
		v.Cat(e, LtRed);
		explorer.Add("", RawPickToValue(v));
	}
	exback.Enable(exprev.GetCount());
	exfw.Enable(exnext.GetCount());
}
Esempio n. 7
0
static int EndTry( void )
{
    int         parent_scope;
    TREEPTR     expr;
    TREEPTR     func;
    TREEPTR     tree;
    TYPEPTR     typ;
    int         expr_type;

    DropBreakLabel();           /* _leave jumps to this label */
    parent_scope = BlockStack->parent_index;
    tree = LeafNode( OPR_TRY );
    tree->op.st.try_index = BlockStack->try_index;
    tree->op.st.parent_scope = parent_scope;
    AddStmt( tree );
    if( (CurToken == T__EXCEPT) || (CurToken == T___EXCEPT) ) {
        NextToken();
        BlockStack->block_type = T__EXCEPT;
        BlockStack->break_label = NextLabel();
        Jump( BlockStack->break_label );
        DeadCode = 0;
        tree = LeafNode( OPR_EXCEPT );
        tree->op.st.try_sym_handle = DummyTrySymbol();
        tree->op.st.parent_scope = parent_scope;
        AddStmt( tree );
        CompFlags.exception_filter_expr = 1;
        expr = RValue( BracketExpr() );
        CompFlags.exception_filter_expr = 0;
        CompFlags.exception_handler = 1;
        typ = TypeOf( expr );
        expr_type = DataTypeOf( typ );
        if( expr_type != TYPE_VOID ) {
            if( expr_type > TYPE_ULONG ) {
                CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
            }
        }
        func = VarLeaf( SymGetPtr( SymExcept ), SymExcept );
        func->op.opr = OPR_FUNCNAME;
        expr = ExprNode( NULL, OPR_PARM, expr );
        expr->expr_type = typ;
        expr->op.result_type = typ;
        tree = ExprNode( func, OPR_CALL, expr );
        tree->expr_type = GetType( TYPE_VOID );
        AddStmt( tree );
        return( 1 );
    } else if( (CurToken == T__FINALLY) || (CurToken == T___FINALLY) ) {
        CompFlags.in_finally_block = 1;
        NextToken();
        BlockStack->block_type = T__FINALLY;
        DeadCode = 0;
        tree = LeafNode( OPR_FINALLY );
        tree->op.st.try_sym_handle = DummyTrySymbol();
        tree->op.st.parent_scope = parent_scope;
        AddStmt( tree );
        return( 1 );
    }
    return( 0 );
}
Esempio n. 8
0
RValue Inst::PointerMath(int type, RValue ptr, RValue val, CodeContext& context)
{
	if (type != ParserBase::TT_INC && type != ParserBase::TT_DEC) {
		context.addError("pointer arithmetic only valid using ++/-- operators");
		return ptr;
	}
	auto ptrVal = GetElementPtrInst::Create(ptr, val.value(), "", context);
	return RValue(ptrVal, ptr.stype());
}
Esempio n. 9
0
void DoPlus( void )
{
    stack_entry *left;

    left = StkEntry( 1 );
    LRValue( left );
    RValue( ExprSP );
    switch( ExprSP->info.kind ) {
    case TK_POINTER:
    case TK_ADDRESS:
        /* get the pointer as the left operand */
        left = ExprSP;
        SwapStack( 1 );
    }
    AddOp( left, ExprSP );
    switch( left->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        U64Add( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
        break;
    case TK_POINTER:
    case TK_ADDRESS:
        switch( ExprSP->info.kind ) {
        case TK_BOOL:
        case TK_ENUM:
        case TK_CHAR:
        case TK_INTEGER:
            break;
        default:
            Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) );
        }
        if( (left->info.modifier & TM_MOD_MASK) == TM_NEAR ) {
            //NYI: 64 bit offsets
            left->v.addr.mach.offset += U32FetchTrunc( ExprSP->v.uint );
        } else {
            //NYI: 64 bit offsets
            left->v.addr = AddrAdd( left->v.addr, U32FetchTrunc( ExprSP->v.uint ) );
        }
        break;
    case TK_REAL:
        LDAdd( &left->v.real, &ExprSP->v.real, &left->v.real );
        break;
    case TK_COMPLEX:
        LDAdd( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re );
        LDAdd( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im );
        break;
    default:
        Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) );
        break;
    }
    CombineEntries( left, left, ExprSP );
}
Esempio n. 10
0
void ExprValue( stack_entry *entry )
{
    ExprResolve( entry );
    AddressExpression( entry );
    switch( entry->info.kind ) {
    case TK_STRUCT:
    case TK_ARRAY:
        break;
    default:
        RValue( entry );
    }
}
Esempio n. 11
0
void DoMinus( void )
{
    stack_entry *left;

    left = StkEntry( 1 );
    LRValue( left );
    RValue( ExprSP );
    AddOp( left, ExprSP );
    switch( left->info.kind ) {
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_INTEGER:
        U64Sub( &left->v.uint, &ExprSP->v.uint, &left->v.uint );
        left->info.modifier = TM_SIGNED;
        break;
    case TK_POINTER:
    case TK_ADDRESS:
        switch( ExprSP->info.kind ) {
        case TK_BOOL:
        case TK_CHAR:
        case TK_ENUM:
        case TK_INTEGER:
            //NYI: 64 bit offsets
            left->v.addr = AddrAdd( left->v.addr, -U32FetchTrunc( ExprSP->v.uint ) );
            break;
        case TK_POINTER:
        case TK_ADDRESS:
            I32ToI64( AddrDiff( left->v.addr, ExprSP->v.addr ), &left->v.sint );
            left->info.kind = TK_INTEGER;
            left->info.modifier = TM_SIGNED;
            left->info.size = sizeof( signed_64 );
            left->th = NULL;
            break;
        default:
            Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) );
        }
        break;
    case TK_REAL:
        LDSub( &left->v.real, &ExprSP->v.real, &left->v.real );
        break;
    case TK_COMPLEX:
        LDSub( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re );
        LDSub( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im );
        break;
    default:
        Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) );
        break;
    }
    CombineEntries( left, left, ExprSP );
}
Esempio n. 12
0
static void SwitchStmt( void )
{
    SWITCHPTR   sw;
    TREEPTR     tree;
    TYPEPTR     typ;
    int         switch_type;

    StartNewBlock();
    NextToken();
    sw = (SWITCHPTR)CMemAlloc( sizeof( SWITCHDEFN ) );
    sw->prev_switch = SwitchStack;
    sw->low_value = ~0l;
    sw->high_value = 0;
    sw->case_format = "%ld";        /* assume signed cases */
    SwitchStack = sw;
    switch_type = TYPE_INT;         /* assume int */
    tree = RValue( BracketExpr() );
    typ = TypeOf( tree );
    if( typ->decl_type == TYPE_ENUM ) typ = typ->object;
    if( typ->decl_type == TYPE_UFIELD ) {
        if( typ->u.f.field_width == (TARGET_INT * 8) ) {
            sw->case_format = "%lu";
            switch_type = TYPE_UINT;
        }
    }
    switch( typ->decl_type ) {
    case TYPE_USHORT:
    case TYPE_UINT:
        sw->case_format = "%lu";
        switch_type = TYPE_UINT;
    case TYPE_CHAR:
    case TYPE_UCHAR:
    case TYPE_SHORT:
    case TYPE_INT:
    case TYPE_FIELD:
    case TYPE_UFIELD:
        break;
    case TYPE_ULONG:
        sw->case_format = "%lu";
        switch_type = TYPE_ULONG;
        break;
    case TYPE_LONG:
        switch_type = TYPE_LONG;
        break;
    default:
        CErr1( ERR_INVALID_TYPE_FOR_SWITCH );
    }
    tree = ExprNode( 0, OPR_SWITCH, tree );
    tree->op.switch_info = sw;
    AddStmt( tree );
}
Esempio n. 13
0
RValue Inst::BinaryOp(int type, RValue lhs, RValue rhs, CodeContext& context)
{
	if (!lhs || !rhs)
		return RValue();

	if (CastMatch(context, lhs, rhs, true))
		return RValue();

	switch ((lhs.stype()->isPointer() << 1) | rhs.stype()->isPointer()) {
	default:
	case 0: // no pointer
	{
		auto llvmOp = getOperator(type, lhs.stype(), context);
		return RValue(BinaryOperator::Create(llvmOp, lhs, rhs, "", context), lhs.stype());
	}
	case 1: // lhs != ptr, rhs == ptr
		swap(lhs, rhs);
	case 2: // lhs == ptr, rhs != ptr
		return PointerMath(type, lhs, rhs, context);
	case 3: // both ptr
		context.addError("can't perform operation with two pointers");
		return lhs;
	}
}
Esempio n. 14
0
/* PopAndEvaluate - pop operators and apply them until a '(' or TKN_FCALL token is found */
static int PopAndEvaluate(EvalState *c)
{
    int tkn;
    for (;;) {
        if (oStackIsEmpty(c))
            Error(c, "mismatched parens");
        if ((tkn = oStackTop(c)) == '(' || tkn == TKN_FCALL_ARGS)
            break;
        oStackDrop(c);
        Apply(c, tkn);
    }
    RValue(c, c->rStackPtr);
    if (tkn == TKN_FCALL_ARGS)
        ++c->argc;
    return tkn;
}
Esempio n. 15
0
/* ApplyUnary - apply a unary operator to an operand */
static void ApplyUnary(EvalState *c, int op, PVAL *pval)
{
    RValue(c, pval);
    switch (op) {
    case TKN_UNARY_MINUS:
        pval->v.value = -pval->v.value;
        break;
    case '~':
        pval->v.value = (VALUE)~((int)pval->v.value);
        break;
    case TKN_FCALL:
    case TKN_FCALL_ARGS:
        break;
    default:
        Error(c, "internal error in UnaryApply -- '%c' (%d)", op, op);
        break;
    }
}
Esempio n. 16
0
static void DoMinusScaled( void )
{
    stack_entry *left;

    left = StkEntry( 1 );
    LRValue( left );
    RValue( ExprSP );
    switch( left->info.kind ) {
    case TK_POINTER:
        switch( ExprSP->info.kind ) {
        case TK_POINTER:
            /* Have to check if base type sizes are the same */
            PushBaseSize();
            DupStack();
            SwapStack( 3 );
            PushBaseSize();
            MoveSP( 1 );
            SwapStack( 3 );
            MoveSP( -1 );
            if( !TstEQ( 1 ) ) {
                Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
            }
            PopEntry();
            MoveSP( 1 );
            DoMinus();
            MoveSP( -1 );
            DoDiv();
            return;
        default:
            ScaleInt();
            break;
        }
        break;
    default:
        switch( ExprSP->info.kind ) {
        case TK_POINTER:
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
            break;
        }
    }
    DoMinus();
}
Esempio n. 17
0
static void ReturnStmt( SYM_HANDLE func_result, struct return_info *info )
{
    TREEPTR             tree;
    BLOCKPTR            block;
    enum return_with    with;

    NextToken();
    if( CurToken != T_SEMI_COLON ) {
        TYPEPTR     func_type;

        func_type = CurFunc->sym_type->object;
        SKIP_TYPEDEFS( func_type );
        tree = RValue( Expr() );
        ChkRetType( tree );
        tree = BoolConv( func_type, tree );
        tree = FixupAss( tree, func_type );
        tree = ExprNode( 0, OPR_RETURN, tree );
        tree->expr_type = func_type;
        tree->op.sym_handle = func_result;
        AddStmt( tree );
        with = RETURN_WITH_EXPR;
        info->with_expr = TRUE;
    } else {
        with = RETURN_WITH_NO_EXPR;
    }
    if( info->with == RETURN_WITH_NONE ) {
        info->with = with;
    }
    if( info->with != with ) {
        CErr1( ERR_INCONSISTENT_USE_OF_RETURN );
    }
    block = BlockStack;                                 /* 16-apr-94 */
    while( block != NULL ) {
        if( (block->block_type == T__TRY) || (block->block_type == T___TRY) )
            break;
        block = block->prev_block;
    }
    if( block != NULL ) {
        UnWindTry( -1 );
    }
}
Esempio n. 18
0
static void DoPlusScaled( void )
{
    stack_entry         *left;

    left = StkEntry( 1 );
    LRValue( left );
    RValue( ExprSP );
    switch( left->info.kind ) {
    case TK_POINTER:
        ScaleInt();
        break;
    default:
        switch( ExprSP->info.kind ) {
        case TK_POINTER:
            SwapStack( 1 );
            ScaleInt();
            break;
        }
    }
    DoPlus();
}
Esempio n. 19
0
RState* RSNrValue::Shift(addr_t v, int32 token, RElem** head)
{
	if (token == tIdent)
	{
		int32 id = v;
		if (ResolveIdentifier(v))
			RAddElement(head, RValue(v), fSize, this);
		else
			error("Unknown identifier: %s", ST_Ident(id));
	}
	else if (token == tInt)
		RAddElement(head, (REval *)v, fSize, this);
	else if (fHasDefault)
	{
		RAddElement(head, (REval *)fValue, fSize, this);
		return fNext->Shift(v, token, head);
	}
	else
		error("internal error 3");

	return RSValue::Shift(v, token, head);
} /* RSNrValue::Shift */
Esempio n. 20
0
static unsigned MechStack( unsigned select, unsigned parm )
{
    unsigned    result = 0;
    stack_entry *entry;
    sym_info    info;

    switch( select ) {
    case 0:
        SwapStack( parm );
        break;
    case 1:
        MoveSP( parm );
        break;
    case 2:
        entry = StkEntry( parm );
        LValue( entry );
        result = TypeInfoToClass( &entry->info ) & (BASE_TYPE | STK_UNSIGNED);
        break;
    case 3:
        ExprValue( StkEntry( parm ) );
        break;
    case 4:
        LValue( StkEntry( parm ) );
        break;
    case 5:
        RValue( StkEntry( parm ) );
        break;
    case 6:
        LRValue( StkEntry( parm ) );
        break;
    case 7:
        entry = StkEntry( parm );
        LValue( entry );
        result = TI_CREATE( entry->info.kind, TM_NONE, 0 );
        break;
    case 8:
        entry = StkEntry( parm );
        NameResolve( entry, FALSE );
        if( entry->flags & SF_SYM ) {
            SymInfo( entry->v.sh, entry->lc, &info );
            result = info.kind;
        } else {
            result = SK_NONE;
        }
        break;
    case 9:
        entry = StkEntry( parm );
        result = NameResolve( entry, FALSE );
        break;
    case 10:
        entry = StkEntry( parm );
        if( entry->flags & SF_NAME ) {
            result = 0;
        } else if( entry->flags & SF_SYM ) {
            result = 1;
        } else if( entry->flags & SF_LOCATION ) {
            result = 2;
        } else {
            result = 3;
        }
        break;
    }
    return( result );
}
Esempio n. 21
0
static unsigned MechMisc( unsigned select, unsigned parm )
{
    long                value;
    unsigned            result = 0;
    mad_type_info       mti;

    switch( select ) {
    case 0:
        ExprAddrDepth += parm;
        result = ExprAddrDepth;
        break;
    case 1:
        if( _IsOn( SW_EXPR_IS_CALL ) && ExprAddrDepth == 0 ) {
            result = TRUE;
        } else {
            result = FALSE;
        }
        break;
    case 2:
        SkipCount += parm;
        break;
    case 3:
        result = SkipCount;
        break;
    case 4:
        //never called
        break;
    case 5:
        if( ScanSavePtr >= MAX_SCANSAVE_PTRS )
            Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANSAVE ) );
        CurrScan[ScanSavePtr++] = ScanPos();
        break;
    case 6:
        if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
        ReScan( CurrScan[--ScanSavePtr] );
        break;
    case 7:
        if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
        --ScanSavePtr;
        break;
    case 8:
        if( parm ) {        /* start scan string */
            scan_string = TRUE;
            ReScan( ScanPos() );
        } else {            /* end scan string */
            scan_string = FALSE;
            ReScan( ScanPos() );
        }
        break;
    case 9:
        ReScan( ScanPos() + (int)parm );
        break;
    case 10:
        AddChar();
        break;
    case 11:
        AddCEscapeChar();
        break;
    case 12:
        AddActualChar( '\0' );
        break;
    case 13:
        ScanCCharNum = parm;
        break;
    case 14:
        if( NestedCallLevel == MAX_NESTED_CALL - 1 ) {
            Error( ERR_NONE, LIT( ERR_TOO_MANY_CALLS ) );
        } else {
            PgmStackUsage[ ++NestedCallLevel ] = 0;
        }
        break;
    case 15:
        RValue( ExprSP );
        ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
        value = U32FetchTrunc( ExprSP->v.uint ) - 1;
        PopEntry();
        if( ExprSP->info.kind == TK_STRING ) {
            if( value < 0 || value >= ExprSP->info.size ) {
                Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
            }
            LocationAdd( &ExprSP->v.string.loc, value*8 );
            ExprSP->info.size -= value;
            ExprSP->v.string.ss_offset = value;
        } else {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
        break;
    case 16:
        RValue( ExprSP );
        ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
        value = U32FetchTrunc( ExprSP->v.sint ) - 1;
        PopEntry();
        if( ExprSP->info.kind == TK_STRING ) {
            value -= ExprSP->v.string.ss_offset;
            if( value < 0 || value >= ExprSP->info.size ) {
                Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
            }
            ExprSP->info.size = value;
        } else {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
        break;
    case 17:
        EvalSubstring = parm;
        if( parm ) ExprSP->v.string.ss_offset = 0;
        break;
    case 18:
        result = EvalSubstring;
        break;
    case 19:
        FreePgmStack( TRUE );
        break;
    case 20:
        switch( parm ) { // nyi - begin temp
        case SSL_CASE_SENSITIVE:
            _SwitchOn( SW_CASE_SENSITIVE );
            break;
        case SSL_SIDE_EFFECT:
            _SwitchOn( SW_SIDE_EFFECT );
            break;
        //case SSL_32_BIT:
        //    _SwitchOn( SW_32_BIT );
        //    break;
        }
        break;
    case 21:
        switch( parm ) {
        case SSL_CASE_SENSITIVE:
            _SwitchOff( SW_CASE_SENSITIVE );
            break;
        case SSL_SIDE_EFFECT:
            _SwitchOff( SW_SIDE_EFFECT );
            break;
        //case SSL_32_BIT:
        //    _SwitchOff( SW_32_BIT );
        //    break;
        }
        break;
    case 22:
        switch( parm ) {
        case SSL_CASE_SENSITIVE:
            result = _IsOn( SW_CASE_SENSITIVE );
            break;
        case SSL_SIDE_EFFECT:
            result = _IsOn( SW_SIDE_EFFECT );
            break;
        case SSL_32_BIT:
            GetMADTypeDefault( MTK_INTEGER, &mti );
            result = (mti.b.bits >= 32);
            break;
        }
        break;
    case 23: // nyi - end temp
        MarkArrayOrder( parm );
        break;
    case 24:
        StartSubscript();
        break;
    case 25:
        AddSubscript();
        break;
    case 26:
        EndSubscript();
        break;
    }
    return( result );
}
Esempio n. 22
0
/* EvalExpr - Eval and evaluate an expression using the shunting yard algorithm */
int EvalExpr(EvalState *c, const char *str, VALUE *pValue)
{
    int unaryPossible = TRUE;
    int tkn, count, prec, op;
    PVAL pval;
    
    /* setup an error target */
    if (setjmp(c->errorTarget))
        return FALSE;
        
    /* initialize the parser */
    c->linePtr = (char *)str;
    c->savedToken = TKN_NONE;
    
    /* initialize the operator and operand stacks */
    c->oStackPtr = c->oStack - 1;
    c->rStackPtr = c->rStack - 1;
    
    /* handle each input token */
    while ((tkn = GetToken(c, &pval)) != TKN_EOF) {
        switch (tkn) {
        case TKN_IDENTIFIER:
        case TKN_NUMBER:
            if (!unaryPossible)
                Error(c, "syntax error");
            rStackPush(c, pval);
            unaryPossible = FALSE;
            break;
        case TKN_FCALL:
            oStackPush(c, c->argc);
            oStackPushData(c, c->fcn);
            oStackPush(c, tkn);
            c->fcn = pval.v.fcn;
            c->argc = 0;
            unaryPossible = FALSE;
            break;
        case '(':
            if (oStackTop(c) == TKN_FCALL)
                c->oStackPtr->op = TKN_FCALL_ARGS;
            else
                oStackPush(c, tkn);
            unaryPossible = TRUE;
            break;
        case ',':
            if (PopAndEvaluate(c) != TKN_FCALL_ARGS)
                Error(c, "argument list outside of a function call");
            unaryPossible = FALSE;
            break;
        case ')':
            tkn = PopAndEvaluate(c);
            oStackDrop(c);
            if (tkn == TKN_FCALL || tkn == TKN_FCALL_ARGS)
                CallFunction(c);
            unaryPossible = FALSE;
            break;
        default:
            if (unaryPossible && tkn == '-')
                tkn = TKN_UNARY_MINUS;
            if (unaryPossible && !Unary(tkn))
                Error(c, "syntax error");
            prec = Prec(c, tkn);
            while (!oStackIsEmpty(c)) {
                int stackPrec = Prec(c, oStackTop(c));
                if ((Assoc(tkn) == ASSOC_LEFT && prec > stackPrec) || prec >= stackPrec)
                    break;
                op = oStackTop(c);
                oStackDrop(c);
                if (op == TKN_FCALL)
                    CallFunction(c);
                else
                    Apply(c, op);
            }
            oStackPush(c, tkn);
            unaryPossible = TRUE;
            break;
        }
    }
    
    /* apply all of the remaining operands on the operator stack */
    while (!oStackIsEmpty(c)) {
        int op = oStackTop(c);
        oStackDrop(c);
        if (op == '(')
            Error(c, "mismatched parens");
        if (op == TKN_FCALL)
            CallFunction(c);
        else
            Apply(c, op);
    }
    
    /* if the operand stack is empty then there was no expression to parse */
    if ((count = rStackCount(c)) == 0)
        return FALSE;
        
    /* otherwise, make sure there is only one entry left on the operand stack */
    else if (count != 1)
        Error(c, "syntax error");
    
    /* return the expression value */
    RValue(c, &c->rStackPtr[0]);
    *pValue = c->rStackPtr[0].v.value;
    
    /* return successfully */
    return TRUE;
}
Esempio n. 23
0
void BinOp( stack_entry *left, stack_entry *right )
{
    RValue( left );
    RValue( right );
    DoBinOp( left, right );
}
Esempio n. 24
0
static void AddParms( void )
{
    PARMPTR             parm;
    PARMPTR             prev_parm;
    SYM_HANDLE          sym_handle;
    SYM_HANDLE          prev_sym_handle;
    SYM_HANDLE          new_sym_handle;
    TYPEPTR             typ = NULL;
    int                 parm_count;
    id_hash_idx         h;
    parm_list           *parmlist;
    SYM_ENTRY           new_sym;

    CurFunc->u.func.locals = SYM_NULL;
    CurFunc->u.func.parms = SYM_NULL;
    parmlist = NULL;
    prev_sym_handle = SYM_NULL;
    parm_count = 0;
    prev_parm = NULL;
    for( parm = ParmList; parm != NULL; parm = parm->next_parm ) {
        new_sym_handle = SYM_NULL;
        parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED;
        parm->sym.attribs.is_parm = true;
        h = parm->sym.info.hash;
        if( parm->sym.name[0] == '\0' ) {
            /* no name ==> ... */
            parm->sym.sym_type = GetType( TYPE_DOT_DOT_DOT );
            parm->sym.attribs.stg_class = SC_AUTO;
        } else if( parm->sym.sym_type == NULL ) {
            parm->sym.sym_type = TypeDefault();
            parm->sym.attribs.stg_class = SC_AUTO;
        } else {
            /*
                    go through ParmList again, looking for FLOAT parms
                    change the name to ".P" and duplicate the symbol with type
                    float and generate an assignment statement.
            */
            typ = parm->sym.sym_type;
            SKIP_TYPEDEFS( typ );

            switch( typ->decl_type ) {
            case TYPE_CHAR:
            case TYPE_UCHAR:
            case TYPE_SHORT:
                if( CompFlags.strict_ANSI ) {
                    parm->sym.sym_type = GetType( TYPE_INT );
                }
                break;

            case TYPE_USHORT:
                if( CompFlags.strict_ANSI ) {
#if TARGET_SHORT == TARGET_INT
                    parm->sym.sym_type = GetType( TYPE_UINT );
#else
                    parm->sym.sym_type = GetType( TYPE_INT );
#endif
                }
                break;

            case TYPE_FLOAT:
                memcpy( &new_sym, &parm->sym, sizeof( SYM_ENTRY ) );
                new_sym.handle = CurFunc->u.func.locals;
                new_sym_handle = SymAdd( h, &new_sym );
                CurFunc->u.func.locals = new_sym_handle;
                SymReplace( &new_sym, new_sym_handle );
                parm->sym.name = ".P";
                parm->sym.flags |= SYM_REFERENCED;
                parm->sym.sym_type = GetType( TYPE_DOUBLE );
                break;

            default:
                break;
            }
        }
        sym_handle = SymAdd( h, &parm->sym );
        if( new_sym_handle != SYM_NULL ) {
            TREEPTR         tree;

            tree = ExprNode( VarLeaf( &new_sym, new_sym_handle ),
                             OPR_EQUALS, RValue( VarLeaf( &parm->sym, sym_handle ) ) );
            tree->op.u2.result_type = typ;
            tree->u.expr_type = typ;
            AddStmt( tree );
        }

        if( prev_parm == NULL ) {
            CurFunc->u.func.parms = sym_handle;
        } else {
            prev_parm->sym.handle = sym_handle;
            SymReplace( &prev_parm->sym, prev_sym_handle );
            CMemFree( prev_parm );
        }
        prev_parm = parm;
        prev_sym_handle = sym_handle;
        ++parm_count;
        parmlist = NewParm( parm->sym.sym_type, parmlist );
    }
    if( prev_parm != NULL ) {
        prev_parm->sym.handle = SYM_NULL;
        SymReplace( &prev_parm->sym, prev_sym_handle );
        CMemFree( prev_parm );
    }
    typ = CurFunc->sym_type;
    // TODO not following my scheme
    CurFunc->sym_type = FuncNode( typ->object, FLAG_NONE,
                                  MakeParmList( parmlist, ParmsToBeReversed( CurFunc->mods, NULL ) ) );

    if( PrevProtoType != NULL ) {
        ChkProtoType();
    }
}
Esempio n. 25
0
RValue Inst::Load(CodeContext& context, RValue value)
{
	return RValue(new LoadInst(value, "", context), value.stype());
}
Esempio n. 26
0
bool Inst::CastTo(CodeContext& context, RValue& value, SType* type, bool upcast)
{
	auto valueType = value.stype();

	if (type == valueType) {
		// non-assignment and non-comparison operations with enum types
		// must result in an int type to keep enum variables within range.
		if (upcast && valueType->isEnum())
			value.castToSubtype();
		return false;
	} else if (type->isComplex() || valueType->isComplex()) {
		context.addError("can not cast complex types");
		return true;
	} else if (type->isPointer()) {
		if (value.isNullPtr()) {
			// NOTE: discard current null value and create
			// a new one using the right type
			value = RValue::getNullPtr(context, type);
			return false;
		} else if (type->subType()->isVoid()) {
			value = RValue(new BitCastInst(value, *type, "", context), type);
			return false;
		}
		context.addError("can't cast value to pointer type");
		return true;
	} else if (type->isVec()) {
		// unwrap enum type
		if (valueType->isEnum())
			valueType = value.castToSubtype();

		if (valueType->isNumeric()) {
			CastTo(context, value, type->subType(), upcast);

			auto i32 = SType::getInt(context, 32);
			auto mask = RValue::getZero(context, SType::getVec(context, i32, type->size()));
			auto udef = UndefValue::get(*SType::getVec(context, type->subType(), 1));
			auto instEle = InsertElementInst::Create(udef, value, RValue::getZero(context, i32), "", context);
			auto retVal = new ShuffleVectorInst(instEle, udef, mask, "", context);

			value = RValue(retVal, type);
			return false;
		} else if (valueType->isPointer()) {
			context.addError("can not cast pointer to vec type");
			return true;
		} else if (type->size() != valueType->size()) {
			context.addError("can not cast vec types of different sizes");
			return true;
		} else if (type->subType()->isBool()) {
			// cast to bool is value != 0
			auto pred = getPredicate(ParserBase::TT_NEQ, valueType, context);
			auto op = valueType->subType()->isFloating()? Instruction::FCmp : Instruction::ICmp;
			auto val = CmpInst::Create(op, pred, value, RValue::getZero(context, valueType), "", context);
			value = RValue(val, type);
			return false;
		} else {
			auto op = getCastOp(valueType->subType(), type->subType());
			auto val = CastInst::Create(op, value, *type, "", context);
			value = RValue(val, type);
			return false;
		}
	} else if (type->isEnum()) {
		// casting to enum would violate value constraints
		context.addError("can't cast to enum type");
		return true;
	} else if (type->isBool()) {
		if (valueType->isVec()) {
			context.addError("can not cast vec type to bool");
			return true;
		} else if (valueType->isEnum()) {
			valueType = value.castToSubtype();
		}

		// cast to bool is value != 0
		auto pred = getPredicate(ParserBase::TT_NEQ, valueType, context);
		auto op = valueType->isFloating()? Instruction::FCmp : Instruction::ICmp;
		auto val = CmpInst::Create(op, pred, value, RValue::getZero(context, valueType), "", context);
		value = RValue(val, type);
		return false;
	}

	if (valueType->isPointer()) {
		context.addError("can't cast pointer to numeric type");
		return true;
	}

	// unwrap enum type
	if (valueType->isEnum())
		valueType = value.castToSubtype();

	auto op = getCastOp(valueType, type);
	auto val = op != Instruction::AddrSpaceCast? CastInst::Create(op, value, *type, "", context) : value;
	value = RValue(val, type);
	return false;
}