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; } }
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; }