Пример #1
0
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

}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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
}
Пример #6
0
    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;
                }
            }
        }

    }
Пример #7
0
    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
    }
Пример #8
0
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);
    }
}
Пример #9
0
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;
}