Exemplo n.º 1
0
TEST(TestEnumeration, CaseAccess_SwitchCase)
{
    SEMANTIC_ANALYZE(L"enum CompassPoint { \n"
            L"case North\n"
            L"case South\n"
            L"case East\n"
            L"case West\n"
            L"}\n"
            L"var directionToHead : CompassPoint = .North;\n"
            L"directionToHead = .North\n"
            L"switch directionToHead {\n"
            L"case .North:\n"
            L"        break\n"
            L"case .South:\n"
            L"        break\n"
            L"case .East:\n"
            L"        break\n"
            L"case .West:\n"
            L"        break\n"
            L"}");
    dumpCompilerResults(compilerResults);
    ASSERT_EQ(0, compilerResults.numResults());
    SymbolPtr directionToHead;
    TypePtr CompassPoint;
    ASSERT_NOT_NULL(directionToHead = scope->lookup(L"directionToHead"));
    ASSERT_NOT_NULL(CompassPoint = dynamic_pointer_cast<Type>(scope->lookup(L"CompassPoint")));
    ASSERT_EQ(CompassPoint, directionToHead->getType());

}
Exemplo n.º 2
0
// Would be nice to make this a virtual member function, but it's
// awkward with the recursion for list printing.
std::ostream& print(std::ostream& os, const ElemPtr& e, bool first=true)
{
  SymbolPtr sym = to_symbol(e);
  NumberPtr num = to_number(e);
  if (sym)
    {
      os << sym->value();
    }
  else if (num)
    {
      os << num->value();
    }
  else
    {
      PairPtr p = to_cons(e);
      if (p)
	{
	  if (first)
	    os << "(";
	  if (is_nil(p))
	    os << ")";
	  else
	    {
	      if (!(to_symbol(p->car())))
		os << "(";
	      print(os, p->car(), false);
	      if (!(is_nil(to_cons(p->cdr()))))
		os << " ";
	      print(os, p->cdr(), false);
	    }
	}
    }
  return os;
}
VarType CodeBlock::make_cast(SymbolPtr p, VarType v1, VarType v2) {
	if (v1 != v2) {
		if (v1 == INTEGER && v2 == FLOATING) {
			// cast back to integer
			write_raw("CASTSI");
			return INTEGER;
		} else if (v1 == FLOATING && v2 == INTEGER) {
			// cast back to floating
			write_raw("CASTSF");
			return FLOATING;
		} else if ((v1 == STRING && v2 != STRING)
				   || (v1 != STRING && v2 == STRING)
				   || (v1 == VOID || v2 == VOID)) {
			if ((v1 == STRING_LITERAL && v2 == STRING) || (v1 == STRING && v2 == STRING_LITERAL)) {
				return STRING;
			}
			// need to catch boolean casting issues here...
			this->valid = false;
			report_error_lc("Semantic Error", "Unable to cast "
							+ var_type_to_string(v1)
							+ " to " + var_type_to_string(v2),
							p->get_row(), p->get_col());
			return VOID;
		} else if ((v1 == BOOLEAN && v2 != BOOLEAN)
				   || (v1 != BOOLEAN && v2 == BOOLEAN)) {
			return v2;
		} else {
			// fine
			return v2;
		}
	} else {
		return v2;
	}
	return VOID;
}
Exemplo n.º 4
0
void FunctionAnalyzer::visitProtocol(const ProtocolDefPtr& node)
{
    SymbolScope* scope = symbolRegistry->getCurrentScope();
    SymbolPtr sym = scope->getForwardDeclaration(node->getIdentifier()->getName());
    assert(sym && sym->getKind() == SymbolKindType);
    TypePtr type = static_pointer_cast<Type>(sym);
    ScopeGuard guard(symbolRegistry, type->getScope());
    SCOPED_SET(ctx->currentType, type);
    semanticAnalyzer->visitImplementation(node, this, true);
}
Exemplo n.º 5
0
TEST(TestFunctionOverloads, testFunc)
{
    SEMANTIC_ANALYZE(L"func test() -> String {}\n"
        L"let a = test()");
    dumpCompilerResults(compilerResults);
    SymbolPtr a;
    ASSERT_NOT_NULL(a = scope->lookup(L"a"));
    TypePtr type = a->getType();
    ASSERT_NOT_NULL(type);
    TypePtr t_String = symbolRegistry.lookupType(L"String");
    ASSERT_TRUE(type == t_String);
}
Exemplo n.º 6
0
TEST(TestEnumeration, ImplicitRawRepresentable)
{
    SEMANTIC_ANALYZE(L"enum Planet: Int {\n"
            L"    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune\n"
            L"}\n"
            L"let earthsOrder = Planet.Earth.rawValue");
    dumpCompilerResults(compilerResults);
    ASSERT_EQ(0, compilerResults.numResults());
    SymbolPtr earthsOrder;
    ASSERT_NOT_NULL(earthsOrder = scope->lookup(L"earthsOrder"));
    ASSERT_EQ(symbolRegistry.getGlobalScope()->Int(), earthsOrder->getType());
}
void DeclarationAnalyzer::verifyProtocolConform(const TypePtr& type, const TypePtr& protocol)
{
    for(auto entry : protocol->getDeclaredMembers())
    {
        SymbolPtr requirement = entry.second;
        if(FunctionOverloadedSymbolPtr funcs = std::dynamic_pointer_cast<FunctionOverloadedSymbol>(requirement))
        {
            //verify function
            for(auto func : *funcs)
            {
                verifyProtocolFunction(type, protocol, func);
            }
        }
        else if(FunctionSymbolPtr func = std::dynamic_pointer_cast<FunctionSymbol>(requirement))
        {
            //verify function
            verifyProtocolFunction(type, protocol, func);
        }
            /*
            else if(requirement == Type::getPlaceHolder())
            {
                //verify inner type
                SymbolPtr sym = type->getAssociatedType(entry.first);
                if(!(std::dynamic_pointer_cast<Type>(sym)))
                {
                    //Type %0 does not conform to protocol %1, unimplemented type %2
                    error(type->getReference(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_UNIMPLEMENTED_TYPE_3, type->getName(), protocol->getName(), entry.first);
                }
            }*/
        else if(TypePtr t = std::dynamic_pointer_cast<Type>(requirement))
        {
            //type can be ignored
        }
        else if(dynamic_pointer_cast<ComputedPropertySymbol>(requirement) || dynamic_pointer_cast<SymbolPlaceHolder>(requirement))
        {
            //verify computed properties
            SymbolPtr sym = type->getMember(entry.first);
            //ComputedPropertySymbolPtr sp = std::dynamic_pointer_cast<ComputedPropertySymbol>(sym);
            if(!sym)
            {
                error(type->getReference(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_UNIMPLEMENTED_PROPERTY_3, type->getName(), protocol->getName(), entry.first);
            }
            bool expectedSetter = requirement->hasFlags(SymbolFlagWritable);
            bool actualSetter = sym->hasFlags(SymbolFlagWritable);
            if(expectedSetter && !actualSetter)
            {
                error(type->getReference(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_UNWRITABLE_PROPERTY_3, type->getName(), protocol->getName(), entry.first);
            }
        }
    }
}
Exemplo n.º 8
0
TEST(TestFunctionOverloads, CallVariable)
{
    SEMANTIC_ANALYZE(L"var a = {(a : Int) -> Bool in return true}\n"
            L"var b = a(3)");
    dumpCompilerResults(compilerResults);
    ASSERT_EQ(0, compilerResults.numResults());


    SymbolPtr b;
    ASSERT_NOT_NULL(b = scope->lookup(L"b"));
    TypePtr type = b->getType();
    ASSERT_NOT_NULL(type);
    TypePtr t_Bool = symbolRegistry.lookupType(L"Bool");
    ASSERT_TRUE(type == t_Bool);
}
Exemplo n.º 9
0
TEST(TestFunctionOverloads, testClosureLiteral)
{
    SEMANTIC_ANALYZE(L"let a = {(c : Int, b : Int)->Int in return c + b}(1, 2)");
    dumpCompilerResults(compilerResults);
    ASSERT_EQ(0, compilerResults.numResults());


    SymbolPtr a;
    ASSERT_NOT_NULL(a = scope->lookup(L"a"));
    TypePtr type = a->getType();
    ASSERT_NOT_NULL(type);
    TypePtr t_Int = symbolRegistry.lookupType(L"Int");
    ASSERT_TRUE(type == t_Int);


}
bool CodeBlock::is_operand(SymbolPtr character) {
	if (character->get_symbol_type() == SYM_CONSTANT) {
		VarType op = static_pointer_cast<SymConstant>(character)->get_constant_type();
		if (!OPERATOR(op)()
			&& op != LPAREN
			&& op != RPAREN) {
			return true;
		} else {
			return false;
		}
	} else if (character->get_symbol_type() == SYM_DATA) {
		return true;
	} else {
		return false;
	}
}
bool CodeBlock::is_operator(SymbolPtr character) {
	if (character->get_symbol_type() == SYM_CONSTANT) {
		VarType op = static_pointer_cast<SymConstant>(character)->get_constant_type();
		if (OPERATOR(op)()) {
			return true;
		}
	}
	return false;
}
Exemplo n.º 12
0
TEST(TestEnumeration, CaseAccess)
{
    SEMANTIC_ANALYZE(L"enum CompassPoint { \n"
            L"case North\n"
            L"case South\n"
            L"case East\n"
            L"case West\n"
            L"}\n"
            L"var a = CompassPoint.East;");
    dumpCompilerResults(compilerResults);
    ASSERT_EQ(0, compilerResults.numResults());
    SymbolPtr a;
    TypePtr CompassPoint;
    ASSERT_NOT_NULL(a = scope->lookup(L"a"));
    ASSERT_NOT_NULL(CompassPoint = dynamic_pointer_cast<Type>(scope->lookup(L"CompassPoint")));
    ASSERT_EQ(CompassPoint, a->getType());

}
Exemplo n.º 13
0
void SemanticAnalyzer::visitValueBinding(const ValueBindingPtr& node)
{
    PatternPtr name = node->getName();
    //tuple was already exploded in declaration analyzer
    if(name->getNodeType() == NodeType::Tuple)
    {
        validateTupleTypeDeclaration(node);
    }
    if (name->getNodeType() != NodeType::Identifier)
        return;
    if(node->getOwner()->isReadOnly() && !node->getInitializer() && ctx->currentType == nullptr)
    {
        error(node, Errors::E_LET_REQUIRES_INITIALIZER);
        return;
    }
    //handle type inference for temporary variable
    if(node->isTemporary() && node->getInitializer())
    {
        //temporary variable always has an initializer
        TypePtr initializerType;
        TypePtr declaredType = node->getType();

        SCOPED_SET(ctx->contextualType, declaredType);
        node->getInitializer()->accept(this);
        initializerType = node->getInitializer()->getType();
        assert(initializerType != nullptr);

        if(declaredType)
        {
            //it has both type definition and initializer, then we need to check if the initializer expression matches the type annotation
            if(!initializerType->canAssignTo(declaredType))
            {
                error(node, Errors::E_CANNOT_CONVERT_EXPRESSION_TYPE_2, initializerType->toString(), declaredType->toString());
                return;
            }
        }
        else
        {
            node->setType(initializerType);
        }
    }
    

    //add implicitly constructor for Optional
    IdentifierPtr id = static_pointer_cast<Identifier>(node->getName());
    SymbolScope* currentScope = symbolRegistry->getCurrentScope();


    TypePtr declaredType = node->getType() ? node->getType() : lookupType(node->getDeclaredType());
    SCOPED_SET(ctx->contextualType, declaredType);
    if(!declaredType && !node->getInitializer())
    {
        error(node, Errors::E_TYPE_ANNOTATION_MISSING_IN_PATTERN);
        return;
    }
    SymbolPtr sym = currentScope->lookup(id->getIdentifier());
    assert(sym != nullptr);
    SymbolPlaceHolderPtr placeholder = std::dynamic_pointer_cast<SymbolPlaceHolder>(sym);
    assert(placeholder != nullptr);
    if(declaredType)
    {
        placeholder->setType(declaredType);
    }
    ExpressionPtr initializer = node->getInitializer();
    if(initializer)
    {
        placeholder->setFlags(SymbolFlagInitializing, true);
        ExpressionPtr initializer = transformExpression(declaredType, node->getInitializer());
        node->setInitializer(initializer);
        TypePtr actualType = initializer->getType();
        assert(actualType != nullptr);
        if(declaredType)
        {
            if(!Type::equals(actualType, declaredType) && !canConvertTo(initializer, declaredType))
            {
                error(initializer, Errors::E_CANNOT_CONVERT_EXPRESSION_TYPE_2, actualType->toString(), declaredType->toString());
                return;
            }
        }

        if(!declaredType)
            placeholder->setType(actualType);
    }
    assert(placeholder->getType() != nullptr);
    placeholder->setFlags(SymbolFlagInitializing, false);
    //optional type always considered initialized, compiler will make it has a default value nil
    TypePtr symbolType = sym->getType();
    GlobalScope* global = symbolRegistry->getGlobalScope();
    if(initializer || global->isOptional(symbolType) || global->isImplicitlyUnwrappedOptional(symbolType))
        markInitialized(placeholder);

    if (initializer)
        placeholder->setFlags(SymbolFlagHasInitializer, true);
    if(node->isTemporary())
    {
        placeholder->setFlags(SymbolFlagTemporary, true);
        markInitialized(placeholder);
    }

    if(!node->isTemporary())
    {
        //check access control level
        DeclarationType decl = ctx->currentType ? DeclarationTypeProperty : DeclarationTypeVariable;
        declarationAnalyzer->verifyAccessLevel(node->getOwner(), placeholder->getType(), decl, ComponentTypeType);
    }
    if(ctx->currentType && ctx->currentType->getCategory() == Type::Protocol)
    {
        error(node, Errors::E_PROTOCOL_VAR_MUST_BE_COMPUTED_PROPERTY_1);
    }
}
Exemplo n.º 14
0
/// Called after code is generated, this function loops over all the ops
/// and figures out the lifetimes of all variables, based on whether the
/// args in each op are read or written.
void
OSLCompilerImpl::track_variable_lifetimes (const OpcodeVec &code,
                                           const SymbolPtrVec &opargs,
                                           const SymbolPtrVec &allsyms)
{
    // Clear the lifetimes for all symbols
    BOOST_FOREACH (Symbol *s, allsyms)
        s->clear_rw ();

    static ustring op_for("for");
    static ustring op_while("while");
    static ustring op_dowhile("dowhile");

    // For each op, mark its arguments as being used at that op
    int opnum = 0;
    BOOST_FOREACH (const Opcode &op, code) {
        // Some work to do for each argument to the op...
        for (int a = 0;  a < op.nargs();  ++a) {
            SymbolPtr s = opargs[op.firstarg()+a];
            ASSERT (s->dealias() == s);
            // s = s->dealias();   // Make sure it's de-aliased

            // Mark that it's read and/or written for this op
            s->mark_rw (opnum, op.argread(a), op.argwrite(a));
        }

        // If this is a loop op, we need to mark its control variable
        // (the only arg) as used for the duration of the loop!
        if (op.opname() == op_for ||
            op.opname() == op_while ||
            op.opname() == op_dowhile) {
            ASSERT (op.nargs() == 1);  // loops should have just one arg
            SymbolPtr s = opargs[op.firstarg()];
            s->mark_rw (opnum+1, true, true);
            s->mark_rw (op.farthest_jump()-1, true, true);
        }

        ++opnum;
    }


    // Special case: temporaries referenced both inside AND outside a
    // loop need their lifetimes extended to cover the entire loop so
    // they aren't accidentally coalesced incorrectly.  The specific
    // danger is for a function that contains a loop, and the function
    // is passed an argument that is a temporary calculation.
    opnum = 0;
    BOOST_FOREACH (const Opcode &op, code) {
        if (op.opname() == op_for ||
            op.opname() == op_while ||
            op.opname() == op_dowhile) {
            int loopend = op.farthest_jump() - 1;
            BOOST_FOREACH (Symbol *s, allsyms) {
                if (s->symtype() == SymTypeTemp && 
                    ((s->firstuse() < opnum && s->lastuse() >= opnum) ||
                     (s->firstuse() < loopend && s->lastuse() >= loopend))) {
                    s->mark_rw (opnum, true, true);
                    s->mark_rw (loopend, true, true);
                }
            }
        }
        ++opnum;
    }
    /**
     * @Inherit
     */
    inline virtual void draw(SimViewer::SimViewer& viewer,
                             const Vector2D& posRoot, scalar angleRoot,
                             const Vector2D& posLeaf, scalar angleLeaf,
                             scalar value)
    {
        // Joint::draw(viewer, posRoot, angleRoot,
        //             posLeaf, angleLeaf, value);




        Vector2D pos_j = posRoot + Vector2D::rotate(
            Joint::getPosRoot(), angleRoot);

        viewer.drawJoint(pos_j.x(), pos_j.y(),
                         (Joint::getAngleRoot()+angleRoot)*180.0/M_PI,
                         (value)*180.0/M_PI);

        Vector2D pos = posLeaf + Vector2D::rotate(
            Joint::getPosLeaf(), angleLeaf);

        viewer.drawSegmentByEnd(posRoot.x(),posRoot.y(), pos_j.x(),pos_j.y() ,0.05,sf::Color(0,200,0,100));

        // viewer.drawJoint(pos.x(), pos.y(),
        //     (Joint::getAngleRoot()+angleRoot)*180.0/M_PI,
        //     (value)*180.0/M_PI);


        double ori=(Joint::getAngleLeaf()+angleLeaf);

        Vector2D rot;

        //Draw the cam
        Vector2D pos_r=pos;
        Vector2D pos_l=pos;
        double x=0.0;
        double y=0.0;

        Leph::Symbolic::Bounder bounder;
        SymbolPtr xs = Symbol::create("x");


        for(int i=0;i<100;i++)
        {
            x+=.3/100.0;
            xs->reset();
            bounder.setValue(xs,x);
            // y=F(x);
            y=_F(xs)->evaluate(bounder);



            rot=Vector2D::rotate(Vector2D(x,y),ori+M_PI);

            viewer.drawSegmentByEnd(pos_r.x(),pos_r.y(), pos.x()+rot.x(),pos.y()+rot.y() ,0.01,sf::Color(200,200,200,100));
            pos_r=Vector2D(pos.x()+rot.x(), pos.y()+rot.y());
            xs->reset();
            bounder.setValue(xs,-x);
            y=_F(xs)->evaluate(bounder);
            // y=F(-x);
            rot=Vector2D::rotate(Vector2D(-x,y),ori+M_PI);

            viewer.drawSegmentByEnd(pos_l.x(),pos_l.y(), pos.x()+rot.x(),pos.y()+rot.y() ,0.01,sf::Color(200,200,200,100));
            pos_l=Vector2D(pos.x()+rot.x(), pos.y()+rot.y());


        }



        viewer.drawSegment(pos.x(),pos.y(),_sH*2.0,(Joint::getAngleLeaf()+angleLeaf-M_PI/2.0)*180.0/M_PI,0.05,sf::Color(255,255,255,100));


        viewer.drawSegment(pos_j.x(),pos_j.y(),_sH,((Joint::getAngleRoot()+angleRoot)+M_PI/2.0-_sphi)*180.0/M_PI,0.01,sf::Color(255,0,255,100));

        viewer.drawCircle(pos_j.x()+_sH*cos((Joint::getAngleRoot()+angleRoot)+M_PI/2.0-_sphi),pos_j.y()+_sH*sin((Joint::getAngleRoot()+angleRoot)+M_PI/2.0-_sphi),0.03,sf::Color(255,0,255,100));

        viewer.drawCircle(pos.x(),pos.y(),0.03,sf::Color(255,255,255,255));


        //Draw spring
        Vector2D pos1 = posRoot + Vector2D::rotate(
            Joint::getPosRoot(), angleRoot);
        Vector2D pos2 = posLeaf + Vector2D::rotate(
            Joint::getPosLeaf(), angleLeaf);

        double zval=Vector2D::dist(pos1,pos2);

        scalar tmp=zval/10.0;
        scalar sig=1.0;
        Vector2D tmppos=pos1;
        scalar angle=atan2(pos2.y()-pos1.y(),pos2.x()-pos1.x());

        Vector2D tmpnew=tmppos+Vector2D::rotate(Vector2D(0.1*sig,tmp), angle+M_PI/2.0+M_PI);

        viewer.drawSegmentByEnd(tmppos.x(),tmppos.y(), tmpnew.x(),tmpnew.y(),0.01,sf::Color(200,200,200,100));

        tmppos=tmpnew;
        sig*=-1.0;

        tmp=zval/5.0;


        for(int i=1;i<5;i++)
        {
            tmpnew=tmppos+Vector2D::rotate(Vector2D(0.2*sig,tmp), angle+M_PI/2.0+M_PI);

            viewer.drawSegmentByEnd(tmppos.x(),tmppos.y(), tmpnew.x(),tmpnew.y(),0.01,sf::Color(200,200,200,100));

            tmppos=tmpnew;
            sig*=-1.0;

        }
        tmp=zval/10.0;

        tmpnew=tmppos+Vector2D::rotate(Vector2D(0.1*sig,tmp), angle+M_PI/2.0+M_PI);
        viewer.drawSegmentByEnd(tmppos.x(),tmppos.y(), tmpnew.x(),tmpnew.y(),0.01,sf::Color(200,200,200,100));

    }
Exemplo n.º 16
0
/// Called after code is generated, this function loops over all the ops
/// and figures out the lifetimes of all variables, based on whether the
/// args in each op are read or written.
void
OSLCompilerImpl::track_variable_lifetimes (const OpcodeVec &code,
                                           const SymbolPtrVec &opargs,
                                           const SymbolPtrVec &allsyms)
{
    // Clear the lifetimes for all symbols
    BOOST_FOREACH (Symbol *s, allsyms)
        s->clear_rw ();

    static ustring op_for("for");
    static ustring op_while("while");
    static ustring op_dowhile("dowhile");

    // For each op, mark its arguments as being used at that op
    int opnum = 0;
    BOOST_FOREACH (const Opcode &op, code) {
        // Some work to do for each argument to the op...
        for (int a = 0;  a < op.nargs();  ++a) {
            SymbolPtr s = opargs[op.firstarg()+a];
            ASSERT (s->dealias() == s);
            // s = s->dealias();   // Make sure it's de-aliased

            // Mark that it's read and/or written for this op
            s->mark_rw (opnum, op.argread(a), op.argwrite(a));
        }

        // If this is a loop op, we need to mark its control variable
        // (the only arg) as used for the duration of the loop!
        if (op.opname() == op_for ||
            op.opname() == op_while ||
            op.opname() == op_dowhile) {
            ASSERT (op.nargs() == 1);  // loops should have just one arg
            SymbolPtr s = opargs[op.firstarg()];
            s->mark_rw (opnum+1, true, true);
            s->mark_rw (op.farthest_jump()-1, true, true);
        }

        ++opnum;
    }


    // Special cases: handle variables whose lifetimes cross the boundaries
    // of a loop.
    opnum = 0;
    BOOST_FOREACH (const Opcode &op, code) {
        if (op.opname() == op_for ||
            op.opname() == op_while ||
            op.opname() == op_dowhile) {
            int loopcond = op.jump (0);  // after initialization, before test
            int loopend = op.farthest_jump() - 1;
            BOOST_FOREACH (Symbol *s, allsyms) {
                // Temporaries referenced both inside AND outside a loop
                // need their lifetimes extended to cover the entire
                // loop so they aren't coalesced incorrectly.  The
                // specific danger is for a function that contains a
                // loop, and the function is passed an argument that is
                // a temporary calculation.
                if (s->symtype() == SymTypeTemp &&
                    ((s->firstuse() < loopcond && s->lastuse() >= loopcond) ||
                     (s->firstuse() < loopend && s->lastuse() >= loopend))) {
                    s->mark_rw (opnum, true, true);
                    s->mark_rw (loopend, true, true);
                }

                // Locals that are written within the loop should have
                // their usage conservatively expanded to the whole
                // loop.  This is not a worry for temps, because they
                // CAN'T be read in the next iteration unless they were
                // set before the loop, handled above.  Ideally, we
                // could be less conservative if we knew that the
                // variable in question was declared/scoped internal to
                // the loop, in which case it can't carry values to the
                // next iteration (FIXME).
                if (s->symtype() == SymTypeLocal &&
                      s->firstuse() < loopend && s->lastwrite() >= loopcond) {
                    bool read = (s->lastread() >= loopcond);
                    s->mark_rw (opnum, read, true);
                    s->mark_rw (loopend, read, true);
                }
            }
        }
        ++opnum;
    }
Exemplo n.º 17
0
        /**
         * @Inherit
         */
        inline virtual void draw(SimViewer::SimViewer& viewer,
            const Vector2D& posRoot, scalar angleRoot,
            const Vector2D& posLeaf, scalar angleLeaf,
            scalar value)
        {
            Joint::draw(viewer, posRoot, angleRoot,
                posLeaf, angleLeaf, value);

            // Vector2D pos = posRoot + Vector2D::rotate(
            //     Joint::getPosRoot(), angleRoot);

            Vector2D pos = posLeaf + Vector2D::rotate(
                Joint::getPosLeaf(), angleLeaf);

            viewer.drawJoint(pos.x(), pos.y(),
                (Joint::getAngleRoot()+angleRoot)*180.0/M_PI,
                (value)*180.0/M_PI);

            pos = posRoot + Vector2D::rotate(
                Joint::getPosRoot(), angleRoot);

            double ori=(Joint::getAngleRoot()+angleRoot);

            Vector2D rot;

                //Draw the cam
            Vector2D pos_r=pos;
            Vector2D pos_l=pos;
            double x=0.0;
            double y=0.0;

            Leph::Symbolic::Bounder bounder;
            SymbolPtr xs = Symbol::create("x");

            for(int i=0;i<100;i++)
            {

                x+=.3/100.0;
                xs->reset();
                bounder.setValue(xs,x);
                // y=F(x);
                y=_F(xs)->evaluate(bounder);

                // std::cout<<"x: "<<x<<" "<<xs->evaluate(bounder)<<" y: "<<y<<std::endl;


                rot=Vector2D::rotate(Vector2D(x,y),ori);

                viewer.drawSegmentByEnd(pos_r.x(),pos_r.y(), pos.x()+rot.x(),pos.y()+rot.y() ,0.01,sf::Color(200,200,200,100));
                pos_r=Vector2D(pos.x()+rot.x(), pos.y()+rot.y());

                xs->reset();
                bounder.setValue(xs,-x);
                y=_F(xs)->evaluate(bounder);
                // y=F(-x);
                rot=Vector2D::rotate(Vector2D(-x,y),ori);

                viewer.drawSegmentByEnd(pos_l.x(),pos_l.y(), pos.x()+rot.x(),pos.y()+rot.y() ,0.01,sf::Color(200,200,200,100));
                pos_l=Vector2D(pos.x()+rot.x(), pos.y()+rot.y());


            }

            viewer.drawSegment(pos.x(),pos.y(),_sH*2.0,((Joint::getAngleRoot()+angleRoot)+M_PI/2.0)*180.0/M_PI,0.05,sf::Color(255,255,255,100));

                //Draw the lever
            viewer.drawSegment(posLeaf.x(),posLeaf.y(),_sH,(angleLeaf-M_PI/2.0)*180.0/M_PI,0.01,sf::Color(255,0,255,100));
            viewer.drawCircle(posLeaf.x()+_sH*cos(angleLeaf-M_PI/2.0),posLeaf.y()+_sH*sin(angleLeaf-M_PI/2.0),0.03,sf::Color(255,0,255,100));
            viewer.drawCircle(pos.x(),pos.y(),0.03,sf::Color(255,255,255,255));

        }
bool DeclarationAnalyzer::verifyProtocolConform(const TypePtr& type, const TypePtr& protocol, bool supressError)
{
    for(auto entry : protocol->getDeclaredMembers())
    {
        SymbolPtr requirement = entry.second;
        if(FunctionOverloadedSymbolPtr funcs = std::dynamic_pointer_cast<FunctionOverloadedSymbol>(requirement))
        {
            //verify function
            for(auto func : *funcs)
            {
                bool success = verifyProtocolFunction(type, protocol, func, supressError);
                if(!success)
                    return false;
            }
        }
        else if(FunctionSymbolPtr func = std::dynamic_pointer_cast<FunctionSymbol>(requirement))
        {
            //verify function
            bool success = verifyProtocolFunction(type, protocol, func, supressError);
            if(!success)
                return false;
        }
        /*
         else if(requirement == Type::getPlaceHolder())
         {
         //verify inner type
         SymbolPtr sym = type->getAssociatedType(entry.first);
         if(!(std::dynamic_pointer_cast<Type>(sym)))
         {
         //Type %0 does not conform to protocol %1, unimplemented type %2
         error(type->getReference(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_UNIMPLEMENTED_TYPE_3, type->getName(), protocol->getName(), entry.first);
         }
         }*/
        else if(TypePtr t = std::dynamic_pointer_cast<Type>(requirement))
        {
            //if type doesn't declare a type alias but the protocol has defined it with a full definition, then we will implicitly declare it
            wstring name = t->getName();
            TypePtr originalType = t->resolveAlias();
            if(type->getAssociatedType(name) == nullptr && originalType != nullptr && originalType->getCategory() != Type::Alias)
            {
                TypeBuilderPtr builder = static_pointer_cast<TypeBuilder>(type);
                builder->addMember(name, originalType);
            }
            //typealias checking is moved to second stage, when all other members verified
            continue;
        }
        else if(dynamic_pointer_cast<ComputedPropertySymbol>(requirement) || dynamic_pointer_cast<SymbolPlaceHolder>(requirement))
        {
            //verify computed properties
            SymbolPtr sym = type->getMember(entry.first);
            //ComputedPropertySymbolPtr sp = std::dynamic_pointer_cast<ComputedPropertySymbol>(sym);
            if(!sym || !checkTypeConform(type, requirement->getType(), sym->getType()))
            {
                if(!supressError)
                {
                    error(type->getReference(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_UNIMPLEMENTED_PROPERTY_3, type->getName(), protocol->getName(), entry.first);
                }
                return false;
            }
            bool expectedSetter = requirement->hasFlags(SymbolFlagWritable);
            bool actualSetter = sym->hasFlags(SymbolFlagWritable);
            if(expectedSetter && !actualSetter)
            {
                if(!supressError)
                {
                    error(type->getReference(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_UNWRITABLE_PROPERTY_3, type->getName(), protocol->getName(), entry.first);
                }
                return false;
            }
        }
    }
    //check again for associated types
    for(auto entry : protocol->getAssociatedTypes())
    {
        if(entry.second->resolveAlias() != nullptr)
            continue;
        TypePtr t = type->getAssociatedType(entry.first);
        if(t == nullptr)
        {
            //undefined type alias
            if(!supressError)
            {
                error(type->getReference(), Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_2_, type->getName(), protocol->getName());
            }
            return false;
        }
    }
    return true;
}
SymbolPtr CodeBlock::translate(TokenPtr token) {
	if (token->get_token() == MP_ID) {
		string search_lexeme = token->get_lexeme();
		unsigned int search_level = this->get_nesting_level();
		SymbolListPtr filtered_data = this->get_analyzer()->get_symtable()->data_in_scope_at(search_lexeme, search_level);
		if (this->check_filter_size(filtered_data)) {
			SymbolPtr found = *filtered_data->begin();
			found->set_col(token->get_column());
			found->set_row(token->get_line());
			return found;
		} else {
			SymbolListPtr global_data = this->get_analyzer()->get_symtable()->data_in_scope_at(search_lexeme, 0);
			if (this->check_filter_size(global_data)) {
				SymbolPtr found = *global_data->begin();
				found->set_col(token->get_column());
				found->set_row(token->get_line());
				return found;
			} else {
				if (global_data == nullptr) {
					report_error_lc("Semantic Error", "ID '" + search_lexeme + "' not found",
									token->get_line(), token->get_column());
				} else {
					report_error("Semantic Error", "ID '" + search_lexeme + "' redefined as...");
					for (auto it = global_data->begin(); it != global_data->end(); it++) {
						SymDataPtr dptr = static_pointer_cast<SymData>(*it);
						report_error_lc("Definition @", (*it)->get_symbol_name() + " as " + var_type_to_string(dptr->get_var_type()), (*it)->get_row(), (*it)->get_col());
					}
				}
				this->valid = false;
				return nullptr;
			}
		}
	} else if (token->get_token() == MP_INT_LITERAL) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), INTEGER_LITERAL));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_STRING_LITERAL) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), STRING_LITERAL));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_FLOAT_LITERAL) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), FLOATING_LITERAL));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_TRUE) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), BOOLEAN_LITERAL_T));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_FALSE) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), BOOLEAN_LITERAL_F));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_LEFT_PAREN) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), LPAREN));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_RIGHT_PAREN) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), RPAREN));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_PLUS) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), ADD));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_MINUS) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), SUB));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_MULT) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), MUL));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_DIV) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), DIV));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_DIV_KW) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), DIV));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_MOD_KW) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), MOD));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_AND) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), AND));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_OR) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), OR));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_NOT) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), NOT));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_LESSTHAN) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), ILT));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_EQUALS) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), IEQ));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_LESSTHAN_EQUALTO) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), ILE));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_GREATERTHAN) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), IGT));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_GREATERTHAN_EQUALTO) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), IGE));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else if (token->get_token() == MP_NOT_EQUAL) {
		SymbolPtr s = SymbolPtr(new SymConstant(token->get_lexeme(), INE));
		s->set_row(token->get_line());
		s->set_col(token->get_column());
		return s;
	} else {
		return nullptr;
	}
}
Exemplo n.º 20
0
/// Called after code is generated, this function loops over all the ops
/// and figures out the lifetimes of all variables, based on whether the
/// args in each op are read or written.
void
OSLCompilerImpl::track_variable_lifetimes (const OpcodeVec &code,
                                           const SymbolPtrVec &opargs,
                                           const SymbolPtrVec &allsyms,
                                           std::vector<int> *bblockids)
{
    // Clear the lifetimes for all symbols
    BOOST_FOREACH (Symbol *s, allsyms)
        s->clear_rw ();

    // Keep track of the nested loops we're inside. We track them by pairs
    // of begin/end instruction numbers for that loop body, including
    // conditional evaluation (skip the initialization). Note that the end
    // is inclusive. We use this vector of ranges as a stack.
    typedef std::pair<int,int> intpair;
    std::vector<intpair> loop_bounds;

    // For each op, mark its arguments as being used at that op
    int opnum = 0;
    BOOST_FOREACH (const Opcode &op, code) {
        if (op.opname() == op_for || op.opname() == op_while ||
                op.opname() == op_dowhile) {
            // If this is a loop op, we need to mark its control variable
            // (the only arg) as used for the duration of the loop!
            ASSERT (op.nargs() == 1);  // loops should have just one arg
            SymbolPtr s = opargs[op.firstarg()];
            int loopcond = op.jump (0); // after initialization, before test
            int loopend = op.farthest_jump() - 1;   // inclusive end
            s->mark_rw (opnum+1, true, true);
            s->mark_rw (loopend, true, true);
            // Also push the loop bounds for this loop
            loop_bounds.push_back (std::make_pair(loopcond, loopend));
        }

        // Some work to do for each argument to the op...
        for (int a = 0;  a < op.nargs();  ++a) {
            SymbolPtr s = opargs[op.firstarg()+a];
            ASSERT (s->dealias() == s);  // Make sure it's de-aliased

            // Mark that it's read and/or written for this op
            bool readhere = op.argread(a);
            bool writtenhere = op.argwrite(a);
            s->mark_rw (opnum, readhere, writtenhere);

            // Adjust lifetimes of symbols whose values need to be preserved
            // between loop iterations.
            BOOST_FOREACH (intpair oprange, loop_bounds) {
                int loopcond = oprange.first;
                int loopend = oprange.second;
                DASSERT (s->firstuse() <= loopend);
                // Special case: a temp or local, even if written inside a
                // loop, if it's entire lifetime is within one basic block
                // and it's strictly written before being read, then its
                // lifetime is truly local and doesn't need to be expanded
                // for the duration of the loop.
                if (bblockids &&
                    (s->symtype()==SymTypeLocal || s->symtype()==SymTypeTemp) &&
                    (*bblockids)[s->firstuse()] == (*bblockids)[s->lastuse()] &&
                    s->lastwrite() < s->firstread()) {
                    continue;
                }
                // Syms written before or inside the loop, and referenced
                // inside or after the loop, need to preserve their value
                // for the duration of the loop. We know it's referenced
                // inside the loop because we're here examining it!
                if (s->firstwrite() <= loopend) {
                    s->mark_rw (loopcond, readhere, writtenhere);
                    s->mark_rw (loopend, readhere, writtenhere);
                }
            }
        }

        ++opnum;  // Advance to the next op index

        // Pop any loop bounds for loops we've just exited
        while (!loop_bounds.empty() && loop_bounds.back().second < opnum)
            loop_bounds.pop_back ();
    }