Value Parse()
 {
     Value v = ParseFactor();
     Gobble('LF');
     Expect('EOF');
     return v;
 }
Beispiel #2
0
 Value Parse()
 {
     Value v = ParseFactor();
     Gobble(T_LINEFEED);
     Expect(T_ENDOFFILE);
     return v;
 }
    Value ParseFactor()
    {
        switch (lex.token)
        {
            case 'INT': { int i    = atoi(lex.sattr.c_str()); lex.Next(); return Value(i); }
            case 'FLT': { double f = atof(lex.sattr.c_str()); lex.Next(); return Value((float)f); }
            case 'STR': { string s = lex.sattr;               lex.Next(); auto str = g_vm->NewString(s); allocated.push_back(str); return Value(str); }     
            case 'NIL': {                                     lex.Next(); return Value(0, V_NIL);    }

            case '-':
            {
                lex.Next(); 
                Value v = ParseFactor();
                switch (v.type)
                {
                    case V_INT:   v.ival *= -1; break;
                    case V_FLOAT: v.fval *= -1; break;
                    default: lex.Error("numeric value expected");
                }
                return v;
            }

            case '[':
            {
                lex.Next();
                Gobble('LF');
                vector<Value> elems;
                if (lex.token == ']') lex.Next();
                else
                {
                    for (;;)
                    {
                        elems.push_back(ParseFactor());
                        bool haslf = lex.token == 'LF';
                        if (haslf) lex.Next();
                        if (lex.token == ']') break;
                        if (!haslf) Expect(',');
                    }
                    lex.Next();
                }

                int type = -1;
                if (lex.token == ':')
                {
                    lex.Next();
                    string sname = lex.sattr;
                    Expect('ID');
                    size_t reqargs = 0;
                    int idx = g_vm->StructIdx(sname, reqargs);
                    if (idx >= 0)   // if unknown type, becomes regular vector
                    {
                        while (elems.size() < reqargs) { elems.push_back(Value(0, V_NIL)); }         // pad with NIL if current type has more fields
                        while (elems.size() > reqargs) { elems.back().DEC(); elems.pop_back(); }     // drop elements if current type has less fields
                        type = idx;
                    }
                }

                auto vec = g_vm->NewVector(elems.size(), type);
                allocated.push_back(vec);
                for (auto &e : elems) vec->push(e.INC());
                return Value(vec);
            }

            default:
                lex.Error("illegal start of expression: " + lex.TokStr());
                return Value();
        }
    }