예제 #1
0
void SymTable::Add(Symbol* symbol, int flag)
{
    SymTable::Add(symbol);
    switch (flag)
    {
    case 0://locals
    {
        SymVar* vp = dynamic_cast<SymVar*>(symbol);
        if (vp)
        {
            SymType* type = vp->GetType();
            if (dynamic_cast<SymTypeArray*>(type))
            {
                symbol->offset = -(shift + offset + type->GetByteSize() - dynamic_cast<SymTypeArray*>(type)->type->GetByteSize());
            }
            else if (dynamic_cast<SymTypeStruct*>(type))
            {
                symbol->offset = -(shift + offset + type->GetByteSize() - dynamic_cast<SymTypeStruct*>(type)->GetShiftForBase());
            }
            else
            {
                symbol->offset = -(shift + offset);
            }
            offset += symbol->GetByteSize();
            vp->local = true;
        }
    }
        break;

    case 1://params
        if (dynamic_cast<SymTypeStruct*>(symbol->GetType()))
        {
            symbol->offset = offset + dynamic_cast<SymTypeStruct*>(symbol->GetType())->GetShiftForBase();
        }
        else
        {
            symbol->offset = offset + symbol->GetByteSize();
        }
        offset += symbol->GetByteSize();
        break;

    case 2://fields
        symbol->offset = offset;
        offset += symbol->GetByteSize();
        break;
    }
}
예제 #2
0
NodeExpression* Parser::ParseFactor()
{
	NodeExpression* r = NULL;
	if (t.GetValue() == "-" || t.GetValue() == "+" || t.GetValue() == "not")
	{
		string op = t.GetValue();
		t = sc.GetNextToken();
		NodeExpression* _r = ParseFactor();
		r = new NodeUnaryOp(new Symbol(op), _r);
		r->SetType(_r->GetType());
	}
	else
	{
		if (t.GetValue() != "(" && t.GetType() != identifier && t.GetType() != int_const_dec && t.GetType() != float_const)
			throw Error("Syntax error : unexpected \""+t.GetValue()+"\";", t);
		if(t.GetValue() == "(")
		{
			t = sc.GetNextToken();
			r = ParseComparision();
			t = RequireToken(")" , "\")\" expected");
		}
		switch(t.GetType()){
			case int_const_dec : case float_const:
			{
				SymVarConst* _const = new SymVarConst(t.GetValue(), t.GetValue(), NULL);
				if (t.GetType() == int_const_dec)
					_const->SetType((SymType*)mainTable->find("integer")->second);
				else
					_const->SetType((SymType*)mainTable->find("real")->second);
				t = sc.GetNextToken();
				r = new NodeConst(_const);
				r->SetType(_const->GetType());
				return r;
				break;
			}
			case identifier:
			{
				Token t1 = t;
				bool found = false;
				_Table::iterator it = TableStack.Find(t1.GetValue(), found);
				if (!found)
					throw Error("unknown identifier", t);
				t = sc.GetNextToken();
				SymVar* name = (SymVar*)it->second;
				SymType* Type = name->GetType();
				if (t.GetValue() == "(")
				{
					if (!it->second->IsFunc())
						throw Error("unexpected identifier", t);
					if (((SymFunc*)it->second)->IsForward())
						throw Error("undefined forward ("+it->second->GetName()+")", t);
					r = ParseSub((SymFunc*)it->second);
				}
				else
					if(name->GetType()->IsRec() || name->GetType()->IsArr())
					{
						r = new NodeVar(name);
						r->SetType(Type);
						while(name->GetType()->IsRec() || name->GetType()->IsArr())
						{
							SymVar* name2 = name;
							if (name->GetType()->IsRec())
								r = ParseRec(r, name);
							if (name->GetType()->IsArr())
								r = ParseArr(r,name);
							if (name2 == name)
								break;
						}
					}
					else
					{
						if (name->IsConst())
							r = new NodeConst(it->second);
						else
							r = new NodeVar(it->second);
						r->SetType(Type);
					}
				break;
			}
		}
	}
	return r;
}