예제 #1
0
    void Expect(int t)
    {
        if (lex.token != t)
            lex.Error(lex.TokStr(t) + " expected, found: " + lex.TokStr());

        lex.Next();
    }
예제 #2
0
    Value ParseElems(TType end, type_elem_t typeoff, int numelems = -1)  // Vector or struct.
    {
        Gobble(T_LINEFEED);
        vector<Value> elems;
        auto &ti = g_vm->GetTypeInfo(typeoff);

        if (lex.token == end) lex.Next();
        else
        {
            for (;;)
            {
                if ((int)elems.size() == numelems)
                {
                    ParseFactor(TYPE_ELEM_ANY).DECRT();  // Ignore the value.
                }
                else
                {
                    elems.push_back(ParseFactor(ti.t == V_VECTOR ? ti.subt : ti.elems[elems.size()]));
                }
                bool haslf = lex.token == T_LINEFEED;
                if (haslf) lex.Next();
                if (lex.token == end) break;
                if (!haslf) Expect(T_COMMA);
            }
            lex.Next();
        }

        if (numelems >= 0)
        {
            while ((int)elems.size() < numelems)
            {
                switch (ti.elems[elems.size()])
                {
                case V_INT:
                    elems.push_back(Value(0));
                    break;
                case V_FLOAT:
                    elems.push_back(Value(0.0f));
                    break;
                case V_NIL:
                    elems.push_back(Value());
                    break;
                default:
                    lex.Error("no default value possible for missing struct elements");
                }
            }
        }

        auto vec = g_vm->NewVector((int)elems.size(), (int)elems.size(), ti);
        vec->Inc();
        allocated.push_back(vec);
        int i = 0;
        for (auto &e : elems) vec->At(i++) = e;
        return Value(vec);
    }
예제 #3
0
 void ExpectType(ValueType given, ValueType needed)
 {
     if (given != needed)
     {
         lex.Error(string("type ") +
                   BaseTypeName(needed) +
                   " required, " +
                   BaseTypeName(given) +
                   " given");
     }
 }
예제 #4
0
    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();
        }
    }
예제 #5
0
    Value ParseFactor(type_elem_t typeoff)
    {
        auto &ti = g_vm->GetTypeInfo(typeoff);
        auto vt = ti.t;

        // TODO: also support boxed parsing as V_ANY.
        // means boxing int/float, deducing runtime type for V_VECTOR, and finding the existing struct.

        switch (lex.token)
        {
        case T_INT:
        {
            ExpectType(V_INT, vt);
            int i = atoi(lex.sattr.c_str());
            lex.Next();
            return Value(i);
        }

        case T_FLOAT:
        {
            ExpectType(V_FLOAT, vt);
            double f = atof(lex.sattr.c_str());
            lex.Next();
            return Value((float)f);
        }

        case T_STR:
        {
            ExpectType(V_STRING, vt);
            string s = lex.sattr;
            lex.Next();
            auto str = g_vm->NewString(s);
            str->Inc();
            allocated.push_back(str);
            return Value(str);
        }

        case T_NIL:
        {
            ExpectType(V_NIL, vt);
            lex.Next();
            return Value();
        }

        case T_MINUS:
        {
            lex.Next();
            Value v = ParseFactor(typeoff);
            switch (typeoff)
            {
            case TYPE_ELEM_INT:
                v.setival(v.ival() * -1);
                break;
            case TYPE_ELEM_FLOAT:
                v.setfval(v.fval() * -1);
                break;
            default:
                lex.Error("unary minus: numeric value expected");
            }
            return v;
        }

        case T_LEFTBRACKET:
        {
            ExpectType(V_VECTOR, vt);
            lex.Next();
            return ParseElems(T_RIGHTBRACKET, typeoff);
        }

        case T_IDENT:
        {
            ExpectType(V_STRUCT, vt);
            string sname = lex.sattr;
            lex.Next();
            Expect(T_LEFTCURLY);
            auto name = g_vm->StructName(ti);
            if (name != sname) lex.Error("struct type " + name + " required, " + sname + " given");
            return ParseElems(T_RIGHTCURLY, typeoff, ti.len);
        }

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