ExprType ExprPrototypeNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) { // TODO: implement prototype bool error=false; checkCondition(false, "Prototypes are currently not supported",error); return ExprType().Error(); #if 0 bool error = false; if (_retTypeSet) checkCondition(returnType().isValid(), "Function has bad return type", error); _argTypes.clear(); for (int c = 0; c < numChildren(); c++) { ExprType type = child(c)->type(); checkCondition(type.isValid(), "Function has a parameter with a bad type", error); _argTypes.push_back(type); ExprLocalVar* localVar = new ExprLocalVar(type); envBuilder.current()->add(((ExprVarNode*)child(c))->name(), localVar); std::cerr << "after create localvar phi " << localVar->getPhi() << std::endl; child(c)->prep(wantScalar, envBuilder); } if (error) setType(ExprType().Error()); else setType(ExprType().None().Varying()); return _type; #endif }
ExprType ExprBlockNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) { ExprType assignType = child(0)->prep(false, envBuilder); ExprType resultType = child(1)->prep(wantScalar, envBuilder); if (!assignType.isValid()) setType(ExprType().Error()); else setType(resultType); return _type; }
bool ExprFuncNode::checkArg(int arg, ExprType type, ExprVarEnvBuilder& envBuilder) { ExprType childType = child(arg)->prep(type.isFP(1), envBuilder); _promote[arg] = 0; if (ExprType::valuesCompatible(type, childType) && type.isLifeCompatible(childType)) { if (type.isFP() && type.dim() > childType.dim()) { _promote[arg] = type.dim(); } return true; } child(arg)->addError("Expected " + type.toString() + " for argument, got " + childType.toString()); return false; }
ExprType ExprVecNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) { bool error = false; int max_child_d = 0; for (int c = 0; c < numChildren(); c++) { ExprType childType = child(c)->prep(true, envBuilder); // TODO: add way to tell what element of vector has the type mismatch checkIsFP(childType, error); max_child_d = std::max(max_child_d, childType.dim()); } if (error) setType(ExprType().Error()); else setTypeWithChildLife(ExprType().FP(numChildren())); return _type; }
ExprType ExprLocalFunctionNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) { #if 0 // TODO: no local functions for now bool error = false; // prep prototype and check for errors ExprPrototypeNode* prototype = (ExprPrototypeNode*)child(0); ExprVarEnv functionEnv; functionEnv.resetAndSetParent(&env); if (!prototype->prep(false, functionEnv).isValid()) error = true; // decide what return type we want bool returnWantsScalar = false; if (!error && prototype->isReturnTypeSet()) returnWantsScalar = prototype->returnType().isFP(1); // prep block and check for errors ExprNode* block = child(1); ExprType blockType = block->prep(returnWantsScalar, functionEnv); if (!error && blockType.isValid()) { if (prototype->isReturnTypeSet()) { if (blockType != prototype->returnType()) { checkCondition(false, "In function result of block '" + blockType.toString() + "' does not match given return type " + prototype->returnType().toString(), error); } } else prototype->setReturnType(blockType); // register the function in the symbol table env.addFunction(prototype->name(), this); } else { checkCondition(false, "Invalid type for blockType is " + blockType.toString(), error); error = true; } return _type = error ? ExprType().Error() : ExprType().None().Varying(); #else bool error=false; checkCondition(false,"Local functions are currently not supported.",error); return ExprType().Error(); #endif }
void modifVec(std::list<ElementRange> const& __r, eltType const& u,vectorType & UnVec,ExprType const& expr, size_type rowstart, int ComponentShiftFactor, mpl::int_<MESH_POINTS> /**/ ) { const size_type context = ExprType::context|vm::POINT; auto mesh = u.functionSpace()->mesh().get(); auto const* dof = u.functionSpace()->dof().get(); auto const* fe = u.functionSpace()->fe().get(); if ( __r.size() == 0 ) return; auto point_it = __r.begin()->template get<1>(); auto point_en = __r.begin()->template get<2>(); bool findAPoint = false; for( auto lit = __r.begin(), len = __r.end(); lit != len; ++lit ) { point_it = lit->template get<1>(); point_en = lit->template get<2>(); if ( point_it != point_en ) { findAPoint=true; break; } } if ( !findAPoint ) return; auto const& pointForInit = boost::unwrap_ref( *point_it ); size_type eid = pointForInit.elements().begin()->first; size_type ptid_in_element = pointForInit.elements().begin()->second; auto const& elt = mesh->element( eid ); auto gm = mesh->gm(); auto geopc = gm->preCompute( fe->vertexPoints(ptid_in_element) ); auto ctx = gm->template context<context>( elt, geopc ); auto expr_evaluator = expr.evaluator( mapgmc(ctx) ); auto IhLoc = fe->vertexLocalInterpolant(); std::vector<bool> dofdone( dof->nLocalDofWithGhost(), false ); for( auto const& lit : __r ) { point_it = lit.template get<1>(); point_en = lit.template get<2>(); DVLOG(2) << "point " << point_it->id() << " with marker " << point_it->marker() << " nb: " << std::distance(point_it,point_en); if ( point_it == point_en ) continue; for ( ; point_it != point_en;++point_it ) { auto const& thept = boost::unwrap_ref( *point_it ); size_type eid = thept.elements().begin()->first; size_type ptid_in_element = thept.elements().begin()->second; auto const& elt = mesh->element( eid ); geopc = gm->preCompute( fe->vertexPoints(ptid_in_element) ); ctx->update( elt, ptid_in_element, geopc, mpl::int_<0>() ); expr_evaluator.update( mapgmc( ctx ) ); fe->vertexInterpolate( expr_evaluator, IhLoc ); for (int c1=0;c1<eltType::nComponents1;c1++) //for( int c = 0; c < (is_product?nComponents:1); ++c ) { size_type index = dof->localToGlobal( eid, ptid_in_element, c1 ).index(); //size_type thedof = u.start()+ (is_comp_space?Elem1::nComponents:1)*index; // global dof size_type thedof = u.start() + ComponentShiftFactor*index; if ( dofdone[index] ) continue; double value = IhLoc( c1 ); UnVec->set(rowstart+thedof,value); dofdone[index] = true; } } } }
void modifVec(std::list<ElementRange> const& __r, eltType const& u,vectorType & UnVec,ExprType const& expr, size_type rowstart, int ComponentShiftFactor, mpl::int_<MESH_EDGES> /**/ ) { const size_type context = ExprType::context|vm::POINT; auto mesh = u.functionSpace()->mesh().get(); auto const* dof = u.functionSpace()->dof().get(); auto const* fe = u.functionSpace()->fe().get(); if ( __r.size() == 0 ) return; auto edge_it = __r.begin()->template get<1>(); auto edge_en = __r.begin()->template get<2>(); bool findAEdge = false; for( auto lit = __r.begin(), len = __r.end(); lit != len; ++lit ) { edge_it = lit->template get<1>(); edge_en = lit->template get<2>(); if ( edge_it != edge_en ) { findAEdge=true; break; } } if ( !findAEdge ) return; auto const& edgeForInit = boost::unwrap_ref( *edge_it ); auto gm = mesh->gm(); //auto const& firstEntity = *entity_it; size_type eid = edgeForInit.elements().begin()->first; size_type ptid_in_element = edgeForInit.elements().begin()->second; auto const& elt = mesh->element( eid ); auto geopc = gm->preCompute( fe->edgePoints(ptid_in_element) ); auto ctx = gm->template context<context>( elt, geopc ); auto expr_evaluator = expr.evaluator( mapgmc(ctx) ); auto IhLoc = fe->edgeLocalInterpolant(); std::vector<bool> dofdone( dof->nLocalDofWithGhost(), false ); for( auto const& lit : __r ) { edge_it = lit.template get<1>(); edge_en = lit.template get<2>(); for ( ; edge_it != edge_en;++edge_it ) { auto const& theedge = boost::unwrap_ref( *edge_it ); if ( theedge.isGhostCell() ) { LOG(WARNING) << "edge id : " << theedge.id() << " is a ghost edge"; continue; } size_type eid = theedge.elements().begin()->first; size_type edgeid_in_element = theedge.elements().begin()->second; auto const& elt = mesh->element( eid ); geopc = gm->preCompute( fe->edgePoints(edgeid_in_element) ); ctx->update( elt, geopc ); expr_evaluator.update( mapgmc( ctx ) ); fe->edgeInterpolate( expr_evaluator, IhLoc ); for( auto const& ldof : u.functionSpace()->dof()->edgeLocalDof( eid, edgeid_in_element ) ) { size_type index = ldof.index(); if ( dofdone[index] ) continue; //size_type thedof = u.start()+ (is_comp_space?Elem1::nComponents:1)*ldof.index(); size_type thedof = u.start() + ComponentShiftFactor*index; double value = ldof.sign()*IhLoc( ldof.localDofInFace() ); UnVec->set(rowstart+thedof,value); dofdone[index] = true; } } // edge_it } // lit }
ExprType ExprFuncStandard::prep(ExprFuncNode* node, bool scalarWanted, ExprVarEnvBuilder& envBuilder) const { if (_funcType < VEC) { // scalar argumented functions returning scalars // use promote protocol... bool error = false; int nonOneDim = 1; // defaults to 1, if another is seen record! bool multiInvoke = !scalarWanted; ExprType retType; for (int c = 0; c < node->numChildren(); c++) { ExprType childType = node->child(c)->prep(scalarWanted, envBuilder); int childDim = childType.dim(); node->child(c)->checkIsFP(childType, error); retType.setLifetime(childType); if (childDim != 1) { if (nonOneDim != 1 && childDim != nonOneDim) multiInvoke = false; nonOneDim = childDim; } } if (error) return retType.Error(); else if (multiInvoke && nonOneDim != 1) return retType.FP(nonOneDim); return retType.FP(1); } else { // vector argumented functions bool error = false; ExprType retType; for (int c = 0; c < node->numChildren(); c++) { ExprType childType = node->child(c)->prep(scalarWanted, envBuilder); int childDim = childType.dim(); node->child(c)->checkIsFP(childType, error); node->child(c)->checkCondition(childDim == 1 || childDim == 3, "Expected float or FP[3]", error); retType.setLifetime(childType); } if (error) return retType.Error(); else if (scalarWanted || _funcType < VECVEC) return retType.FP(1); else return retType.FP(3); } }
int Parser::expression(int pos, int status) { int isputs = 0; if(tok.skip("$")) { // global varibale if(is_asgmt()) asgmt(); } else if(tok.skip("require")) { make_require(); } else if(tok.skip("def")) { blocksCount++; make_func(); } else if(tok.skip("module")) { blocksCount++; module = tok.tok[tok.pos++].val; eval(0, NON); module = ""; } else if(funcs.inside == false && !tok.is("def", 1) && !tok.is("module", 1) && !tok.is("$", 1) && !tok.is(";", 1) && module == "") { // main func entry funcs.inside = true; funcs.now++; funcs.append("main", ntv.count, 0); // append funcs ntv.genas("push ebp"); ntv.genas("mov ebp esp"); uint32_t espBgn = ntv.count + 2; ntv.genas("sub esp 0"); ntv.gencode(0x8b); ntv.gencode(0x75); ntv.gencode(0x0c); // mov esi, 0xc(%ebp) eval(0, BLOCK_NORMAL); ntv.gencode(0x81); ntv.gencode(0xc4); ntv.gencode_int32(ADDR_SIZE * (var.focus().size() + 6)); // add %esp nn ntv.gencode(0xc9);// leave ntv.gencode(0xc3);// ret ntv.gencode_int32_insert(ADDR_SIZE * (var.focus().size() + 6), espBgn); funcs.inside = false; } else if(is_asgmt()) { asgmt(); } else if((isputs=tok.skip("puts")) || tok.skip("print")) { do { ExprType et = expr_entry(); ntv.genas("push eax"); if(et.is_type(T_STRING)) { ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(4);// call *0x04(esi) putString } else { ntv.gencode(0xff); ntv.gencode(0x16); // call (esi) putNumber } ntv.genas("add esp 4"); } while(tok.skip(",")); // for new line if(isputs) { ntv.gencode(0xff); ntv.gencode(0x56); ntv.gencode(8);// call *0x08(esi) putLN } } else if(tok.skip("for")) { blocksCount++; asgmt(); if(!tok.skip(",")) error("error: %d: expected ','", tok.tok[tok.pos].nline); make_while(); } else if(tok.skip("while")) { blocksCount++; make_while(); } else if(tok.skip("return")) { make_return(); } else if(tok.skip("if")) { blocksCount++; make_if(); } else if(tok.skip("else")) { uint32_t end; ntv.gencode(0xe9); end = ntv.count; ntv.gencode_int32(0);// jmp while end ntv.gencode_int32_insert(ntv.count - pos - 4, pos); eval(end, BLOCK_NORMAL); return 1; } else if(tok.skip("elsif")) { uint32_t endif, end; ntv.gencode(0xe9); endif = ntv.count; ntv.gencode_int32(0);// jmp while end ntv.gencode_int32_insert(ntv.count - pos - 4, pos); expr_entry(); // if condition ntv.gencode(0x83); ntv.gencode(0xf8); ntv.gencode(0x00);// cmp eax, 0 ntv.gencode(0x75); ntv.gencode(0x05); // jne 5 tok.skip(";"); ntv.gencode(0xe9); end = ntv.count; ntv.gencode_int32(0);// jmp while end eval(end, BLOCK_NORMAL); ntv.gencode_int32_insert(ntv.count - endif - 4, endif); return 1; } else if(tok.skip("break")) { make_break(); } else if(tok.skip("end")) { blocksCount--; if(status == NON) return 1; if(status == BLOCK_NORMAL) { ntv.gencode_int32_insert(ntv.count - pos - 4, pos); } else if(status == BLOCK_FUNC) funcs.inside = false; return 1; } else if(!tok.skip(";")) { expr_entry(); } return 0; }