Attributes.cpp 21.4 KB
Newer Older
gsell's avatar
gsell committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// ------------------------------------------------------------------------
// $RCSfile: Attributes.cpp,v $
// ------------------------------------------------------------------------
// $Revision: 1.2 $
// ------------------------------------------------------------------------
// Copyright: see Copyright.readme
// ------------------------------------------------------------------------
//
// Namespace Attributes
//
// ------------------------------------------------------------------------
//
// $Date: 2002/01/17 22:18:36 $
// $Author: jsberg $
//
// ------------------------------------------------------------------------

18 19
#include "Attributes/Attributes.h"

gsell's avatar
gsell committed
20 21 22 23 24 25 26 27 28 29
#include "AbstractObjects/Attribute.h"
#include "Attributes/Bool.h"
#include "Attributes/BoolArray.h"
#include "Attributes/Place.h"
#include "Attributes/Range.h"
#include "Attributes/Real.h"
#include "Attributes/RealArray.h"
#include "Attributes/Reference.h"
#include "Attributes/opalstr.h"
#include "Attributes/StringArray.h"
frey_m's avatar
frey_m committed
30
#include "Attributes/UpperCaseString.h"
frey_m's avatar
frey_m committed
31
#include "Attributes/UpperCaseStringArray.h"
gsell's avatar
gsell committed
32 33 34 35 36 37 38 39
#include "Attributes/TableRow.h"
#include "Attributes/TokenList.h"
#include "Attributes/TokenListArray.h"
#include "Expressions/AValue.h"
#include "Expressions/SRefAttr.h"
#include "Expressions/SValue.h"
#include "Utilities/OpalException.h"

40 41 42 43 44 45
#include "AbstractObjects/OpalData.h"
#include "ValueDefinitions/RealVariable.h"
#include "Utilities/Util.h"

#include <boost/regex.hpp>

gsell's avatar
gsell committed
46 47 48 49 50 51 52 53 54 55 56
using namespace Expressions;


// Namespace Attributes.
// ------------------------------------------------------------------------

namespace Attributes {

    // ----------------------------------------------------------------------
    // Boolean value.

Steve Russell's avatar
Steve Russell committed
57
    Attribute makeBool(const std::string &name, const std::string &help) {
58
        return Attribute(new Bool(name, help), nullptr);
gsell's avatar
gsell committed
59 60 61
    }


Steve Russell's avatar
Steve Russell committed
62
    Attribute makeBool(const std::string &name, const std::string &help, bool ini) {
gsell's avatar
gsell committed
63 64 65 66 67
        return Attribute(new Bool(name, help), new SValue<bool>(ini));
    }


    bool getBool(const Attribute &attr) {
68 69
        if(attr.isBaseAllocated()) {
            AttributeBase *base = &attr.getBase();
gsell's avatar
gsell committed
70 71 72 73 74 75 76
            if(dynamic_cast<Bool *>(&attr.getHandler())) {
                return dynamic_cast<SValue<bool> *>(base)->evaluate();
            } else if(SValue<SRefAttr<bool> > *ref =
                          dynamic_cast<SValue<SRefAttr<bool> > *>(base)) {
                const SRefAttr<bool> &value = ref->evaluate();
                return value.evaluate();
            } else {
snuverink_j's avatar
snuverink_j committed
77
                throw OpalException("Attributes::getBool()", "Attribute \"" +
gsell's avatar
gsell committed
78 79 80 81 82 83 84 85 86
                                    attr.getName() + "\" is not logical.");
            }
        } else {
            return false;
        }
    }


    void setBool(Attribute &attr, bool val) {
87
        SValue<SRefAttr<bool> > *ref;
gsell's avatar
gsell committed
88 89
        if(dynamic_cast<const Bool *>(&attr.getHandler())) {
            attr.set(new SValue<bool>(val));
90 91
        } else if((attr.isBaseAllocated() == true) &&
                  (ref = dynamic_cast<SValue<SRefAttr<bool> >*>(&attr.getBase()))) {
gsell's avatar
gsell committed
92 93 94 95 96 97 98 99 100 101 102
            const SRefAttr<bool> &value = ref->evaluate();
            value.set(val);
        } else {
            throw OpalException("Attributes::setBool()", "Attribute \"" +
                                attr.getName() + "\" is not logical.");
        }
    }


