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; } }
SymVar* Parser::ParseDeclarator(SymType* type, bool parseParams) { SymVar* result = NULL; //pointer while (*lexer.Peek() == MULTIPLICATION) { type = new SymTypePointer(type); lexer.Get(); } //direct-declarator if (*lexer.Peek() == ROUND_LEFT_BRACKET) { lexer.Get(); result = ParseDeclarator(type); Expected(lexer.Get()->GetSubType(), ROUND_RIGHT_BRACKET); return result; } Expected(parseParams || *lexer.Peek() == IDENTIFIER, "exepcted an identifier"); if (parseParams && *lexer.Peek() != IDENTIFIER) { string n = to_string((long double)counter++); BaseToken* dummy = new BaseToken("abstract-"+n, 0, 0, IDENTIFIER, IDENTIFIER); result = new SymVar(dummy, type); } else { string msg = "redefinition: " + lexer.Peek()->GetText(); Expected(!symStack.Top()->Find(lexer.Peek()->GetText()), &msg[0]); result = new SymVar(lexer.Get(), type); } BaseToken* token = lexer.Peek(); if (*token == SQUARE_LEFT_BRACKET) { lexer.Get(); Expected(*lexer.Peek() != SQUARE_RIGHT_BRACKET, "unknown size"); SyntaxNode* index = ParseExpression(); Expected(*index->token != IDENTIFIER, "expression must have a constant value"); SymType* indexType = index->GetType(); Expected(indexType == intType && indexType->CanConvertTo(intType), "expression must be an integral constant expression"); Expected(lexer.Get()->GetSubType(), SQUARE_RIGHT_BRACKET); int size = dynamic_cast<TokenVal <int> *>(index->token)->GetValue(); result->SetType(new SymTypeArray(size, type)); } else if (*token == ROUND_LEFT_BRACKET) { lexer.Get(); SymTypeFunc* t = new SymTypeFunc(type); t->params->offset = 4; symStack.Push(t->params); ParseParameterList(); symStack.Pop(); if (*lexer.Peek() == FIGURE_LEFT_BRACKET) { parseFunc.push_back(t); t->body = ParseBlock(); parseFunc.pop_back(); } result->SetType(t); } return result; }
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; }