static Int32 Factor(void) { Int32 type; switch(Token) { case tINTCONST: vm_genI(op_pushint,GetInt()); NextToken(); type=INT_TYPE; break; case tREALCONST: vm_genR(op_pushreal,GetReal()); NextToken(); type=REAL_TYPE; break; case tSTRINGCONST: vm_genS(op_pushstring,GetString()); NextToken(); type=STRING_TYPE; break; case tNOT: NextToken(); type=Factor(); vm_gen0(op_not); break; case tLPAREN: SkipToken(tLPAREN); type=Expr(); SkipToken(tRPAREN); break; case tLBRACK: ArrayInitializer(); type=ARRAY_TYPE; break; default: type=Rhs(); break; } return type; }
void Pass1::accept_asgn( std::string asgn_nm, ParseNode *asgn_rhs, ParseNode *simple, std::string insn_name, Insn &insn, char asz, char osz ) { /// fixme, do this! // 1. Get size of asgn_nm (destination of assignment). // Actually, we can just look up asgn_nm in the symbol table. // 2. asgn_rhs is an 'rhs' node. // If the rhs node is a NUM token then we have to give it a size that matches the destination // size. // 3. Evaluation of 'rhs'. // a. [?] std::map<std::string, Symbol *>::iterator symiter = symtab2.find(asgn_nm); if(symiter == symtab2.end()) { throw ParseError("Destination of assignment not found in symbol table: " + asgn_nm, simple->lineNum, simple->fileNum, __LINE__ ); } Symbol &destsym = *symiter->second; Size &destsize = destsym.size; insn.stmts.push_back(Statement(SO_ASGN)); Statement &stmt = insn.stmts.back(); stmt.osz = osz; stmt.asz = asz; stmt.dest = &destsym; assert(stmt.dest->type == ST_LOCAL || stmt.dest->type == ST_EXTERN || stmt.dest->type == ST_ARGNAME); stmt.src.push_back(Rhs()); Rhs &rhsT = stmt.src.back(); accept_rhs(rhsT, asgn_rhs, insn_name, insn, destsize); if(rhsT.size.base != destsize.base || rhsT.size.scalar != destsize.scalar) { ///std::cout << rhsT.size.base << " " << rhsT.size.scalar << " " << destsize.base << " " << destsize.scalar << std::endl; throw ParseError("Size mismatch for assignment to " + asgn_nm, simple->lineNum, simple->fileNum, __LINE__ ); } }
void Pass1::accept_statement(ParseNode *stmt, std::string insn_name, Insn &insn) { assert(stmt->token == RULE_STATEMENT); char osz = 0, asz = 0; std::list<ParseNode *>::iterator i = stmt->children.begin(); assert(i != stmt->children.end()); bool valid = true; while((*i)->token == RULE_PREFIX) { int prefix = (*i)->children.front()->token; switch(prefix) { case KEYWORD_O16: if(osz == 0) osz = 16; else valid = false; break; case KEYWORD_O32: if(osz == 0) osz = 32; else valid = false; break; case KEYWORD_O64: if(osz == 0) osz = 64; else valid = false; break; case KEYWORD_A16: if(asz == 0) asz = 16; else valid = false; break; case KEYWORD_A32: if(asz == 0) asz = 32; else valid = false; break; case KEYWORD_A64: if(asz == 0) asz = 64; else valid = false; break; default: assert(0); break; } ++i; } assert((*i)->token == RULE_SIMPLE_D_STATEMENT); if(!valid) { throw ParseError("Too many prefix (o16/o32/o64 or a16/a32/a64).", stmt->lineNum, stmt->fileNum, __LINE__ ); } ParseNode *simple = *i; assert(!simple->children.empty()); bool is_pure_asgn = false; if(simple->children.size() == 3) { i = simple->children.begin(); // possibly IDENT ++i; // skip possible IDENT if((*i)->token == '=') is_pure_asgn = true; } i = simple->children.begin(); if(!is_pure_asgn && (*i)->token == CTokenEnums::TOKEN_IDENT) { if(osz != 0 || asz != 0) { throw ParseError("Prefix (o16/o32/o64 or a16/a32/a64) used with local variable definition.", stmt->lineNum, stmt->fileNum, __LINE__ ); } } std::string asgn_nm; ParseNode *asgn_rhs = NULL; // First allocate a local variable if that is in order. if(!is_pure_asgn && (*i)->token == CTokenEnums::TOKEN_IDENT) { std::string sizeid = (*i)->text; // get identifier (size) ++i; // skip size identifier Size sz = get_exact_size(sizeid); if(sz.scalar == 0) { // Look up this size, it's a parameter. std::map<std::string, Symbol *>::iterator j = symtab2.find(sizeid); if(j == symtab2.end() || j->second->type != ST_ARGSIZE) { throw ParseError("Local variable size error: can't find size: " + sizeid, stmt->lineNum, stmt->fileNum, __LINE__ ); } sz.base = j->second->num; assert(sz.base < 0); sz.scalar = 1; if((*i)->token == '*') { ++i; // skip * sz.scalar = get_short((*i)->text); if(sz.scalar <= 1) { throw ParseError("Local variable size error: scalar must be 2..32767, found: " + (*i)->text, stmt->lineNum, stmt->fileNum, __LINE__ ); } ++i; // skip scalar } } else { if((*i)->token == '*') { throw ParseError("Local variable size error: can't use * with built-in type: " + sizeid, stmt->lineNum, stmt->fileNum, __LINE__ ); } } assert((*i)->token == CTokenEnums::TOKEN_IDENT); std::string nm = (*i)->text; // (sz, nm) now set. ++i; if(i != simple->children.end()) { assert((*i)->token == '='); ++i; // skip '=' asgn_rhs = *i; asgn_nm = nm; } // Create local variable here. if(!is_valid_new_ident(nm)) { throw ParseError("Local variable name already in symbol table: " + nm, stmt->lineNum, stmt->fileNum, __LINE__ ); } Symbol sym(); addsym(nm, new Symbol(ST_LOCAL, insn.locals.size(), sz)); insn.locals.push_back(sz); locals.insert(nm); } i = simple->children.begin(); if(is_pure_asgn) { asgn_nm = (*i)->text; // ident ++i; // skip ident assert((*i)->token == '='); ++i; // skip '=' asgn_rhs = *i; } // This is used for e.g. both of these cases: // zeta = undefined; // bit tmp = undefined; if(asgn_rhs != NULL) { accept_asgn(asgn_nm, asgn_rhs, simple, insn_name, insn, asz, osz); } // Handle assert, push, pop, discard, outport, inport, reserve, restore here. i = simple->children.begin(); if((*i)->token != CTokenEnums::TOKEN_IDENT) { int x = 0; switch((*i)->token) { case KEYWORD_ASSERT: x = SO_ASSERT; break; case KEYWORD_PUSH: x = SO_PUSH; break; case KEYWORD_POP: x = SO_POP; break; case KEYWORD_DISCARD: x = SO_DISCARD; break; case KEYWORD_OUTPORT: x = SO_OUTPORT; break; case KEYWORD_INPORT: x = SO_INPORT; break; case KEYWORD_RESERVE: x = SO_RESERVE; break; case KEYWORD_RESTORE: x = SO_RESTORE; break; case KEYWORD_COMMIT: x = SO_COMMIT; break; default: assert(0); break; } insn.stmts.push_back(Statement(x)); Statement &stmt = insn.stmts.back(); stmt.osz = osz; stmt.asz = asz; stmt.dest = NULL; // Now do any arguments. if(x == SO_RESERVE || x == SO_RESTORE) { stmt.src.push_back(Rhs()); Rhs &outrhs = stmt.src.back(); ++i; // skip keyword ++i; // skip '(' accept_rhs(outrhs, *i, insn_name, insn, Size(8, 1)); } else { ++i; // skip keyword ++i; // skip '(' while((*i)->token == RULE_RHS) { stmt.src.push_back(Rhs()); Rhs &outrhs = stmt.src.back(); accept_rhs(outrhs, *i, insn_name, insn, Size(0, 0)); if(outrhs.size.scalar == 0) { throw ParseError("Unable to resolve size of argument. If NUM, try e.g. tr<B8>(NUM)." + asgn_nm, simple->lineNum, simple->fileNum, __LINE__ ); } ++i; // skip rhs if((*i)->token != ',') break; ++i; // skip comma } assert((*i)->token == ')'); } } }
int main() { //malha geometrica TPZGeoMesh *firstmesh = new TPZGeoMesh; firstmesh->NodeVec().Resize(3); TPZVec<REAL> coord(2); coord[0] = 0.; coord[1] = 0.; //nos geometricos firstmesh->NodeVec()[0].Initialize(coord,*firstmesh); coord[0] = 1.0; firstmesh->NodeVec()[1].Initialize(coord,*firstmesh); coord[1] = 1.0; firstmesh->NodeVec()[2].Initialize(coord,*firstmesh); // coord[0] = 0.0; // firstmesh->NodeVec()[3].Initialize(coord,*firstmesh); TPZVec<int> nodeindexes(3);//triangulo nodeindexes[0] = 0;//local[i] = global[i] , i=0,1,2,3 nodeindexes[1] = 1; nodeindexes[2] = 2; //elementos geometricos TPZGeoElT2d *elq1 = new TPZGeoElT2d(nodeindexes,1,*firstmesh); //orientacao local de um segundo elemento superposto int i,sen;; cout<<"Sentido local antihorario/horario : 0/1 ? "; cin>>sen; cout<<"Entre primeiro no = 0,1,2 : "; cin>>i; if(sen==0) {//direito nodeindexes[0] = (0+i)%3;//local[i] = global[j] , i,j em {0,1,2} nodeindexes[1] = (1+i)%3; nodeindexes[2] = (2+i)%3; } else {//inverso nodeindexes[0] = (0+i)%3;//local[i] = global[j] , i,j em {0,1,2} nodeindexes[1] = (2+i)%3; nodeindexes[2] = (1+i)%3; } /* nodeindexes[0] = 1;//local[i] = global[i] , i=0,1,2,3 nodeindexes[1] = 2; nodeindexes[2] = 3;*/ TPZGeoElT2d *elq2 = new TPZGeoElT2d(nodeindexes,1,*firstmesh);//segundo elemento superposto ao primeiro /* coord[1] = 0.0; coord[0] = 2.0; firstmesh->NodeVec()[4].Initialize(coord,*firstmesh); coord[1] = 1.0; firstmesh->NodeVec()[5].Initialize(coord,*firstmesh); nodeindexes[0] = 1;//local[i] = global[i] , i=0,1,2,3 nodeindexes[1] = 4; nodeindexes[2] = 5; nodeindexes[3] = 2; TPZGeoElT2d *elq2 = new TPZGeoElT2d(nodeindexes,1,*firstmesh); */ //Arquivos de saida ofstream outgm1("outgm1.dat"); ofstream outcm1("outcm1.dat"); ofstream outcm2("outcm2.dat"); //montagem de conectividades entre elementos firstmesh->BuildConnectivity(); firstmesh->Print(outgm1); outgm1.flush(); //teste de divisao geometrica : 1 elemento TPZVec<TPZGeoEl *> vecsub,vecsub1; elq1->Divide(vecsub);//divide 0 elq2->Divide(vecsub);//divide 1 /* vecsub[2]->Divide(vecsub1);// vecsub1[3]->Divide(vecsub1); vecsub[0]->Divide(vecsub1);//divide 1 vecsub1[2]->Divide(vecsub1); */ firstmesh->Print(outgm1); outgm1.flush(); //malha computacional TPZCompMesh *secondmesh = new TPZCompMesh(firstmesh); //material int matindex = secondmesh->MaterialVec().AllocateNewElement(); TPZFMatrix k(1,1,1.),f(1,1,0.),c(1,2,1.); TPZMat2dLin * mat = new TPZMat2dLin(1); mat->SetMaterial(k,c,f); //mat->SetForcingFunction(force); mat->SetForcingFunction(derivforce); secondmesh->MaterialVec()[matindex] = mat; //CC : condicao de contorno //ordem de interpolacao // TPZCompEl::gOrder = 3; cmesh.SetDefaultOrder(3); //constroe a malha computacional secondmesh->AutoBuild(); secondmesh->InitializeBlock(); secondmesh->ComputeConnectSequence(); secondmesh->Print(outcm1); outcm1.flush(); //Resolucao do sistema TPZFMatrix Rhs(secondmesh->NEquations(),1),Stiff(secondmesh->NEquations(),secondmesh->NEquations()),U; Stiff.Zero(); Rhs.Zero(); secondmesh->Assemble(Stiff,Rhs); Rhs.Print("Rhs teste",outcm2); Stiff.Print("Bloco teste",outcm2); Rhs.Print("Computational Mesh -> fBlock",outcm2); TPZMatrixSolver solver(&Stiff); solver.SetDirect(ELU); solver.Solve(Rhs,U); U.Print("Resultado",outcm2); secondmesh->LoadSolution(U); secondmesh->Solution().Print("Mesh solution ",outcm2); // TPZElementMatrix ek,ef; // secondmesh->ElementVec()[0]->CalcStiff(ek,ef); // ek.fMat->Print(); // ef.fMat->Print(); delete secondmesh; delete firstmesh; return 0; }