    // ----------------------------------------------------------------------
    // Boolean array value.
Steve Russell's avatar
Steve Russell committed
103
    Attribute makeBoolArray(const std::string &name, const std::string &help) {
104
        return Attribute(new BoolArray(name, help), nullptr);
gsell's avatar
gsell committed
105 106 107 108
    }


    std::vector<bool> getBoolArray(const Attribute &attr) {
109 110
        if(attr.isBaseAllocated()) {
            AttributeBase *base = &attr.getBase();
gsell's avatar
gsell committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
            if(AValue<bool> *value =
                   dynamic_cast<AValue<bool>*>(base)) {
                return value->evaluate();
            } else {
                throw OpalException("Attributes::getBoolArray()", "Attribute \"" +
                                    attr.getName() + "\" is not a logical array.");
            }
        } else {
            return std::vector<bool>();
        }
    }


    void setBoolArray(Attribute &attr, const std::vector<bool> &value) {
        if(dynamic_cast<const BoolArray *>(&attr.getHandler())) {
            // Use ADeferred here, since a component may be overridden later
            // by an expression.
            attr.set(new ADeferred<bool>(value));
        } else {
            throw OpalException("Attributes::setBoolArray()", "Attribute \"" +
                                attr.getName() + "\" is not a logical array");
        }
    }


    // ----------------------------------------------------------------------
    // Place value.

Steve Russell's avatar
Steve Russell committed
139
    Attribute makePlace(const std::string &name, const std::string &help) {
gsell's avatar
gsell committed
140 141 142 143 144 145
        return Attribute(new Place(name, help),
                         new SValue<PlaceRep>(PlaceRep("#S")));
    }


    PlaceRep getPlace(const Attribute &attr) {
146
        if(attr.isBaseAllocated()) {
gsell's avatar
gsell committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
            if(SValue<PlaceRep> *place =
                   dynamic_cast<SValue<PlaceRep> *>(&attr.getBase())) {
                return place->evaluate();
            } else {
                throw OpalException("Attributes::getPlace()", "Attribute \"" +
                                    attr.getName() + "\" is not a place reference.");
            }
        } else {
            return PlaceRep();
        }
    }


    void setPlace(Attribute &attr, const PlaceRep &rep) {
        if(dynamic_cast<const Place *>(&attr.getHandler())) {
            attr.set(new SValue<PlaceRep>(rep));
        } else {
snuverink_j's avatar
snuverink_j committed
164
            throw OpalException("Attributes::setPlace()", "Attribute \"" +
gsell's avatar
gsell committed
165 166 167 168 169 170 171 172
                                attr.getName() + "\" is not a place reference.");
        }
    }


    // ----------------------------------------------------------------------
    // Range value.

Steve Russell's avatar
Steve Russell committed
173
    Attribute makeRange(const std::string &name, const std::string &help) {
gsell's avatar
gsell committed
174 175 176 177 178 179
        return Attribute(new Range(name, help),
                         new SValue<RangeRep>(RangeRep()));
    }


    RangeRep getRange(const Attribute &attr) {
180
        if(attr.isBaseAllocated()) {
gsell's avatar
gsell committed
181 182 183 184
            if(SValue<RangeRep> *range =
                   dynamic_cast<SValue<RangeRep> *>(&attr.getBase())) {
                return range->evaluate();
            } else {
snuverink_j's avatar
snuverink_j committed
185
                throw OpalException("Attributes::getRange()", "Attribute \"" +
gsell's avatar
gsell committed
186 187 188 189 190 191 192 193 194 195 196 197
                                    attr.getName() + "\" is not a range reference.");
            }
        } else {
            return RangeRep();
        }
    }


    void setRange(Attribute &attr, const RangeRep &rep) {
        if(dynamic_cast<const Range *>(&attr.getHandler())) {
            attr.set(new SValue<RangeRep>(rep));
        } else {
snuverink_j's avatar
snuverink_j committed
198
            throw OpalException("Attributes::setRange()", "Attribute \"" +
gsell's avatar
gsell committed
199 200 201 202 203 204 205 206
                                attr.getName() + "\" is not a range reference.");
        }
    }


