PageRenderTime 170ms CodeModel.GetById 22ms app.highlight 130ms RepoModel.GetById 1ms app.codeStats 2ms

/winxedst0.cpp

http://github.com/NotFound/winxed
C++ | 6494 lines | 5816 code | 541 blank | 137 comment | 792 complexity | 48432d18214d862feaa6834e8061c257 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// winxedst0.cpp
   2// Revision 25-jun-2012
   3
   4// Winxed compiler stage 0.
   5
   6#include "token.h"
   7#include "errors.h"
   8#include "emit.h"
   9
  10#include <string>
  11#include <iostream>
  12#include <istream>
  13#include <fstream>
  14#include <sstream>
  15#include <cctype>
  16#include <vector>
  17#include <map>
  18#include <algorithm>
  19#include <stdexcept>
  20
  21#include <string.h>
  22#include <errno.h>
  23
  24#include <typeinfo>
  25
  26//**********************************************************************
  27
  28// Register types
  29const char REGint    = 'I';
  30const char REGstring = 'S';
  31const char REGvar    = 'P';
  32// Pseudotypes for builtins
  33const char REGany    = '?';
  34const char REGnone   = '\0'; // void return
  35
  36static const char * nameoftype(char ctype)
  37{
  38    switch (ctype)
  39    {
  40    case REGint:    return "int";
  41    case REGstring: return "string";
  42    case REGvar:    return "pmc";
  43    default:
  44        throw CompileError("Invalid type");
  45    }
  46}
  47
  48char nativetype(const Token &name)
  49{
  50    if (name.iskeyword("int")) return REGint;
  51    else if (name.iskeyword("string")) return REGstring;
  52    else if (name.iskeyword("var")) return REGvar;
  53    else return '\0';
  54}
  55
  56//**********************************************************************
  57
  58#define INDENT "    "
  59#define INDENTLABEL "  "
  60
  61inline
  62std::string op(const char *name, const std::string &op1)
  63{
  64    return INDENT + std::string(name) + ' ' + op1;
  65}
  66
  67inline
  68std::string op(const char *name,
  69    const std::string &op1, const std::string &op2)
  70{
  71    return INDENT + std::string(name) + ' ' + op1 + ", " + op2;
  72}
  73
  74inline
  75std::string op(const char *name,
  76    const std::string &op1,
  77    const std::string &op2, const std::string &op3)
  78{
  79    return INDENT + std::string(name) + ' ' + op1 + ", " + op2 + ", " + op3;
  80}
  81
  82inline
  83std::string op_inc(const std::string &op1)
  84{
  85    return op("inc", op1);
  86}
  87
  88inline
  89std::string op_dec(const std::string &op1)
  90{
  91    return op("dec", op1);
  92}
  93
  94inline
  95std::string op_set(const std::string &res, const std::string &op1)
  96{
  97    return op("set", res, op1);
  98}
  99
 100inline
 101std::string op_assign(const std::string &res, const std::string &op1)
 102{
 103    return op("assign", res, op1);
 104}
 105
 106inline
 107std::string op_box(const std::string &res, const std::string &op1)
 108{
 109    return op("box", res, op1);
 110}
 111
 112inline
 113std::string op_add(const std::string &res,
 114    const std::string &op1, const std::string &op2)
 115{
 116    return op("add", res, op1, op2);
 117}
 118
 119inline
 120std::string op_sub(const std::string &res,
 121    const std::string &op1, const std::string &op2)
 122{
 123    return op("sub", res, op1, op2);
 124}
 125
 126inline
 127std::string op_mul(const std::string &res,
 128    const std::string &op1, const std::string &op2)
 129{
 130    return op("mul", res, op1, op2);
 131}
 132
 133inline
 134std::string op_div(const std::string &res,
 135    const std::string &op1, const std::string &op2)
 136{
 137    return op("div", res, op1, op2);
 138}
 139
 140inline
 141std::string op_mod(const std::string &res,
 142    const std::string &op1, const std::string &op2)
 143{
 144    return op("mod", res, op1, op2);
 145}
 146
 147inline
 148std::string op_cmod(const std::string &res,
 149    const std::string &op1, const std::string &op2)
 150{
 151    return op("cmod", res, op1, op2);
 152}
 153
 154inline
 155std::string op_null(const std::string &res)
 156{
 157    return op("null", res);
 158}
 159
 160inline
 161std::string op_isnull(const std::string &res, const std::string &op1)
 162{
 163    return op("isnull", res, op1);
 164}
 165
 166inline
 167std::string op_iseq(const std::string &res,
 168    const std::string &op1, const std::string &op2)
 169{
 170    return op("iseq", res, op1, op2);
 171}
 172
 173inline
 174std::string op_isne(const std::string &res,
 175    const std::string &op1, const std::string &op2)
 176{
 177    return op("isne", res, op1, op2);
 178}
 179
 180inline
 181std::string op_islt(const std::string &res,
 182    const std::string &op1, const std::string &op2)
 183{
 184    return op("islt", res, op1, op2);
 185}
 186
 187inline
 188std::string op_isgt(const std::string &res,
 189    const std::string &op1, const std::string &op2)
 190{
 191    return op("isgt", res, op1, op2);
 192}
 193
 194inline
 195std::string op_isle(const std::string &res,
 196    const std::string &op1, const std::string &op2)
 197{
 198    return op("isle", res, op1, op2);
 199}
 200
 201inline
 202std::string op_isge(const std::string &res,
 203    const std::string &op1, const std::string &op2)
 204{
 205    return op("isge", res, op1, op2);
 206}
 207
 208inline
 209std::string op_isa(const std::string &res,
 210    const std::string &op1, const std::string &op2)
 211{
 212    return op("isa", res, op1, op2);
 213}
 214
 215//**********************************************************************
 216
 217inline void RequireOp(char name, const Token &t)
 218{
 219    if (! t.isop(name) )
 220        throw Expected (name, t);
 221}
 222
 223inline void ExpectOp(char name, Tokenizer &tk)
 224{
 225    Token t= tk.get();
 226    RequireOp(name, t);
 227}
 228
 229//**********************************************************************
 230
 231template <typename T>
 232void emit_group(const std::vector<T *> &group, Emit &e)
 233{
 234    for (size_t i= 0; i < group.size(); ++i)
 235        group[i]->emit(e);
 236}
 237
 238//**********************************************************************
 239
 240class BuiltinFunction
 241{
 242public:
 243    static const int VarArgs = -1;
 244    BuiltinFunction(const std::string &name, char typeresult, int nargs) :
 245        pname(name),
 246        tresult(typeresult),
 247        n(nargs)
 248    {
 249    }
 250    BuiltinFunction(const std::string &name, char typeresult) :
 251        pname(name),
 252        tresult(typeresult),
 253        n(VarArgs)
 254    {
 255    }
 256    static const BuiltinFunction *find(const std::string &name,
 257        size_t numargs);
 258    bool name_is(const std::string &name) const
 259    { return pname == name; }
 260    size_t numargs() const { return n; }
 261    char resulttype() const { return tresult; }
 262
 263    virtual char paramtype(size_t n) const = 0;
 264    virtual void emit(Emit &e, const std::string &result,
 265        const std::vector<std::string> args) const = 0;
 266private:
 267    static const BuiltinFunction *builtins[];
 268    static const size_t numbuiltins;
 269    const std::string pname;
 270    char tresult;
 271    unsigned int n;
 272};
 273
 274class BuiltinFunctionFixargs : public BuiltinFunction
 275{
 276public:
 277    BuiltinFunctionFixargs(const std::string &name,
 278            const std::string &body,
 279            char typeresult,
 280            char type0= '\0',
 281            char type1= '\0',
 282            char type2= '\0',
 283            char type3= '\0');
 284private:
 285    void emit(Emit &e, const std::string &result,
 286        const std::vector<std::string> args) const;
 287    char paramtype(size_t n) const
 288    {
 289        switch(n)
 290        {
 291        case 0: return t0;
 292        case 1: return t1;
 293        case 2: return t2;
 294        case 3: return t3;
 295        default: return '\0';
 296        }
 297    }
 298    char t0, t1, t2, t3;
 299    std::vector<std::string> chunks;
 300    std::vector<int> marks;
 301};
 302
 303class BuiltinFunctionVarargs : public BuiltinFunction
 304{
 305protected:
 306    BuiltinFunctionVarargs(const std::string &name,
 307            char typeresult) :
 308        BuiltinFunction(name, typeresult)
 309    { }
 310    char paramtype(size_t /*unused*/) const
 311    {
 312        return REGany;
 313    }
 314};
 315
 316class Builtin_print : public BuiltinFunctionVarargs
 317{
 318public:
 319    Builtin_print() : BuiltinFunctionVarargs("print", REGnone)
 320    { }
 321private:
 322    void emit(Emit &e, const std::string &,
 323        const std::vector<std::string> args) const
 324    {
 325        const size_t n = args.size();
 326        for (size_t i= 0; i < n; ++i)
 327            e << INDENT "print " << args[i] << '\n';
 328    }
 329};
 330
 331class Builtin_say : public BuiltinFunctionVarargs
 332{
 333public:
 334    Builtin_say() : BuiltinFunctionVarargs("say", REGnone)
 335    { }
 336private:
 337    void emit(Emit &e, const std::string &,
 338        const std::vector<std::string> args) const
 339    {
 340        const size_t n = args.size();
 341        if (n > 0) {
 342            for (size_t i= 0; i < n - 1; ++i)
 343                e << INDENT "print " << args[i] << '\n';
 344            e << INDENT "say " << args[n-1] << '\n';
 345        }
 346        else
 347            e << INDENT "say ''\n";
 348    }
 349};
 350
 351class Builtin_cry : public BuiltinFunctionVarargs
 352{
 353public:
 354    Builtin_cry() : BuiltinFunctionVarargs("cry", REGnone)
 355    { }
 356private:
 357    void emit(Emit &e, const std::string &,
 358        const std::vector<std::string> args) const
 359    {
 360        e <<
 361            INDENT "getstderr $P0\n";
 362        const size_t n = args.size();
 363        for (size_t i= 0; i < n; ++i)
 364            e << INDENT "$P0.'print'(" << args[i] << ")\n";
 365        e << INDENT "$P0.'print'(\"\\n\")\n";
 366    }
 367};
 368
 369class Builtin_ASSERT : public BuiltinFunction
 370{
 371public:
 372    Builtin_ASSERT() : BuiltinFunction("__ASSERT__", REGnone, 1)
 373    { }
 374    char paramtype(size_t n) const { return REGint; }
 375    void emit(Emit &e, const std::string &,
 376        const std::vector<std::string> args) const
 377    {
 378         if (e.getDebug())
 379         {
 380             e <<
 381                 INDENT ".const 'Sub' __WINXED_ASSERT_check ='__WINXED_ASSERT_check'\n"
 382                 INDENT "__WINXED_ASSERT_check(" << args[0] << ")\n";
 383         }
 384    }
 385};
 386
 387const BuiltinFunction *BuiltinFunction::builtins[]= {
 388    new Builtin_ASSERT(),
 389    new Builtin_print(),
 390    new Builtin_say(),
 391    new Builtin_cry(),
 392    new BuiltinFunctionFixargs("int",
 393        "{res} = {arg0}",
 394        REGint, REGany),
 395    new BuiltinFunctionFixargs("string",
 396        "{res} = {arg0}",
 397        REGstring, REGany),
 398    new BuiltinFunctionFixargs("exit",
 399        "exit {arg0}",
 400        REGnone, REGint),
 401    new BuiltinFunctionFixargs("spawnw",
 402        "spawnw {res}, {arg0}",
 403        REGint, REGvar),
 404    new BuiltinFunctionFixargs("getstdin",
 405        "getstdin {res}",
 406        REGvar),
 407    new BuiltinFunctionFixargs("getstdout",
 408        "getstdout {res}",
 409        REGvar),
 410    new BuiltinFunctionFixargs("getstderr",
 411        "getstderr {res}",
 412        REGvar),
 413    new BuiltinFunctionFixargs("open",
 414        "root_new {res}, ['parrot';'FileHandle']\n"
 415        "{res}.'open'({arg0})",
 416        REGvar, REGstring),
 417    new BuiltinFunctionFixargs("open",
 418        "root_new {res}, ['parrot';'FileHandle']\n"
 419        "{res}.'open'({arg0},{arg1})",
 420        REGvar, REGstring, REGstring),
 421    new BuiltinFunctionFixargs("Error",
 422        "root_new {res}, ['parrot';'Exception']\n"
 423        "{res}['message'] = {arg0}\n"
 424        , REGvar, REGstring),
 425    new BuiltinFunctionFixargs("Error",
 426        "root_new {res}, ['parrot';'Exception']\n"
 427        "{res}['message'] = {arg0}\n"
 428        "{res}['severity'] = {arg1}\n"
 429        , REGvar, REGstring, REGint),
 430    new BuiltinFunctionFixargs("Error",
 431        "root_new {res}, ['parrot';'Exception']\n"
 432        "{res}['message'] = {arg0}\n"
 433        "{res}['severity'] = {arg1}\n"
 434        "{res}['type'] = {arg2}\n"
 435        , REGvar, REGstring, REGint, REGint),
 436    new BuiltinFunctionFixargs("Error",
 437        "root_new {res}, ['parrot';'Exception']\n"
 438        "{res}['message'] = {arg0}\n"
 439        "{res}['severity'] = {arg1}\n"
 440        "{res}['type'] = {arg2}\n"
 441        "{res}['payload'] = {arg3}\n"
 442        , REGvar, REGstring, REGint, REGint, REGvar),
 443    new BuiltinFunctionFixargs("elements",
 444        "elements {res}, {arg0}",
 445        REGint, REGvar),
 446    new BuiltinFunctionFixargs("length",
 447        "length {res}, {arg0}",
 448        REGint, REGstring),
 449    new BuiltinFunctionFixargs("bytelength",
 450        "bytelength {res}, {arg0}",
 451        REGint, REGstring),
 452    new BuiltinFunctionFixargs("chr",
 453        "chr $S0, {arg0}\n"
 454        "find_encoding $I0, 'utf8'\n"
 455        "trans_encoding {res}, $S0, $I0\n",
 456        REGstring, REGint),
 457    new BuiltinFunctionFixargs("ord",
 458        "ord {res}, {arg0}",
 459        REGint, REGstring),
 460    new BuiltinFunctionFixargs("ord",
 461        "ord {res}, {arg0}, {arg1}",
 462        REGint, REGstring, REGint),
 463    new BuiltinFunctionFixargs("substr",
 464        "substr {res}, {arg0}, {arg1}",
 465        REGstring, REGstring, REGint),
 466    new BuiltinFunctionFixargs("substr",
 467        "substr {res}, {arg0}, {arg1}, {arg2}",
 468        REGstring, REGstring, REGint, REGint),
 469    new BuiltinFunctionFixargs("replace",
 470        "replace {res}, {arg0}, {arg1}, {arg2}, {arg3}",
 471        REGstring, REGstring, REGint, REGint, REGstring),
 472    new BuiltinFunctionFixargs("indexof",
 473        "index {res}, {arg0}, {arg1}",
 474        REGint, REGstring, REGstring),
 475    new BuiltinFunctionFixargs("indexof",
 476        "index {res}, {arg0}, {arg1}, {arg2}",
 477        REGint, REGstring, REGstring, REGint),
 478    new BuiltinFunctionFixargs("escape",
 479        "escape {res}, {arg0}",
 480        REGstring, REGstring),
 481    new BuiltinFunctionFixargs("unescape",
 482        "$P0 = new ['String']\n"
 483        "$P0 = {arg0}\n"
 484        "{res} = $P0.'unescape'('utf8')\n",
 485        REGstring, REGstring),
 486    new BuiltinFunctionFixargs("unescape",
 487        "$P0 = new ['String']\n"
 488        "$P0 = {arg0}\n"
 489        "{res} = $P0.'unescape'({arg1})\n",
 490        REGstring, REGstring, REGstring),
 491    new BuiltinFunctionFixargs("upcase",
 492        "upcase {res}, {arg0}",
 493        REGstring, REGstring),
 494    new BuiltinFunctionFixargs("downcase",
 495        "downcase {res}, {arg0}",
 496        REGstring, REGstring),
 497    new BuiltinFunctionFixargs("titlecase",
 498        "titlecase {res}, {arg0}",
 499        REGstring, REGstring),
 500    new BuiltinFunctionFixargs("join",
 501        "join {res}, {arg0}, {arg1}",
 502        REGstring, REGstring, REGvar),
 503    new BuiltinFunctionFixargs("split",
 504        "split {res}, {arg0}, {arg1}",
 505        REGvar, REGstring, REGstring),
 506    new BuiltinFunctionFixargs("push",
 507        "push {arg0}, {arg1}",
 508        REGnone, REGvar, REGany),
 509    new BuiltinFunctionFixargs("getinterp",
 510        "getinterp {res}",
 511        REGvar),
 512    new BuiltinFunctionFixargs("get_class",
 513        "get_class {res}, {arg0}",
 514        REGvar, REGstring),
 515    new BuiltinFunctionFixargs("typeof",
 516        "typeof {res}, {arg0}",
 517        REGvar, REGvar),
 518    new BuiltinFunctionFixargs("clone",
 519        "clone {res}, {arg0}",
 520        REGvar, REGvar),
 521    new BuiltinFunctionFixargs("compreg",
 522        "compreg {res}, {arg0}",
 523        REGvar, REGstring),
 524    new BuiltinFunctionFixargs("compreg",
 525        "compreg {arg0}, {arg1}",
 526        REGnone, REGstring, REGvar),
 527    new BuiltinFunctionFixargs("load_language",
 528        "load_language {arg0}\n"
 529        "compreg {res}, {arg0}",
 530        REGvar, REGstring),
 531    new BuiltinFunctionFixargs("load_language",
 532        "load_language {arg0}\n"
 533        "compreg {res}, {arg1}",
 534        REGvar, REGstring, REGstring),
 535    new BuiltinFunctionFixargs("loadlib",
 536        "loadlib {res}, {arg0}",
 537        REGvar, REGstring),
 538    new BuiltinFunctionFixargs("load_bytecode",
 539        "load_bytecode {arg0}",
 540        REGvar, REGstring),
 541    new BuiltinFunctionFixargs("sprintf",
 542        "sprintf {res}, {arg0}, {arg1}",
 543        REGstring, REGstring, REGvar)
 544};
 545
 546const size_t BuiltinFunction::numbuiltins =
 547    sizeof(BuiltinFunction::builtins) / sizeof(BuiltinFunction::builtins[0]);
 548
 549const BuiltinFunction *BuiltinFunction::find(const std::string &name,
 550    size_t numargs)
 551{
 552    for (size_t i= 0; i < numbuiltins; ++i) {
 553        int n = builtins[i]->n;
 554        if ((n == BuiltinFunction::VarArgs || n == int(numargs)) &&
 555                builtins[i]->name_is(name) )
 556            return builtins[i];
 557    }
 558    return 0;
 559}
 560
 561BuiltinFunctionFixargs::BuiltinFunctionFixargs(const std::string &name,
 562            const std::string &body,
 563            char typeresult,
 564            char type0, char type1, char type2, char type3) :
 565        BuiltinFunction(name, typeresult,
 566                bool(type0) +bool(type1) + bool(type2) + bool(type3) ),
 567        t0(type0), t1(type1), t2(type2), t3(type3)
 568{
 569    const size_t ntags = 5;
 570    const std::string tags[ntags] =
 571        { "{res}", "{arg0}", "{arg1}", "{arg2}", "{arg3}" };
 572    std::string::size_type pos[ntags];
 573
 574    std::string aux = body;
 575
 576    for (;;)
 577    {
 578        for (size_t i = 0; i < ntags; ++i)
 579            pos[i] = aux.find(tags[i]);
 580        const std::string::size_type *minp = std::min_element(pos, pos + ntags);
 581        size_t minpos = minp - pos;
 582        std::string::size_type mpos = pos[minpos];
 583        if (mpos == std::string::npos)
 584            break;
 585        chunks.push_back(aux.substr(0, mpos));
 586        marks.push_back(minpos);
 587        aux.erase(0, mpos + tags[minpos].length());
 588    }
 589    if (aux.length() > 0)
 590    {
 591        chunks.push_back(aux);
 592        marks.push_back(-1);
 593    }
 594}
 595
 596void BuiltinFunctionFixargs::emit(Emit &e, const std::string &result,
 597    const std::vector<std::string> args) const
 598{
 599    std::string body;
 600    size_t n = chunks.size();
 601    for (size_t i = 0; i < n; ++i)
 602    {
 603        body+= chunks[i];
 604        int m = marks[i];
 605        switch (m)
 606        {
 607          case 0:
 608            body+= result;
 609            break;
 610          case 1: case 2: case 3: case 4:
 611            body+= args[m-1];
 612            break;
 613          case -1:
 614            break;
 615          default:
 616            throw InternalError("Unexpected failure in builtin");
 617        }
 618    }
 619
 620    size_t pos = 0;
 621    size_t prev = 0;
 622    while ((pos = body.find("\n", prev)) != std::string::npos)
 623    {
 624        e << INDENT << body.substr(prev, pos - prev + 1);
 625        prev = pos + 1;
 626    }
 627    e << INDENT << body.substr(prev) << '\n';
 628}
 629
 630//**********************************************************************
 631
 632class Annotated
 633{
 634protected:
 635    Annotated(const Token & tstart) : start(tstart)
 636    { }
 637public:
 638    void annotate(Emit &e)
 639    {
 640        e.annotate(start);
 641    }
 642    const Token & getstart() const
 643    {
 644        return start;
 645    }
 646private:
 647    const Token start;
 648};
 649
 650//**********************************************************************
 651
 652class ConstantValue
 653{
 654public:
 655    ConstantValue(char type, const Token &value) :
 656        t(type), v(value)
 657    {
 658        switch(t)
 659        {
 660        case REGint:
 661            if (!v.isinteger())
 662                throw SyntaxError("Invalid const int value", v);
 663            break;
 664        case REGstring:
 665            if (!v.isliteralstring())
 666                throw SyntaxError("Invalid const string value", v);
 667            break;
 668        case 'n':
 669            // Special case
 670            if (!v.isidentifier())
 671                throw SyntaxError("Invalid const string value", v);
 672            break;
 673        default:
 674            throw InternalError("Invalid const type");
 675        }
 676    }
 677    char type() const { return t; }
 678    Token value() const { return v; }
 679private:
 680    char t;
 681    Token v;
 682};
 683
 684//**********************************************************************
 685
 686class ClassStatement;
 687
 688typedef std::vector<std::string> ClassKey;
 689
 690std::string dotted(const ClassKey &ck)
 691{
 692    size_t l = ck.size();
 693    if (l == 0)
 694        return "(anonimous)";
 695    else
 696    {
 697        std::string r = ck[0];
 698        for (size_t i = 1; i < l; ++i)
 699        {
 700            r+= '.';
 701            r+= ck[i];
 702        }
 703        return r;
 704    }
 705}
 706
 707//**********************************************************************
 708
 709class FunctionStatement;
 710
 711class BlockBase
 712{
 713public:
 714    virtual char checklocal(const std::string &name) const = 0;
 715    virtual char checkconstant(const std::string &name) const = 0;
 716    virtual ConstantValue getconstant(const std::string &name) const = 0;
 717    virtual FunctionStatement *getfunction(const std::string &name) const = 0;
 718    virtual void genconstant(const std::string &name, char type, const Token &value) = 0;
 719    virtual std::string genlocallabel() = 0;
 720    virtual std::string genlocalregister(char type)= 0;
 721    virtual void freelocalregister(const std::string &)= 0;
 722    virtual std::string gentemp(char /*unused*/)
 723    {
 724        throw std::runtime_error("No temp registers here!");
 725    }
 726    virtual void freetempregs()
 727    {
 728        throw std::runtime_error("No temp registers here!");
 729    }
 730    virtual void genlocal(const std::string &name, char type) = 0;
 731    virtual bool islocal(std::string /*name*/) const = 0;
 732    virtual std::string getbreaklabel() const
 733    {
 734        throw std::runtime_error("No break allowed");
 735    }
 736    virtual std::string getcontinuelabel() const
 737    {
 738        throw std::runtime_error("No continue allowed");
 739    }
 740    virtual ClassStatement *findclass(const ClassKey &classkey)
 741    {
 742        std::cerr << "BlockBase::findclass **WRONG CALL**\n";
 743        return 0;
 744    }
 745    virtual ~BlockBase() { }
 746};
 747
 748class Block : public BlockBase
 749{
 750public:
 751    Block();
 752    virtual unsigned int blockid() = 0;
 753    void genlocal(const std::string &name, char type);
 754    bool islocal(std::string name) const;
 755    void genconstant(const std::string &name, char type, const Token &value);
 756    char checklocal(const std::string &name) const;
 757    char checkconstant(const std::string &name) const;
 758    ConstantValue getconstant(const std::string &name) const;
 759    std::string genlabel();
 760protected:
 761    typedef std::map<std::string, char> Locals;
 762    Locals locals;
 763    typedef std::map<std::string, ConstantValue> Constants;
 764    Constants constants;
 765};
 766
 767class InBlock : public BlockBase
 768{
 769protected:
 770    InBlock(BlockBase &block) : bl(block) { };
 771public:
 772    std::string getbreaklabel() const
 773    {
 774        return bl.getbreaklabel();
 775    }
 776    std::string getcontinuelabel() const
 777    {
 778        return bl.getcontinuelabel();
 779    }
 780    char checklocal(const std::string &name) const
 781    {
 782        return bl.checklocal(name);
 783    }
 784    char checkconstant(const std::string &name) const
 785    {
 786        return bl.checkconstant(name);
 787    }
 788    void genconstant(const std::string &name, char type, const Token &value)
 789    {
 790        bl.genconstant(name, type, value);
 791    }
 792    ConstantValue getconstant(const std::string &name) const
 793    {
 794        return bl.getconstant(name);
 795    }
 796    FunctionStatement *getfunction(const std::string &name) const
 797    {
 798        return bl.getfunction(name);
 799    }
 800    std::string genlocallabel()
 801    {
 802        return bl.genlocallabel();
 803    }
 804    std::string genlocalregister(char type)
 805    {
 806        return bl.genlocalregister(type);
 807    }
 808    void freelocalregister(const std::string &reg)
 809    {
 810        bl.freelocalregister(reg);
 811    }
 812    std::string gentemp(char type)
 813    {
 814        return bl.gentemp(type);
 815    }
 816    void freetempregs()
 817    {
 818        bl.freetempregs();
 819    }
 820    void genlocal(const std::string &name, char type)
 821    {
 822        bl.genlocal(name, type);
 823    }
 824    bool islocal(std::string name) const
 825    {
 826        return bl.islocal(name);
 827    }
 828    ClassStatement *findclass(const ClassKey &classkey)
 829    {
 830        return bl.findclass(classkey);
 831    }
 832private:
 833    BlockBase &bl;
 834};
 835
 836Block::Block()
 837{ }
 838
 839void Block::genlocal(const std::string &name, char type)
 840{
 841    locals[name]= type;
 842}
 843
 844bool Block::islocal(std::string name) const
 845{
 846    return locals.find(name) != locals.end();
 847}
 848
 849void Block::genconstant(const std::string &name, char type, const Token &value)
 850{
 851    constants.insert(std::make_pair(name, ConstantValue(type, value)));
 852}
 853
 854char Block::checklocal(const std::string &name) const
 855{
 856    Locals::const_iterator it= locals.find(name);
 857    if (it != locals.end() )
 858        return it->second;
 859    Constants::const_iterator itc= constants.find(name);
 860    if (itc != constants.end() )
 861        return itc->second.type();
 862    return '\0';
 863}
 864
 865char Block::checkconstant(const std::string &name) const
 866{
 867    Constants::const_iterator itc= constants.find(name);
 868    if (itc != constants.end() )
 869        return itc->second.type();
 870    return '\0';
 871}
 872
 873ConstantValue Block::getconstant(const std::string &name) const
 874{
 875    Constants::const_iterator itc= constants.find(name);
 876    if (itc != constants.end() )
 877        return itc->second;
 878    throw InternalError("No such constant");
 879}
 880
 881std::string Block::genlabel()
 882{
 883    return genlocallabel();
 884}
 885
 886//**********************************************************************
 887
 888class SubBlock : public Block
 889{
 890public:
 891    SubBlock(Block &parentblock) :
 892        parent(parentblock),
 893        id(parent.blockid()),
 894        nlabel(0)
 895    {
 896    }
 897    std::string getbreaklabel() const;
 898    std::string getcontinuelabel() const;
 899    bool islocal(std::string name) const;
 900    char checklocal(const std::string &name) const;
 901    char checkconstant(const std::string &name) const;
 902    ConstantValue getconstant(const std::string &name) const;
 903    FunctionStatement *getfunction(const std::string &name) const
 904    {
 905        return parent.getfunction(name);
 906    }
 907    std::string genlocalregister(char type)
 908    {
 909        return parent.genlocalregister(type);
 910    }
 911    void freelocalregister(const std::string &reg)
 912    {
 913        parent.freelocalregister(reg);
 914    }
 915    std::string gentemp(char type)
 916    {
 917        return parent.gentemp(type);
 918    }
 919    void freetempregs()
 920    {
 921        parent.freetempregs();
 922    }
 923    std::string genlocallabel();
 924    ClassStatement *findclass(const ClassKey &classkey)
 925    {
 926        return parent.findclass(classkey);
 927    }
 928private:
 929    unsigned int blockid();
 930
 931    Block &parent;
 932    unsigned int id;
 933    unsigned int nlabel;
 934};
 935
 936unsigned int SubBlock::blockid()
 937{
 938    return parent.blockid();
 939}
 940
 941std::string SubBlock::getbreaklabel() const
 942{
 943    return parent.getbreaklabel();
 944}
 945
 946std::string SubBlock::getcontinuelabel() const
 947{
 948    return parent.getcontinuelabel();
 949}
 950
 951char SubBlock::checklocal(const std::string &name) const
 952{
 953    if (char c= Block::checklocal(name))
 954        return c;
 955    else
 956        return parent.checklocal(name);
 957}
 958
 959bool SubBlock::islocal(std::string name) const
 960{
 961    return checklocal(name) != '\0';
 962}
 963
 964char SubBlock::checkconstant(const std::string &name) const
 965{
 966    char c= Block::checkconstant(name);
 967    if (c == '\0')
 968        c= parent.checkconstant(name);
 969    return c;
 970}
 971
 972ConstantValue SubBlock::getconstant(const std::string &name) const
 973{
 974    if (Block::checkconstant(name))
 975        return Block::getconstant(name);
 976    else
 977        return parent.getconstant(name);
 978}
 979
 980std::string SubBlock::genlocallabel()
 981{
 982    std::ostringstream l;
 983    l << "__label_" << id << '_' << ++nlabel;
 984    return l.str();
 985}
 986
 987//**********************************************************************
 988
 989class NamespaceKey
 990{
 991    typedef std::vector <std::string> key_t;
 992public:
 993    NamespaceKey() { }
 994    NamespaceKey(const std::string &name) :
 995        key(1, name)
 996    {
 997    }
 998    NamespaceKey(const key_t &newkey) :
 999        key(newkey)
1000    {
1001    }
1002    bool isroot() const
1003    {
1004        return key.empty();
1005    }
1006    NamespaceKey parent() const
1007    {
1008        key_t newkey = key;
1009        newkey.pop_back();
1010        return NamespaceKey(newkey);
1011    }
1012    std::string get_key() const
1013    {
1014        std::string r= "[ ";
1015        for (size_t i= 0; i < key.size(); ++i)
1016        {
1017            if (i > 0)
1018                r+= "; ";
1019            r+= '\'' + key [i] + '\'';
1020        }
1021        r+= " ]";
1022        return r;
1023    }
1024    void emit (Emit &e) const
1025    {
1026        e << ".namespace " << get_key() << '\n';
1027    }
1028private:
1029    std::vector <std::string> key;
1030};
1031
1032//**********************************************************************
1033
1034class FunctionBlock : public SubBlock
1035{
1036public:
1037    FunctionBlock(Block &parent) :
1038        SubBlock(parent),
1039        subblocks(0),
1040        nreg(0), nlabel(0)
1041    {
1042    }
1043public:
1044    std::string genlocallabel();
1045    std::string genlocalregister(char type);
1046    std::string gentemp(char type);
1047    std::string genregister(char type);
1048    void freelocalregister(const std::string &reg);
1049    void freeregister(const std::string &reg);
1050protected:
1051    size_t tempsused() const
1052    {
1053        return tempi.size() + temps.size() + tempp.size() +
1054            + freetempi.size() + freetemps.size() + freetempp.size();
1055    }
1056    void freetempregs()
1057    {
1058        using std::copy;
1059        using std::back_inserter;
1060        copy(tempi.begin(), tempi.end(), back_inserter(freetempi));
1061        tempi= std::vector<std::string>();
1062        copy(temps.begin(), temps.end(), back_inserter(freetemps));
1063        temps= std::vector<std::string>();
1064        copy(tempp.begin(), tempp.end(), back_inserter(freetempp));
1065        tempp= std::vector<std::string>();
1066    }
1067private:
1068    unsigned int subblocks;
1069    unsigned int nreg;
1070    unsigned int nlabel;
1071    std::vector <std::string> tempi;
1072    std::vector <std::string> temps;
1073    std::vector <std::string> tempp;
1074    std::vector <std::string> freetempi;
1075    std::vector <std::string> freetemps;
1076    std::vector <std::string> freetempp;
1077};
1078
1079std::string FunctionBlock::genlocalregister(char type)
1080{
1081    if (type != REGint && type != REGstring && type != REGvar)
1082        throw InternalError("invalid register type");
1083    std::ostringstream l;
1084    l << '$' << type << ++nreg;
1085    return l.str();
1086}
1087
1088void FunctionBlock::freelocalregister(const std::string &reg)
1089{
1090    if (reg.at(0) != '$')
1091        throw InternalError("invalid free register");
1092    switch(reg.at(1))
1093    {
1094    case REGint:    freetempi.push_back(reg); break;
1095    case REGstring: freetemps.push_back(reg); break;
1096    case REGvar:    freetempp.push_back(reg); break;
1097    default: throw InternalError("invalid free register");
1098    }
1099}
1100
1101void FunctionBlock::freeregister(const std::string &reg)
1102{
1103   return freelocalregister(reg);
1104}
1105
1106std::string FunctionBlock::genregister(char type)
1107{
1108    return genlocalregister(type);
1109}
1110
1111std::string FunctionBlock::gentemp(char type)
1112{
1113    std::vector<std::string> &usefree= type == REGint ? freetempi :
1114        type == REGstring ? freetemps : freetempp;
1115    std::string temp;
1116    if (usefree.size() > 0)
1117    {
1118        temp= usefree.back();
1119        usefree.pop_back();
1120    }
1121    else
1122    {
1123        temp= genlocalregister(type);
1124        switch(type)
1125        {
1126        case REGint:    tempi.push_back(temp); break;
1127        case REGstring: temps.push_back(temp); break;
1128        default:        tempp.push_back(temp); break;
1129        }
1130    }
1131    return temp;
1132}
1133
1134std::string FunctionBlock::genlocallabel()
1135{
1136    std::ostringstream l;
1137    l << "__label_" << ++nlabel;
1138    return l.str();
1139}
1140
1141//**********************************************************************
1142
1143class NamespaceBlockBase;
1144class Expr;
1145
1146//**********************************************************************
1147
1148class BaseStatement
1149{
1150public:
1151    virtual bool isempty() { return false; }
1152    virtual void emit (Emit &e) = 0;
1153    virtual BaseStatement *optimize() { return this; }
1154    void optimize_branch(BaseStatement *&branch);
1155    void optimize_branch(Expr *&branch);
1156    virtual ~BaseStatement() { };
1157};
1158
1159//**********************************************************************
1160
1161class MultiStatement : public BaseStatement
1162{
1163public:
1164    MultiStatement(BaseStatement *st1, BaseStatement *st2)
1165    {
1166        subst.push_back(st1);
1167        subst.push_back(st2);
1168    }
1169    void push(BaseStatement *st)
1170    {
1171        subst.push_back(st);
1172    }
1173private:
1174    std::vector <BaseStatement *> subst;
1175    BaseStatement *optimize()
1176    {
1177        for (size_t i= 0; i < subst.size(); ++i)
1178            subst[i] = subst[i]->optimize();
1179        return this;
1180    }
1181    void emit (Emit &e)
1182    {
1183        for (size_t i= 0; i < subst.size(); ++i)
1184            subst[i]->emit(e);
1185    }
1186};
1187
1188BaseStatement *addtomulti(BaseStatement *oldst, BaseStatement *newst)
1189{
1190    if (! oldst)
1191        return newst;
1192    else if (MultiStatement *multi = dynamic_cast<MultiStatement *>(oldst))
1193    {
1194        multi->push(newst);
1195        return multi;
1196    }
1197    else
1198        return new MultiStatement(oldst, newst);
1199}
1200
1201//**********************************************************************
1202
1203enum ClassSpecifierType
1204{
1205    CLASSSPECIFIER_invalid,
1206    CLASSSPECIFIER_parrotkey,
1207    CLASSSPECIFIER_id
1208};
1209
1210class ClassSpecifier : public Annotated
1211{
1212protected:
1213    ClassSpecifier(const Token &t) : Annotated(t)
1214    { }
1215public:
1216    virtual ClassSpecifierType reftype() const
1217    { return CLASSSPECIFIER_invalid; }
1218    virtual ~ClassSpecifier() {}
1219    virtual std::string basename() const = 0;
1220    virtual void emit(Emit &e) = 0;
1221};
1222
1223ClassSpecifier *parseClassSpecifier(const Token &start, Tokenizer &tk,
1224        BlockBase &owner);
1225
1226//**********************************************************************
1227
1228class SubStatement : public BaseStatement, public InBlock
1229{
1230public:
1231    SubStatement(Block &block);
1232};
1233
1234SubStatement::SubStatement(Block &block) :
1235    InBlock(block)
1236{
1237}
1238
1239//**********************************************************************
1240
1241class EmptyStatement : public BaseStatement
1242{
1243private:
1244    bool isempty() { return true; }
1245    void emit (Emit &) { };
1246};
1247
1248//**********************************************************************
1249
1250class BlockStatement : public BaseStatement, public SubBlock
1251{
1252public:
1253    BlockStatement (Block &parentblock) :
1254            SubBlock(parentblock)
1255    {
1256    }
1257};
1258
1259//**********************************************************************
1260
1261class Expr : public InBlock, public Annotated
1262{
1263public:
1264    Expr(BlockBase &block, const Token & tstart) :
1265        InBlock(block),
1266        Annotated(tstart)
1267    {
1268    }
1269    virtual Expr *optimize()
1270    {
1271        return this;
1272    }
1273    virtual bool isleft() const { return false; }
1274    virtual void emitleft(Emit &)
1275    {
1276        std::cerr << typeid(*this).name() << '\n';
1277        throw InternalError("Not a left-side expression");
1278    }
1279    virtual void emitleft(Emit &, const std::string &)
1280    {
1281        std::cerr << typeid(*this).name() << '\n';
1282        throw InternalError("Not a left-side expression");
1283    }
1284    virtual void emitassign(Emit &, Expr &, const std::string &)
1285    {
1286        std::cerr << typeid(*this).name() << '\n';
1287        throw InternalError("Not an assignable expression");
1288    }
1289    virtual void emit(Emit &e, const std::string &result) = 0;
1290    virtual std::string emit_get(Emit &e);
1291    virtual bool issimple() const { return false; }
1292    virtual const Token &gettoken() const
1293    {
1294        std::cerr << typeid(*this).name() << '\n';
1295        throw InternalError("In gettoken: Not a simple expression");
1296    }
1297    virtual bool isidentifier() const { return false; }
1298    virtual std::string getidentifier() const
1299    { throw InternalError("Not an identifier"); }
1300    virtual bool isnull() const { return false; }
1301    virtual bool isliteralinteger() const { return false; }
1302    virtual bool isinteger() const { return false; }
1303    virtual int getintegervalue () const
1304    {
1305        std::cerr << typeid(*this).name() << '\n';
1306        throw InternalError("Not an integer");
1307    }
1308    virtual bool isliteralstring() const { return false; }
1309    virtual std::string getstringvalue () const
1310    { throw InternalError("Not a string"); }
1311    virtual bool isstring() const { return false; }
1312    virtual bool isindex() const { return false; }
1313    char checkresult() const
1314    {
1315        if (isinteger() ) return REGint;
1316        else if (isstring() ) return REGstring;
1317        else return REGvar;
1318    }
1319    void optimize_branch(Expr *&branch)
1320    { branch= branch->optimize(); }
1321};
1322
1323Expr * parseExpr(BlockBase &block, Tokenizer &tk);
1324
1325//**********************************************************************
1326
1327class Condition : public InBlock
1328{
1329public:
1330    Condition (Block &block, Tokenizer &tk);
1331    Condition (BlockBase &block, Expr *condexpr);
1332    Condition *optimize();
1333    bool issimple() const;
1334    bool isinteger() const { return true; }
1335    //bool isstring() const { return expr->isstring(); }
1336    bool isliteralinteger() const;
1337    std::string value() const;
1338    std::string emit(Emit &e);
1339    void emit_if(Emit &e, const std::string &labeltrue);
1340    void emit_else(Emit &e, const std::string &labelfalse);
1341    enum Value { CVtrue, CVfalse, CVruntime };
1342    Value getvalue() const;
1343private:
1344    Expr *expr;
1345};
1346
1347//**********************************************************************
1348
1349void BaseStatement::optimize_branch(BaseStatement *&branch)
1350{
1351    if (branch)
1352        branch= branch->optimize();
1353}
1354
1355void BaseStatement::optimize_branch(Expr *&branch)
1356{
1357    if (branch)
1358        branch= branch->optimize();
1359}
1360
1361//**********************************************************************
1362
1363class Modifier
1364{
1365public:
1366    Modifier(BlockBase &block, Tokenizer &tk)
1367    {
1368        Token t= tk.get();
1369        if (!t.isidentifier())
1370            throw Expected("Modifier name", t);
1371        start = t;
1372        name= t.identifier();
1373        t= tk.get();
1374        if (!t.isop('('))
1375            tk.unget(t);
1376        else
1377        {
1378            do
1379            {
1380                args.push_back(parseExpr(block, tk));
1381            } while ((t= tk.get()).isop(','));
1382            RequireOp(')', t);
1383        }
1384    }
1385    std::string getname() const { return name; }
1386    Token getstart() const { return start; }
1387    void optimize()
1388    {
1389        for (size_t i= 0; i < args.size(); ++i)
1390            args[i]= args[i]->optimize();
1391    }
1392    size_t numargs() const { return args.size(); }
1393    Expr *getarg(size_t narg) const
1394    {
1395        return args.at(narg);
1396    }
1397    int getintegervalue(size_t narg) const
1398    {
1399        Expr *arg= args.at(narg);
1400        return arg->getintegervalue();
1401    }
1402    std::string getstringvalue(size_t narg) const
1403    {
1404        Expr *arg= args.at(narg);
1405        return arg->getstringvalue();
1406    }
1407private:
1408    Token start;
1409    std::string name;
1410    std::vector <Expr *> args;
1411};
1412
1413//**********************************************************************
1414
1415class ModifierList
1416{
1417public:
1418    bool has_modifier(const std::string &name) const
1419    {
1420        return modifiers.find(name) != modifiers.end();
1421    }
1422    const Modifier * getmodifier(const std::string &name) const
1423    {
1424        ModList::const_iterator it= modifiers.find(name);
1425        if (it != modifiers.end())
1426            return &it->second;
1427        else
1428            return NULL;
1429    }
1430    void parse(BlockBase &block, Tokenizer &tk)
1431    {
1432        Token t;
1433        do {
1434            Modifier m(block, tk);
1435            std::string name= m.getname();
1436            modifiers.insert(std::make_pair(name, m));
1437        } while ((t= tk.get()).isop(','));
1438        RequireOp(']', t);
1439    }
1440    void optimize()
1441    {
1442        for (ModList::iterator it= modifiers.begin();
1443                it != modifiers.end(); ++it)
1444           it->second.optimize();
1445    }
1446protected:
1447    typedef std::map<std::string, Modifier> ModList;
1448    ModList modifiers;
1449};
1450
1451//**********************************************************************
1452
1453class FunctionModifiers : public ModifierList
1454{
1455public:
1456    FunctionModifiers(BlockBase &block, Tokenizer &tk)
1457    {
1458        Token t= tk.get();
1459        if (! t.isop('[') )
1460            tk.unget(t);
1461        else
1462            parse(block, tk);
1463    }
1464};
1465
1466//**********************************************************************
1467
1468class ArgumentModifierList : public ModifierList
1469{
1470public:
1471    void emitmodifiers(Emit &e)
1472    {
1473        bool isflat = false, isnamed = false;
1474        Expr * setname = 0;
1475        for (ModList::iterator it = modifiers.begin(); it != modifiers.end();
1476                ++it)
1477        {
1478            std::string name = it->first;
1479            Modifier &modifier = it->second;
1480            if (name == "flat")
1481                isflat = true;
1482            if (name == "named")
1483            {
1484                isnamed = true;
1485                switch (modifier.numargs())
1486                {
1487                  case 0:
1488                    break;
1489                  case 1:
1490                    setname = modifier.getarg(0);
1491                    break;
1492                  default:
1493                    throw SyntaxError("Invalid modifier", modifier.getstart());
1494                }
1495            }
1496        }
1497        if (isflat)
1498        {
1499            if (isnamed)
1500                e << " :flat :named";
1501            else
1502                e << " :flat";
1503        }
1504        else if (isnamed)
1505        {
1506            e << " :named";
1507            if (setname)
1508                e << '(';
1509                setname->emit(e, "");
1510                e << ')';
1511        }
1512    }
1513};
1514
1515class Argument
1516{
1517public:
1518    Argument(BlockBase &block, Tokenizer &tk) :
1519            modifiers(0)
1520    {
1521        expr = parseExpr(block, tk);
1522        Token t = tk.get();
1523        if (t.isop(':'))
1524        {
1525            t = tk.get();
1526            if (! t.isop('['))
1527                throw Expected("modifier list", t);
1528            modifiers = new ArgumentModifierList();
1529            modifiers->parse(block, tk);
1530        }
1531        else
1532            tk.unget(t);
1533    }
1534    Expr *get()
1535    {
1536        return expr;
1537    }
1538    ArgumentModifierList *getmodifiers()
1539    {
1540        return modifiers;
1541    }
1542    Argument *optimize()
1543    {
1544        expr= expr->optimize();
1545        return this;
1546    }
1547    void emit(Emit &e, const std::string &result)
1548    {
1549        expr->emit(e, result);
1550    }
1551private:
1552    Expr *expr;
1553    ArgumentModifierList *modifiers;
1554};
1555
1556class ArgumentList : public InBlock
1557{
1558public:
1559    ArgumentList(BlockBase &block, Tokenizer &tk, char delimiter);
1560    int numargs() const
1561    {
1562        return args ? args->size() : 0;
1563    }
1564    Expr *getfreearg(int i)
1565    {
1566        return args->at(i)->get();
1567    }
1568    void optimize();
1569    void prepare(Emit &e);
1570    void emit(Emit &e);
1571private:
1572    std::vector <Argument *> *args;
1573    std::vector <std::string> argregs;
1574};
1575
1576//**********************************************************************
1577
1578class ExprStatement : public BaseStatement
1579{
1580public:
1581    ExprStatement(Block &parentblock, Tokenizer &tk);
1582private:
1583    BaseStatement *optimize();
1584    void emit (Emit &e);
1585
1586    Expr *expr;
1587};
1588
1589//**********************************************************************
1590
1591class CompoundStatement : public BlockStatement
1592{
1593public:
1594    CompoundStatement(Block &parentblock, Tokenizer &tk);
1595    BaseStatement *optimize();
1596    void emit (Emit &e);
1597    Token getend() const { return tend; }
1598private:
1599    std::vector <BaseStatement *> subst;
1600    Token tend;
1601};
1602
1603//**********************************************************************
1604
1605class ValueStatement : public SubStatement, public Annotated
1606{
1607public:
1608    ValueStatement(Block & block, const Token & tstart);
1609protected:
1610    void parseArray(Tokenizer &tk);
1611    void emit (Emit &e, const std::string &name, char type);
1612
1613    enum ValueType { ValueSimple, ValueArray, ValueFixedArray };
1614    ValueType vtype;
1615    Expr *esize;
1616    std::vector<Expr *> value;
1617private:
1618    BaseStatement *optimize();
1619};
1620
1621//**********************************************************************
1622
1623class IntStatement : public ValueStatement
1624{
1625public:
1626    IntStatement(Block & block, const Token &st, Tokenizer &tk);
1627    void emit (Emit &e);
1628    using ValueStatement::emit;
1629private:
1630    std::string name;
1631};
1632
1633//**********************************************************************
1634
1635class StringStatement : public ValueStatement
1636{
1637public:
1638    StringStatement(Block & block, const Token &st, Tokenizer &tk);
1639    void emit (Emit &e);
1640    using ValueStatement::emit;
1641private:
1642    std::string name;
1643};
1644
1645//**********************************************************************
1646
1647template <class DECST> 
1648BaseStatement *parseDeclare(Block & block, const Token &st, Tokenizer &tk)
1649{
1650    BaseStatement *multi = 0;
1651    Token t;
1652    do {
1653       BaseStatement *item = new DECST(block, st, tk);
1654       multi = addtomulti(multi, item);
1655       t= tk.get();
1656    } while (t.isop(','));
1657    RequireOp (';', t);
1658    return multi;
1659}
1660
1661//**********************************************************************
1662
1663class VarStatement : public ValueStatement
1664{
1665public:
1666    VarStatement(Block & block, const Token &st, Tokenizer &tk);
1667    void emit (Emit &e);
1668private:
1669    std::string name;
1670};
1671
1672//**********************************************************************
1673
1674class ConstStatement : public ValueStatement
1675{
1676public:
1677    ConstStatement(Block & block, const Token &st, Tokenizer &tk, char typed);
1678    BaseStatement *optimize();
1679    void emit (Emit &e);
1680private:
1681    char type;
1682    std::string name;
1683    Expr *value;
1684};
1685
1686BaseStatement * parseConst(Block & block, const Token &st, Tokenizer &tk);
1687
1688//**********************************************************************
1689
1690class LabelStatement: public SubStatement
1691{
1692public:
1693    LabelStatement(Block &block, const std::string &name);
1694    void emit (Emit &e);
1695private:
1696    std::string labelname;
1697    std::string codename;
1698};
1699
1700//**********************************************************************
1701
1702class ReturnStatement : public SubStatement, public Annotated
1703{
1704public:
1705    ReturnStatement(Block & block, const Token & tstart, Tokenizer &tk);
1706    BaseStatement *optimize();
1707    void emit (Emit &e);
1708private:
1709    ArgumentList *values;
1710};
1711
1712//**********************************************************************
1713
1714class BreakStatement : public SubStatement
1715{
1716public:
1717    BreakStatement(Block &block, Tokenizer &tk) :
1718        SubStatement(block)
1719    {
1720        ExpectOp(';', tk);
1721    }
1722private:
1723    void emit (Emit &e)
1724    {
1725        e << INDENT "goto " << getbreaklabel() << " # break\n";
1726    }
1727};
1728
1729//**********************************************************************
1730
1731class ContinueStatement : public SubStatement
1732{
1733public:
1734    ContinueStatement(Block &block, Tokenizer &tk) :
1735        SubStatement(block)
1736    {
1737        ExpectOp(';', tk);
1738    }
1739private:
1740    void emit (Emit &e)
1741    {
1742        e << INDENT "goto " << getcontinuelabel() << " # continue\n";
1743    }
1744};
1745
1746//**********************************************************************
1747
1748class BreakableStatement : public BlockStatement
1749{
1750protected:
1751    BreakableStatement(Block &block) :
1752        BlockStatement(block)
1753    { }
1754    std::string getbreaklabel() const
1755    {
1756        if (breaklabel.empty())
1757            throw InternalError("attempt to use break label before creating");
1758        return breaklabel;
1759    }
1760    std::string genbreaklabel()
1761    {
1762        if (! breaklabel.empty())
1763            throw InternalError("attempt to create break label twice");
1764        breaklabel = genlabel();
1765        return breaklabel;
1766    }
1767private:
1768    std::string breaklabel;
1769};
1770
1771class ContinuableStatement : public BreakableStatement
1772{
1773protected:
1774    ContinuableStatement(Block &block) :
1775        BreakableStatement(block)
1776    { }
1777    std::string getcontinuelabel() const
1778    {
1779        if (continuelabel.empty())
1780            throw InternalError("attempt to use continue label before creating");
1781        return continuelabel;
1782    }
1783    std::string gencontinuelabel()
1784    {
1785        if (! continuelabel.empty())
1786            throw InternalError("attempt to create continue label twice");
1787        continuelabel = genlabel();
1788        return continuelabel;
1789    }
1790private:
1791    std::string continuelabel;
1792};
1793
1794//**********************************************************************
1795
1796class SwitchBaseStatement : public BreakableStatement
1797{
1798protected:
1799    SwitchBaseStatement(Block &block);
1800    void parse_cases(Tokenizer &tk);
1801    std::vector<Expr *> casevalue;
1802    std::vector<std::vector<BaseStatement *> > casest;
1803    std::vector<BaseStatement *> defaultst;
1804    BaseStatement *optimize();
1805};
1806
1807class SwitchStatement : public SwitchBaseStatement
1808{
1809public:
1810    SwitchStatement(Block &block, Tokenizer &tk);
1811private:
1812    BaseStatement *optimize();
1813    void emit (Emit &e);
1814    Expr *condition;
1815};
1816
1817class SwitchCaseStatement : public SwitchBaseStatement
1818{
1819public:
1820    SwitchCaseStatement(Block &block, Tokenizer &tk);
1821private:
1822    void emit (Emit &e);
1823};
1824
1825//**********************************************************************
1826
1827class IfStatement : public BlockStatement
1828{
1829public:
1830    IfStatement(Block &block, Tokenizer &tk);
1831private:
1832    BaseStatement *optimize();
1833    void emit (Emit &e);
1834    Condition *condition;
1835    BaseStatement *st;
1836    BaseStatement *stelse;
1837};
1838
1839//**********************************************************************
1840
1841class WhileStatement : public ContinuableStatement
1842{
1843public:
1844    WhileStatement(Block &block, Tokenizer &tk);
1845private:
1846    BaseStatement *optimize();
1847    void emit (Emit &e);
1848    Condition *condition;
1849    BaseStatement *st;
1850};
1851
1852//**********************************************************************
1853
1854class DoStatement : public ContinuableStatement
1855{
1856public:
1857    DoStatement(Block &block, Tokenizer &tk);
1858private:
1859    BaseStatement *optimize();
1860    void emit (Emit &e);
1861    Condition *condition;
1862    BaseStatement *st;
1863};
1864
1865//**********************************************************************
1866
1867class ForeachStatement : public ContinuableStatement
1868{
1869public:
1870    ForeachStatement(Block &block, Tokenizer &tk);
1871private:
1872    BaseStatement *optimize();
1873    void emit (Emit &e);
1874
1875    Token start;
1876    std::string varname;
1877    char vartype;
1878    Expr * container;
1879    BaseStatement *st;
1880};
1881
1882//**********************************************************************
1883
1884class ForStatement : public ContinuableStatement
1885{
1886public:
1887    ForStatement(Block &block, Tokenizer &tk);
1888private:
1889    BaseStatement *optimize();
1890    void emit (Emit &e);
1891
1892    BaseStatement * initializer;
1893    Expr * condition;
1894    Expr * iteration;
1895    BaseStatement *st;
1896};
1897
1898//**********************************************************************
1899
1900class ThrowStatement : public SubStatement
1901{
1902public:
1903    ThrowStatement(Block &block, const Token &st, Tokenizer &tk);
1904private:
1905    BaseStatement *optimize();
1906    void emit (Emit &e);
1907    Token pos;
1908    Expr * excep;
1909};
1910
1911//**********************************************************************
1912
1913class TryStatement : public BlockStatement, public Annotated
1914{
1915public:
1916    TryStatement(Block &block, const Token &st, Tokenizer &tk);
1917private:
1918    BaseStatement *optimize();
1919    void emit (Emit &e);
1920    BaseStatement *stry;
1921    BaseStatement *scatch;
1922    std::string exname;
1923};
1924
1925//**********************************************************************
1926
1927class FunctionParameter
1928{
1929public:
1930    FunctionParameter(FunctionStatement *owner, Tokenizer &tk);
1931    char gettype() const { return type; }
1932    std::string getname() const { return name; }
1933    void emit (Emit &e);
1934private:
1935    std::string name;
1936    char type;
1937    ModifierList modifiers;
1938    bool has_modifier(const std::string &name) const
1939    {
1940        return modifiers.has_modifier(name);
1941    }
1942};
1943
1944//**********************************************************************
1945
1946class FunctionStatement : protected FunctionModifiers, public FunctionBlock,
1947        public Annotated
1948{
1949public:
1950    FunctionStatement(Tokenizer &tk, const Token & tstart,
1951        Block &parent,
1952        const std::string &funcname);
1953    virtual std::string getsubid() const;
1954    std::string getname() const { return name; }
1955    void optimize();
1956    virtual void emit (Emit &e);
1957    void local(std::string name);
1958    bool islocal(std::st

Large files files are truncated, but you can click here to view the full file