⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expr.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 5 页
字号:
    CYG_REPORT_FUNCNAME("parse_bitxor");        parse_bitand(expr);    while (T_BitXor == current_token) {        CdlSubexpression subexpr;        subexpr.op = CdlExprOp_BitXor;        subexpr.lhs_index = expr->first_subexpression;                next_token();        parse_bitand(expr);        subexpr.rhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }        CYG_REPORT_RETURN();}static voidparse_bitor(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_bitor");        parse_bitxor(expr);    while (T_BitOr == current_token) {        CdlSubexpression subexpr;        subexpr.op = CdlExprOp_BitOr;        subexpr.lhs_index = expr->first_subexpression;                next_token();        parse_bitxor(expr);        subexpr.rhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }        CYG_REPORT_RETURN();}static voidparse_and(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_and");    parse_bitor(expr);    while (T_And == current_token) {        CdlSubexpression subexpr;        subexpr.op = CdlExprOp_And;        subexpr.lhs_index = expr->first_subexpression;                next_token();        parse_bitor(expr);        subexpr.rhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }        CYG_REPORT_RETURN();}static voidparse_or(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_or");    parse_and(expr);    while (T_Or == current_token) {        CdlSubexpression subexpr;        subexpr.op = CdlExprOp_Or;        subexpr.lhs_index = expr->first_subexpression;                next_token();        parse_and(expr);        subexpr.rhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }        CYG_REPORT_RETURN();}static voidparse_eqv(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_eqv");    parse_or(expr);    while ((T_Xor == current_token) || (T_Eqv == current_token)) {                CdlSubexpression subexpr;        subexpr.op = (T_Xor == current_token) ? CdlExprOp_Xor : CdlExprOp_Eqv;        subexpr.lhs_index = expr->first_subexpression;                next_token();        parse_or(expr);        subexpr.rhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }        CYG_REPORT_RETURN();}static voidparse_implies(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_implies");    parse_eqv(expr);    while (T_Implies == current_token) {                CdlSubexpression subexpr;        subexpr.op = CdlExprOp_Implies;        subexpr.lhs_index = expr->first_subexpression;                next_token();        parse_eqv(expr);        subexpr.rhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }        CYG_REPORT_RETURN();}static voidparse_conditional(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_conditional");    parse_implies(expr);    if (T_Questionmark == current_token) {        CdlSubexpression subexpr;        subexpr.op = CdlExprOp_Cond;        subexpr.lhs_index = expr->first_subexpression;        next_token();        parse_conditional(expr);        subexpr.rhs_index = expr->first_subexpression;        if (T_Colon != current_token) {            throw CdlParseException("Expected colon in conditional expression.\n" + get_error_location());        }        next_token();        parse_conditional(expr);        subexpr.rrhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }        CYG_REPORT_RETURN();}static voidparse_expression(CdlExpression expr){    CYG_REPORT_FUNCNAME("parse_expression");    parse_conditional(expr);        CYG_REPORT_RETURN();}// ----------------------------------------------------------------------------// The entry point.voidCdlExpressionBody::continue_parse(CdlExpression expr, std::string data, int& index, CdlExprOp& token, int& token_end){    CYG_REPORT_FUNCNAME("CdlExpression::continue_parse");    CYG_REPORT_FUNCARG1XV(expr);    CYG_PRECONDITION_CLASSC(expr);    CYG_PRECONDITIONC((CdlExprOp_Invalid == token) || (CdlExprOp_And == token));    int current_subexpr = expr->first_subexpression;    initialise_tokenisation(data, index);    parse_expression(expr);    if (CdlExprOp_And == token) {        CdlSubexpression subexpr;        subexpr.op        = CdlExprOp_And;        subexpr.lhs_index = current_subexpr;        subexpr.rhs_index = expr->first_subexpression;        push_subexpression(expr, subexpr);    }    token       = token_to_expr_op();    index       = token_start;    token_end   = current_index;    CYG_REPORT_RETURN();}//}}}//}}}//{{{  Expression Evaluation            // ----------------------------------------------------------------------------// Expression evaluation. This always happens in the context of a// particular toplevel. The parsed expression is held in what amounts// to a simple tree, so evaluation involves some recursion and a big// switch statement.static voidevaluate_subexpr(CdlEvalContext& context, CdlExpression expr, int subexpr_index, CdlSimpleValue& result){    CYG_REPORT_FUNCNAME("evaluate_subexpr");    CYG_REPORT_FUNCARG2XV(expr, subexpr_index);    CYG_ASSERTC((subexpr_index >= 0) && ((unsigned int)subexpr_index < expr->sub_expressions.size()));    const CdlSubexpression& subexpr = expr->sub_expressions[subexpr_index];    switch(subexpr.op) {    case CdlExprOp_StringConstant :    case CdlExprOp_IntegerConstant :    case CdlExprOp_DoubleConstant :    {        result = subexpr.constants;        break;    }    case CdlExprOp_Function :    {        CdlFunction::eval(context, expr, subexpr, result);        break;    }    case CdlExprOp_Reference :    {        // This expression may be happening in the context of a particular        // property. If so then the destination may or may not be resolved,        // and this is significant in the context of loading and unloading.        // Alternatively this expression may be being evaluated inside        // some Tcl code, with no particular context.        CdlNode destination = 0;        if (0 != context.property) {            // There is a property, use the bound/unbound reference.            destination = expr->references[subexpr.reference_index].get_destination();        } else {            // The destination name can be retrieved, but we still need some            // way of resolving it.            if (0 != context.toplevel) {                std::string destination_name = expr->references[subexpr.reference_index].get_destination_name();                destination = context.toplevel->lookup(destination_name);            }        }        if (0 == destination) {            // There are two ways of handling this.            //   1) throw an eval exception, which will usually result            //      in a new conflict object            //   2) substitute a value of 0.            // There should already be a conflict object for an            // unresolved reference, and having two conflicts for            // essentially the same error is not useful. Using a value            // of 0 allows things to continue for a bit longer. It is            // consistent with active vs. inactive values, gives            // basically the right result for "requires" properties,            // and so on.            //            // For now option (2) has it, but this decision may be            // reversed in future.            result = false;        } else {            CdlValuable valuable = dynamic_cast<CdlValuable>(destination);            if (0 == valuable) {                // This is a serious problem, an exception is warranted.                throw CdlEvalException("The expression references `" + destination->get_class_name() + " " +                                       destination->get_name() + "' which does not have a value.");            } else {                CdlSimpleValue::eval_valuable(context, valuable, result);            }        }        break;    }    case CdlExprOp_Negate :    {        // Unary -. Evaluate the target. If it is numeric, fine. Otherwise        // an error is warranted.        evaluate_subexpr(context, expr, subexpr.lhs_index, result);        if (result.has_integer_value()) {            result.set_integer_value(-1 * result.get_integer_value());        } else if (result.has_double_value()) {            result.set_double_value(-1.0 * result.get_double_value());        } else {            throw CdlEvalException("Attempt to negate non-numeric value `" + result.get_value() + "'.");        }        break;    }    case CdlExprOp_Plus :    {        // Unary +. Essentially this just checks that the current value is numeric.        evaluate_subexpr(context, expr, subexpr.lhs_index, result);        if ((!result.has_integer_value()) && (!result.has_double_value())) {            throw CdlEvalException("Attempt to apply unary + operator to non-numeric value `" + result.get_value() + "'.");        }        break;    }    case CdlExprOp_LogicalNot :    {        // !x        evaluate_subexpr(context, expr, subexpr.lhs_index, result);        if (result.get_bool_value()) {            result = false;;        } else {            result = true;        }        result.set_value_format(CdlValueFormat_Default);        break;    }    case CdlExprOp_BitNot :    {        // ~x. The operand must be an integer value.        evaluate_subexpr(context, expr, subexpr.lhs_index, result);        if (result.has_integer_value()) {            cdl_int tmp = result.get_integer_value();            result = ~tmp;        } else {            throw CdlEvalException("Attempt to apply unary ~ operator to non-integer value `" + result.get_value() + "'.");        }        break;    }    case CdlExprOp_Indirect :    {        // *x. The operand must evaluate to a string, and that string should be        // the name of a CdlValuable object.        CdlNode destination = 0;        evaluate_subexpr(context, expr, subexpr.lhs_index, result);        std::string name = result.get_value();                if (0 != context.toplevel) {            destination = context.toplevel->lookup(name);        } else {            CYG_FAIL("This situation should probably never happen.");        }                if (0 == destination) {            throw CdlEvalException("Attempt to apply unary indirection operator * to `" + name +                                   "', which is not the name of a known CDL entity.");        } else {            CdlValuable valuable = dynamic_cast<CdlValuable>(destination);            if (0 == valuable) {                throw CdlEvalException("Attempt to apply unary indirection operator * to `" + name +                                       "', which does not have a value.");            } else {                CdlSimpleValue::eval_valuable(context, valuable, result);            }        }        break;    }    case CdlExprOp_Active :    {        // ?x. If x is currently unresolved then default to 0.        // See the CdlExprOp_Reference code above for a similar case.        CdlNode destination = 0;        if (0 != context.property) {            destination =  expr->references[subexpr.reference_index].get_destination();        } else {            if (0 != context.toplevel) {                std::string destination_name = expr->references[subexpr.reference_index].get_destination_name();                destination = context.toplevel->lookup(destination_name);            }        }        bool active = false;        if ((0 != destination) && context.transaction->is_active(destination)) {            active = true;        }        if (active) {            result = true;        } else {            result = false;        }        break;    }    case CdlExprOp_Multiply :    {        // x * y. For now this only makes sense for numerical data,        // but it is possible to mix and match integer and double        // precision data.        //        // Strictly speaking the rhs need only be evaluated if it        // is known that the lhs is numeric.        CdlSimpleValue lhs;        CdlSimpleValue rhs;        evaluate_subexpr(context, expr, subexpr.lhs_index, lhs);        evaluate_subexpr(context, expr, subexpr.rhs_index, rhs);        if ((!(lhs.has_integer_value() || lhs.has_double_value())) ||            (!(rhs.has_integer_value() || rhs.has_double_value()))) {            throw CdlEvalException("Attempt to multiply non-numerical values: `" + lhs.get_value() + "' * `" +                                   rhs.get_value() +

⌨️ 快捷键说明

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