    // ----------------------------------------------------------------------
    // Real value.

Steve Russell's avatar
Steve Russell committed
207
    Attribute makeReal(const std::string &name, const std::string &help) {
208
        return Attribute(new Real(name, help), nullptr);
gsell's avatar
gsell committed
209 210 211 212
    }


    Attribute
Steve Russell's avatar
Steve Russell committed
213
    makeReal(const std::string &name, const std::string &help, double initial) {
gsell's avatar
gsell committed
214 215 216 217 218 219
        return Attribute(new Real(name, help),
                         new SValue<double>(initial));
    }


    double getReal(const Attribute &attr) {
220 221
        if(attr.isBaseAllocated()) {
            AttributeBase *base = &attr.getBase();
gsell's avatar
gsell committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
            if(dynamic_cast<Real *>(&attr.getHandler())) {
                return dynamic_cast<SValue<double> *>(base)->evaluate();
            } else if(SValue<SRefAttr<double> > *ref =
                          dynamic_cast<SValue<SRefAttr<double> > *>(base)) {
                const SRefAttr<double> &value = ref->evaluate();
                return value.evaluate();
            } else {
                throw OpalException("Attributes::getReal()", "Attribute \"" +
                                    attr.getName() + "\" is not real.");
            }
        } else {
            return 0.0;
        }
    }


    void setReal(Attribute &attr, double val) {
239
        SValue<SRefAttr<double> > *ref;
gsell's avatar
gsell committed
240 241
        if(dynamic_cast<const Real *>(&attr.getHandler())) {
            attr.set(new SValue<double>(val));
242 243
        } else if((attr.isBaseAllocated() == true) &&
                  (ref = dynamic_cast<SValue<SRefAttr<double> >*>(&attr.getBase()))) {
gsell's avatar
gsell committed
244 245 246 247
            const SRefAttr<double> &value = ref->evaluate();
            value.set(val);
        } else {
            throw OpalException("Attributes::setReal()", "Attribute \"" +
248
                                attr.getName() + "\" is not real.");
gsell's avatar
gsell committed
249 250 251 252 253 254 255
        }
    }


    // ----------------------------------------------------------------------
    // Real array value.

Steve Russell's avatar
Steve Russell committed
256
    Attribute makeRealArray(const std::string &name, const std::string &help) {
257
        return Attribute(new RealArray(name, help), nullptr);
gsell's avatar
gsell committed
258 259 260 261
    }


    std::vector<double> getRealArray(const Attribute &attr) {
262
        if(attr.isBaseAllocated()) {
gsell's avatar
gsell committed
263
            if(dynamic_cast<RealArray *>(&attr.getHandler())) {
264
                AttributeBase *base = &attr.getBase();
gsell's avatar
gsell committed
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
                return dynamic_cast<AValue<double>*>(base)->evaluate();
            } else {
                throw OpalException("Attributes::getRealArray()", "Attribute \"" +
                                    attr.getName() + "\" is not a real array.");
            }
        } else {
            return std::vector<double>();
        }
    }


    void setRealArray(Attribute &attr, const std::vector<double> &value) {
        if(dynamic_cast<const RealArray *>(&attr.getHandler())) {
            // Use ADeferred here, since a component may be overridden later
            // by an expression.
            attr.set(new ADeferred<double>(value));
        } else {
            throw OpalException("Attributes::setRealArray()", "Attribute \"" +
                                attr.getName() + "\" is not a real array.");
        }
    }


    // ----------------------------------------------------------------------
    // Reference value.

Steve Russell's avatar
Steve Russell committed
291
    Attribute makeReference(const std::string &name, const std::string &help) {
292
        return Attribute(new Reference(name, help), nullptr);
gsell's avatar
gsell committed
293 294 295 296 297 298
    }


    // ----------------------------------------------------------------------
    // String value.

Steve Russell's avatar
Steve Russell committed
299
    Attribute makeString(const std::string &name, const std::string &help) {
300
        return Attribute(new String(name, help), nullptr);
gsell's avatar
gsell committed
301 302 303 304
    }


