//
// aegis - project change supervisor
// Copyright (C) 1994-1996, 1999, 2002-2008, 2012 Peter Miller
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
#include
#include
#include
#include
#include
#include
rpt_expr_and_bit::~rpt_expr_and_bit()
{
trace(("%s\n", __PRETTY_FUNCTION__));
}
rpt_expr_and_bit::rpt_expr_and_bit(const rpt_expr::pointer &lhs,
const rpt_expr::pointer &rhs)
{
trace(("%s\n", __PRETTY_FUNCTION__));
append(lhs);
append(rhs);
}
rpt_expr::pointer
rpt_expr_and_bit::create(const rpt_expr::pointer &lhs,
const rpt_expr::pointer &rhs)
{
trace(("%s\n", __PRETTY_FUNCTION__));
return pointer(new rpt_expr_and_bit(lhs, rhs));
}
rpt_value::pointer
rpt_expr_and_bit::evaluate()
const
{
trace(("%s\n", __PRETTY_FUNCTION__));
assert(get_nchildren() == 2);
rpt_value::pointer v1 = nth_child(0)->evaluate(true, true);
trace(("v1 is %s\n", v1->name()));
if (v1->is_an_error())
return v1;
rpt_value::pointer v1i = rpt_value::integerize(v1);
trace(("v1i is %s\n", v1i->name()));
rpt_value_integer *v1ip = dynamic_cast(v1i.get());
if (!v1ip)
{
sub_context_ty sc;
sc.var_set_charstar("Name", v1->name());
nstring s
(
sc.subst_intl
(
i18n("integer value required for bit and (was given $name)")
)
);
assert(nth_child(0)->get_pos());
rpt_value::pointer result =
rpt_value_error::create(nth_child(0)->get_pos(), s);
return result;
}
trace(("v1ip is %ld\n", v1ip->query()));
rpt_value::pointer v2 = nth_child(1)->evaluate(true, true);
trace(("v2 is %s\n", v2->name()));
if (v2->is_an_error())
return v2;
rpt_value::pointer v2i = rpt_value::integerize(v2);
trace(("v2i is %s\n", v2i->name()));
rpt_value_integer *v2ip = dynamic_cast(v2i.get());
if (!v2ip)
{
sub_context_ty sc;
sc.var_set_charstar("Name", v2->name());
nstring s
(
sc.subst_intl
(
i18n("integer value required for bit and (was given $name)")
)
);
rpt_value::pointer result =
rpt_value_error::create(nth_child(1)->get_pos(), s);
return result;
}
trace(("v2ip is %ld\n", v2ip->query()));
return rpt_value_integer::create(v1ip->query() & v2ip->query());
}
rpt_expr_xor_bit::~rpt_expr_xor_bit()
{
}
rpt_expr_xor_bit::rpt_expr_xor_bit(const rpt_expr::pointer &lhs,
const rpt_expr::pointer &rhs)
{
append(lhs);
append(rhs);
}
rpt_expr::pointer
rpt_expr_xor_bit::create(const rpt_expr::pointer &lhs,
const rpt_expr::pointer &rhs)
{
return pointer(new rpt_expr_xor_bit(lhs, rhs));
}
rpt_value::pointer
rpt_expr_xor_bit::evaluate()
const
{
assert(get_nchildren() == 2);
rpt_value::pointer v1 = nth_child(0)->evaluate(true, true);
if (v1->is_an_error())
return v1;
rpt_value::pointer v1i = rpt_value::integerize(v1);
rpt_value_integer *v1ip = dynamic_cast(v1i.get());
if (!v1ip)
{
sub_context_ty sc;
sc.var_set_charstar("Name", v1->name());
nstring s
(
sc.subst_intl
(
i18n("integer value required for bit xor (was given $name)")
)
);
rpt_value::pointer result =
rpt_value_error::create(nth_child(0)->get_pos(), s);
return result;
}
rpt_value::pointer v2 = nth_child(1)->evaluate(true, true);
if (v2->is_an_error())
return v2;
rpt_value::pointer v2i = rpt_value::integerize(v2);
rpt_value_integer *v2ip = dynamic_cast(v2i.get());
if (!v2ip)
{
sub_context_ty sc;
sc.var_set_charstar("Name", v2->name());
nstring s
(
sc.subst_intl
(
i18n("integer value required for bit xor (was given $name)")
)
);
rpt_value::pointer result =
rpt_value_error::create(nth_child(1)->get_pos(), s);
return result;
}
return rpt_value_integer::create(v1ip->query() ^ v2ip->query());
}
rpt_expr_or_bit::~rpt_expr_or_bit()
{
}
rpt_expr_or_bit::rpt_expr_or_bit(const rpt_expr::pointer &lhs,
const rpt_expr::pointer &rhs)
{
append(lhs);
append(rhs);
}
rpt_expr::pointer
rpt_expr_or_bit::create(const rpt_expr::pointer &lhs,
const rpt_expr::pointer &rhs)
{
return pointer(new rpt_expr_or_bit(lhs, rhs));
}
rpt_value::pointer
rpt_expr_or_bit::evaluate()
const
{
assert(get_nchildren() == 2);
rpt_value::pointer v1 = nth_child(0)->evaluate(true, true);
if (v1->is_an_error())
return v1;
rpt_value::pointer v1i = rpt_value::integerize(v1);
rpt_value_integer *v1ip = dynamic_cast(v1i.get());
if (!v1ip)
{
sub_context_ty sc;
sc.var_set_charstar("Name", v1->name());
nstring s
(
sc.subst_intl
(
i18n("integer value required for bit or (was given $name)")
)
);
rpt_value::pointer result =
rpt_value_error::create(nth_child(0)->get_pos(), s);
return result;
}
rpt_value::pointer v2 = nth_child(1)->evaluate(true, true);
if (v2->is_an_error())
return v2;
rpt_value::pointer v2i = rpt_value::integerize(v2);
rpt_value_integer *v2ip = dynamic_cast(v2i.get());
if (!v2ip)
{
sub_context_ty sc;
sc.var_set_charstar("Name", v2->name());
nstring s
(
sc.subst_intl
(
i18n("integer value required for bit or (was given $name)")
)
);
rpt_value::pointer result =
rpt_value_error::create(nth_child(1)->get_pos(), s);
return result;
}
return rpt_value_integer::create(v1ip->query() | v2ip->query());
}
rpt_expr_not_bit::~rpt_expr_not_bit()
{
}
rpt_expr_not_bit::rpt_expr_not_bit(const rpt_expr::pointer &arg)
{
append(arg);
}
rpt_expr::pointer
rpt_expr_not_bit::create(const rpt_expr::pointer &arg)
{
return pointer(new rpt_expr_not_bit(arg));
}
rpt_value::pointer
rpt_expr_not_bit::evaluate()
const
{
//
// evaluate the argument
//
trace(("not::evaluate()\n{\n"));
assert(get_nchildren() == 1);
rpt_value::pointer v1 = nth_child(0)->evaluate(true, true);
if (v1->is_an_error())
{
trace(("}\n"));
return v1;
}
//
// coerce the argument to an arithmetic type
// (will not give error if can't, will copy instead)
//
rpt_value::pointer v2 = rpt_value::integerize(v1);
//
// the type of the result depends on
// the types of the argument
//
rpt_value_integer *vip = dynamic_cast(v2.get());
if (!vip)
{
sub_context_ty sc;
sc.var_set_charstar("Name", v2->name());
nstring s(sc.subst_intl(i18n("illegal bit not ($name)")));
rpt_value::pointer vp =
rpt_value_error::create(nth_child(0)->get_pos(), s);
return vp;
}
return rpt_value_integer::create(~vip->query());
}
// vim: set ts=8 sw=4 et :