    Attribute
Steve Russell's avatar
Steve Russell committed
305 306
    makeString(const std::string &name, const std::string &help, const std::string &initial) {
        return Attribute(new String(name, help), new SValue<std::string>(initial));
gsell's avatar
gsell committed
307 308 309
    }


Steve Russell's avatar
Steve Russell committed
310
    std::string getString(const Attribute &attr) {
311 312
        if(attr.isBaseAllocated()) {
            AttributeBase *base = &attr.getBase();
313
            std::string expr;
frey_m's avatar
frey_m committed
314
            if(dynamic_cast<String *>(&attr.getHandler())
frey_m's avatar
frey_m committed
315
               || dynamic_cast<UpperCaseString *>(&attr.getHandler())) {
316
                expr = dynamic_cast<SValue<std::string> *>(base)->evaluate();
Steve Russell's avatar
Steve Russell committed
317 318 319
            } else if(SValue<SRefAttr<std::string> > *ref =
                          dynamic_cast<SValue<SRefAttr<std::string> > *>(base)) {
                const SRefAttr<std::string> &value = ref->evaluate();
320
                expr = value.evaluate();
gsell's avatar
gsell committed
321 322 323 324
            } else {
                throw OpalException("Attributes::getString()", "Attribute \"" +
                                    attr.getName() + "\" is not string.");
            }
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353

            auto opal = OpalData::getInstance();

            boost::regex variableRE("\\$\\{(.*?)\\}");
            boost::smatch what;

            std::string exprDeref;
            std::string::const_iterator start = expr.begin();
            std::string::const_iterator end = expr.end();

            while (boost::regex_search(start, end, what, variableRE, boost::match_default)) {
                exprDeref += std::string(start, what[0].first);
                std::string variable = Util::toUpper(std::string(what[1].first, what[1].second));

                if (Object *obj = opal->find(variable)) {
                    std::ostringstream value;

                    RealVariable *real = static_cast<RealVariable*>(obj);
                    real->printValue(value);
                    exprDeref += value.str();
                } else {
                    exprDeref += std::string(what[0].first, what[0].second);
                }

                start = what[0].second;
            }
            exprDeref += std::string(start, end);

            return exprDeref;
gsell's avatar
gsell committed
354
        } else {
Steve Russell's avatar
Steve Russell committed
355
            return std::string();
gsell's avatar
gsell committed
356 357 358 359
        }
    }


Steve Russell's avatar
Steve Russell committed
360
    void setString(Attribute &attr, const std::string &val) {
361
        SValue<SRefAttr<std::string> > *ref;
gsell's avatar
gsell committed
362
        if(dynamic_cast<const String *>(&attr.getHandler())) {
Steve Russell's avatar
Steve Russell committed
363
            attr.set(new SValue<std::string>(val));
364 365
        } else if((attr.isBaseAllocated() == true) &&
                  (ref = dynamic_cast<SValue<SRefAttr<std::string> >*>(&attr.getBase()))) {
Steve Russell's avatar
Steve Russell committed
366
            const SRefAttr<std::string> &value = ref->evaluate();
gsell's avatar
gsell committed
367 368 369 370 371 372 373 374 375
            value.set(val);
        } else {
            throw OpalException("Attributes::setString()", "Attribute \"" +
                                attr.getName() + "\" is not a string.");
        }
    }


    // ----------------------------------------------------------------------
frey_m's avatar
frey_m committed
376
    // Upper case string value.
gsell's avatar
gsell committed
377

frey_m's avatar
frey_m committed
378 379
    Attribute makeUpperCaseString(const std::string &name, const std::string &help) {
        return Attribute(new UpperCaseString(name, help), nullptr);
frey_m's avatar
frey_m committed
380 381 382 383
    }


    Attribute
frey_m's avatar
frey_m committed
384
    makeUpperCaseString(const std::string &name, const std::string &help, const std::string &initial) {
frey_m's avatar
frey_m committed
385
        return Attribute(new UpperCaseString(name, help), new SValue<std::string>(Util::toUpper(initial)));
frey_m's avatar
frey_m committed
386 387 388
    }


frey_m's avatar
frey_m committed
389
    void setUpperCaseString(Attribute &attr, const std::string &val) {
390
        SValue<SRefAttr<std::string> > *ref;
frey_m's avatar
frey_m committed
391
        if(dynamic_cast<const UpperCaseString *>(&attr.getHandler())) {
frey_m's avatar
frey_m committed
392
            attr.set(new SValue<std::string>(Util::toUpper(val)));
393 394
        } else if((attr.isBaseAllocated() == true) &&
                  (ref = dynamic_cast<SValue<SRefAttr<std::string> >*>(&attr.getBase()))) {
frey_m's avatar
frey_m committed
395
            const SRefAttr<std::string> &value = ref->evaluate();
frey_m's avatar
frey_m committed
396
            value.set(Util::toUpper(val));
frey_m's avatar
frey_m committed
397
        } else {
frey_m's avatar
frey_m committed
398
            throw OpalException("Attributes::setUpperCaseString()", "Attribute \"" +
frey_m's avatar
frey_m committed
399
                                attr.getName() + "\" is not an upper case string.");
frey_m's avatar
frey_m committed
400 401 402 403 404 405
        }
    }


    // ----------------------------------------------------------------------
    // String array value.
Steve Russell's avatar
Steve Russell committed
406
    Attribute makeStringArray(const std::string &name, const std::string &help) {
407
        return Attribute(new StringArray(name, help), nullptr);
gsell's avatar
gsell committed
408 409
    }

Steve Russell's avatar
Steve Russell committed
410 411

    std::vector<std::string> getStringArray(const Attribute &attr) {
412 413
        if(attr.isBaseAllocated()) {
            AttributeBase *base = &attr.getBase();
frey_m's avatar
frey_m committed
414 415
            if(dynamic_cast<StringArray *>(&attr.getHandler())
                || dynamic_cast<UpperCaseStringArray *>(&attr.getHandler())) {
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
                auto opal = OpalData::getInstance();

                boost::regex variableRE("\\$\\{(.*?)\\}");
                boost::smatch what;

                std::vector<std::string> value = dynamic_cast<AValue<std::string>*>(base)->evaluate();
                for (auto expr: value) {
                    std::string exprDeref;
                    std::string::const_iterator start = expr.begin();
                    std::string::const_iterator end = expr.end();

                    while (boost::regex_search(start, end, what, variableRE, boost::match_default)) {
                        exprDeref += std::string(start, what[0].first);
                        std::string variable = Util::toUpper(std::string(what[1].first, what[1].second));

                        if (Object *obj = opal->find(variable)) {
                            std::ostringstream value;

                            RealVariable *real = static_cast<RealVariable*>(obj);
                            real->printValue(value);
                            exprDeref += value.str();
                        } else {
                            exprDeref += std::string(what[0].first, what[0].second);
                        }

                        start = what[0].second;
                    }
                    expr = exprDeref + std::string(start, end);
                }

                return value;
gsell's avatar
gsell committed
447 448 449 450 451
            } else {
                throw OpalException("Attributes::getStringArray()", "Attribute \"" +
                                    attr.getName() + "\" is not a string array.");
            }
        } else {
Steve Russell's avatar
Steve Russell committed
452
            return std::vector<std::string>();
gsell's avatar
gsell committed
453 454 455 456
        }
    }


Steve Russell's avatar
Steve Russell committed
457
    void setStringArray(Attribute &attr, const std::vector<std::string> &value) {
gsell's avatar
gsell committed
458 459
        if(dynamic_cast<const StringArray *>(&attr.getHandler())) {
            // Strings are never expressions, so AValue will do here.
Steve Russell's avatar
Steve Russell committed
460
            attr.set(new AValue<std::string>(value));
gsell's avatar
gsell committed
461 462 463 464 465 466
        } else {
            throw OpalException("Attributes::setStringArray()", "Attribute \"" +
                                attr.getName() + "\" is not a string array.");
        }
    }

frey_m's avatar
frey_m committed
467 468 469 470 471 472 473 474 475
    // ----------------------------------------------------------------------
    // Upper case string array value.
    Attribute makeUpperCaseStringArray(const std::string &name, const std::string &help) {
        return Attribute(new UpperCaseStringArray(name, help), nullptr);
    }

    void setUpperCaseStringArray(Attribute &attr, const std::vector<std::string> &value) {
        if(dynamic_cast<const UpperCaseStringArray *>(&attr.getHandler())) {
            // Strings are never expressions, so AValue will do here.
frey_m's avatar
frey_m committed
476 477 478 479
            std::vector<std::string> uppercase(value.size());
            std::transform(value.begin(), value.end(), uppercase.begin(),
                           [](std::string val) -> std::string { return Util::toUpper(val); });
            attr.set(new AValue<std::string>(uppercase));
frey_m's avatar
frey_m committed
480 481 482 483 484 485
        } else {
            throw OpalException("Attributes::setUpperCaseStringArray()", "Attribute \"" +
                                attr.getName() + "\" is not an upper case string array.");
        }
    }

gsell's avatar
gsell committed
486 487 488 489

    // ----------------------------------------------------------------------
    // Table row reference value.

Steve Russell's avatar
Steve Russell committed
490
    Attribute makeTableRow(const std::string &name, const std::string &help) {
491
        return Attribute(new TableRow(name, help), nullptr);
gsell's avatar
gsell committed
492 493 494 495
    }


    TableRowRep getTableRow(const Attribute &attr) {
496
        if(attr.isBaseAllocated()) {
gsell's avatar
gsell committed
497 498 499 500
            if(SValue<TableRowRep> *row =
                   dynamic_cast<SValue<TableRowRep> *>(&attr.getBase())) {
                return row->evaluate();
            } else {
snuverink_j's avatar
snuverink_j committed
501
                throw OpalException("Attributes::getTableRow()", "Attribute \"" +
gsell's avatar
gsell committed
502 503 504 505 506 507 508 509 510 511 512 513 514
                                    attr.getName() +
                                    "\" is not a table row reference.");
            }
        } else {
            return TableRowRep();
        }
    }


    void setTableRow(Attribute &attr, const TableRowRep &rep) {
        if(dynamic_cast<const TableRow *>(&attr.getHandler())) {
            attr.set(new SValue<TableRowRep>(rep));
        } else {
snuverink_j's avatar
snuverink_j committed
515
            throw OpalException("Attributes::setTableRow()", "Attribute \"" +
gsell's avatar
gsell committed
516 517 518 519 520 521 522 523 524
                                attr.getName() +
                                "\" is not a table row reference.");
        }
    }


    // ----------------------------------------------------------------------
    // Token list value.

Steve Russell's avatar
Steve Russell committed
525
    Attribute makeTokenList(const std::string &name, const std::string &help) {
526
        return Attribute(new TokenList(name, help), nullptr);
gsell's avatar
gsell committed
527 528 529 530
    }


    std::list<Token> getTokenList(const Attribute &attr) {
531 532
        if(attr.isBaseAllocated()) {
            AttributeBase *base = &attr.getBase();
gsell's avatar
gsell committed
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
            if(dynamic_cast<TokenList *>(&attr.getHandler())) {
                return dynamic_cast<SValue<std::list<Token> > *>(base)->evaluate();
            } else {
                throw OpalException("Attributes::getTokenList()", "Attribute \"" +
                                    attr.getName() + "\" is not a token list.");
            }
        } else {
            return std::list<Token>();
        }
    }


    void setTokenList(Attribute &attr, const std::list<Token> &val) {
        if(dynamic_cast<const TokenList *>(&attr.getHandler())) {
            attr.set(new SValue<std::list<Token> >(val));
        } else {
snuverink_j's avatar
snuverink_j committed
549
            throw OpalException("Attributes::setTokenList()", "Attribute \"" + attr.getName() +
gsell's avatar
gsell committed
550 551 552 553 554 555 556 557
                                "\" is not a token list.");
        }
    }


    // ----------------------------------------------------------------------
    // Token list array value.

Steve Russell's avatar
Steve Russell committed
558
    Attribute makeTokenListArray(const std::string &name, const std::string &help) {
559
        return Attribute(new TokenListArray(name, help), nullptr);
gsell's avatar
gsell committed
560 561 562 563
    }


    std::vector<std::list<Token> > getTokenListArray(const Attribute &attr) {
564 565
        if(attr.isBaseAllocated()) {
            AttributeBase *base = &attr.getBase();
gsell's avatar
gsell committed
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
            if(dynamic_cast<TokenListArray *>(&attr.getHandler())) {
                return dynamic_cast<AValue<std::list<Token> > *>(base)->evaluate();
            } else {
                throw OpalException("Attributes::getTokenListArray()", "Attribute \"" +
                                    attr.getName() + "\" is not a token list array.");
            }
        } else {
            return std::vector<std::list<Token> >();
        }
    }


    void
    setTokenListArray(Attribute &attr,
                      const std::vector<std::list<Token> > &value) {
        // Token lists are never expressions, so AValue will do here.
        attr.set(new AValue<std::list<Token> >(value));
    }
584
}