Exemple #1
0
//--------------------------------------------------------------
void ofApp::update(){
    for( int i = 0; i < bubbles.size() ; i++) {
        bubbles[i].update() ;
        //Code to erase the bubbles once they reach a certain distance
        float distance = ofDist(bubbles[i].birth.x, bubbles[i].birth.y , bubbles[i].pos.x, bubbles[i].pos.y) ;
        if(distance > 300) {
            bubbles.erase(bubbles.begin() + i) ;
            i-- ;
        }
        //Code to erase a bubble if its underneath the mouse cursor
        if(mouseX >= bubbles[i].pos.x - 10 && mouseX <= bubbles[i].pos.x + 10
           && mouseY >= bubbles[i].pos.y - 10 && mouseY <= bubbles[i].pos.y +10) {
            bubbles.erase(bubbles.begin() + i) ;
            i-- ;
            
        }
//        if(bubbles[i].pos.x < 100 || bubbles[i].pos.x > 800) {
//            bubbles.erase(bubbles.begin() + i) ;
//            i-- ;
//        }
//        if(bubbles[i].pos.y < 100 || bubbles[i].pos.y > 600) {
//            bubbles.erase(bubbles.begin() + i) ;
//            i-- ;
//        }
    }
    //generates a bubble to be drawn
    Bubble tempBubble ;
    tempBubble.setup(ofGetWidth()/2, ofGetHeight()/2) ;
    bubbles.push_back(tempBubble) ;
}
Exemple #2
0
void PlayScene::DestroyBubble(Bubble* bubble)
{
    if (!bubble)
        return;

    m_bubbles.remove(bubble);

    // Scene ending
    if (bubble->GetBubbleType() == eBubbles::Player)
        m_status = Status::Lose;
    else if (bubble->GetBubbleType() == eBubbles::Good)
    {
        // Set good bubbles score
        const uint32 goodBubbles = std::count_if(m_bubbles.cbegin(), m_bubbles.cend(), [](const Bubble* b)
        {
            return b->GetBubbleType() == eBubbles::Good;
        });
        m_scorePanel->SetValue(eScores::GOOD_BUBBLES, goodBubbles);

        if (!GetBubble(eBubbles::Good))
        {
            Bubble* plBubble = GetBubble(eBubbles::Player);
            Assert(plBubble == nullptr,
                "PlayScene::DestroyBubble: Player bubble not found for finish game");

            m_playerBubbleSizeOnEnd = plBubble->GetCircle()->getRadius() * 2;
            m_status = Status::Win;
        }
    }

    delete bubble;
}
Exemple #3
0
void Simulation:: initialize()
{
    const double Ly = sim_region.length.y;
    const double Lx = sim_region.length.x;
    U.ldz();
    P.ldz();
    bubbles.empty();
    for( unit_t j=lower.y;j<=upper.y;++j)
    {
        for( unit_t i=lower.x;i<=upper.x;++i)
        {
            P[j][i]   = Y[j] / Ly;
            P[j][i]   = 0.1 * (0.5 - Alea());
            U[j][i].y = 0.04 + 0.08 * cos( numeric<double>::pi * Y[j] / Ly );
            U[j][i].y = 0.15;
        }
    }
    if( master )
    {
        Bubble *b = bubbles.create();
        //b->map_peanut( Vertex(sim_box.x/2,0), 0.15 * Lx, 0.9 + 0.09 * Alea() );
        b->map_circle(Vertex(sim_box.x/3,0), 0.15 * Lx);
        b->set_pressure(2);
    }
    cycle = 0;
    bubbles_velocities = true;
    compute_fields();
}
Exemple #4
0
void Network::parseUserCommand(uint8_t *buff, int size)
{
	printf("user command received\n");

	movementCommand_t move;
	memcpy(&move, &buff[1], sizeof(move));

	int id;
	memcpy(&id, &buff[1 + sizeof(move)], sizeof(id));

	//name gathering
	char *name;
	name = (char *)&buff[1 + sizeof(move) + sizeof(id)];

	Bubble *b = new Bubble();

	Point pos;
	pos.x = move.x;
	pos.y = move.y;
	Point dir;
	dir.x = move.dirX;
	dir.y = move.dirY;
	std::string strName(name);

	b->setPos(pos);
	b->setDir(dir);
	b->setName(strName);
	b->setID(id);

	chatObject->addBubble(*b);	

	return;
}
void BubbleGrid::dropBubbles()
{
	// Find any bubbles not connected and set them to fall
	for (int i = 0; i < GRID_WIDTH; i++)
	{
		for (int j = 0; j < GRID_HEIGHT; j++)
		{
			if(m_pBubbles[i][j]->getChecked() == false)
			{
				if(m_pBubbles[i][j]->getType() != EMPTY)
				{
					// Store the falling bubble in the vector for updating
					Bubble *fallingBubble = m_pBubbles[i][j];
					fallingBubble->setFalling(true);
					m_pFallingBubbles.push_back(fallingBubble);

					// create a new bubble in its place
					Bubble *bubble = Bubble::create();
					bubble->setPosition(getPosition(i, j));
					this->addChild(bubble);
					m_pBubbles[i][j] = bubble;
				}
			}
		}
	}
}
Exemple #6
0
//--------------------------------------------------------------
void ofApp::update(){
    Bubble tempBubble;
    tempBubble.setup(ofGetMouseX(), ofGetMouseY());
    bubbles.push_back(tempBubble);
    for(int i=0; i<bubbles.size(); i++){
        //bubbles[i].vel = ofVec2f(ofRandom(-4, 4), ofRandom(-10, 10));
        bubbles[i].update();
        float distance = ofDist(bubbles[i].birth.x, bubbles[i].birth.y, bubbles[i].pos.x , bubbles[i].pos.y);
        //this equation erases bubble instances after they go off the screen so the program doesn't keep trying to draw them
        if (distance>500){
            bubbles.erase(bubbles.begin()+i);
            i--;  //if we don't do this here, we'll skip the next bubble in this update
        }
    }
    Box tempBox;
    tempBox.setup(ofGetWindowWidth()/2, ofGetWindowHeight());
    boxes.push_back(tempBox);
    for(int i=0; i<boxes.size(); i++){
        boxes[i].update();
        float distance = ofDist(boxes[i].birth.x, boxes[i].birth.y, boxes[i].pos.x , boxes[i].pos.y);
        if (distance>500){
            boxes.erase(boxes.begin()+i);
            i--;
        }

    }
}
Exemple #7
0
void test_cubic_collision(Bubble &bubble){
    int top = 1;
    
    if(top < (bubble.get_y()+bubble.get_radius())){
        bubble.reset();
    }
}
Exemple #8
0
 bool BubbleBand::
 AppendTarget(const Goal & global_goal)
 {
   m_min_ignore_distance = global_goal.Dr() + robot_radius;
   m_nf1_goal_radius = m_min_ignore_distance;
   m_global_goal = global_goal;
   if(m_active_blist->m_head == 0){
     m_replan_request = true;
     return false;
   }
   
   // cheap method: move the last bubble onto the target, attempt to
   // keep a copy on its previous position, don't even check if
   // there's enough clearance (next update should take care of that...)
   Bubble *bubble = m_bubble_factory->Clone(m_active_blist->m_tail);
   if(bubble != 0){
     bubble->SetMinIgnoreDistance(0);
     bubble->_alpha_int = Bubble::DEFAULTALPHAINT;
     bubble->_alpha_ext = Bubble::DEFAULTALPHAEXT;
     m_active_blist->InsertAfter(m_active_blist->m_tail->_previous, bubble);
   }
   m_active_blist->m_tail->_position =
     make_pair(m_global_goal.X(), m_global_goal.Y());
   return true;
 }
Exemple #9
0
void PacientScene::createBubble()
{
    Bubble *bubble = new Bubble();
    bubble->setText("Write text here...");
    bubble->setPos(_lastMousePressPosition);
    addItem(bubble);

    bubble->changeText();
}
Exemple #10
0
//! [13]
void GLWidget::animate()
{
    QMutableListIterator<Bubble*> iter(bubbles);

    while (iter.hasNext()) {
        Bubble *bubble = iter.next();
        bubble->move(rect());
    }
    update();
}
void BubbleCollection::drawRandomlyFromCollection() {
    if (collection.size() == 0) {
        std::cerr << "Error: size of collection is 0" << std::endl;
        return;
    }
    
    // Use random number to select bubble from collection
    Bubble selection = collection.at( ((int)rand()) % collection.size() );
    
    // Draw Selection
    selection.draw();
}
Exemple #12
0
Bubble * Bubble::initWithType(BubbleType type) //根据传过来的类型来生成泡泡
{
	Bubble *pRet = Bubble::create();
	pRet->setType(type);
	pRet->initWithSpriteFrameName(getStringByType(type));






	return pRet;
}
Exemple #13
0
int CglWnd::drawGL()
{
	//esDPrint(L"DrawBegin\n");

	glClear(GL_COLOR_BUFFER_BIT);
	//复位坐标
	memcpy(m_dTexVertex, m_oTexVertex, sizeof(m_oTexVertex));
	if (!m_bEdit)
	{
		updateBubbles();
	}
	glVertexAttribPointer(positionLoc, 3, GL_INT, GL_FALSE, 0, m_dTexVertex);
	glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, m_texCoord);
	glBindTexture(GL_TEXTURE_2D, texture[TEXID_BG]);
	glDrawElements(GL_TRIANGLES /*GL_LINE_LOOP*/, columnPieces*rowPieces*3*2, GL_UNSIGNED_SHORT, m_indices);

	if (m_bEdit)
	{	
		int nHide = 0;
		Bubble *bubbleSelect = NULL;
		glBindTexture(GL_TEXTURE_2D, texture[TEXID_SET]);
		for (int i = 0; i < MAX_BUBBLES; i++)
		{
			Bubble *b = &m_bubbles[i];
			if (b->eState == ST_REMOVED) continue;
			b->update();
			if (b->eState == ST_NORMAL)
			{
				nHide++;
				continue;
			}
			if (b->bSelect)
				bubbleSelect = b;
			else
				drawSquare(b->ox, b->oy, b->r * b->zoomRate);
		}
		if (bubbleSelect)
		{
			glBindTexture(GL_TEXTURE_2D, texture[TEXID_SET_SELECT]);
			drawSquare(bubbleSelect->ox, bubbleSelect->oy, bubbleSelect->r * bubbleSelect->zoomRate);
		}
		
		if ( m_activeBubbles > 0)
			m_bEdit = nHide < m_activeBubbles;
	}
	m_toolbar.draw();
	//esDPrint(L"Draw\n");
	eglSwapBuffers(m_Display, m_Surface);
	g_fps_count++;
	return 1;
}
Exemple #14
0
void GameBoard::updateBubblePostion(float dt){
    Bubble * bubble;
    CCPoint * point;
    for (int i=0; i<bubblesData->count(); i++) {
        bubble = (Bubble*) bubblesData->objectAtIndex(bubblesData->count() - 1 - i);
        point = getBubblePostion(bubble);
        if (!bubble->active) {
            bubble->x = point->x;
            bubble->y = point->y;
            bubble->setPosition(CCPointMake(bubble->x, bubble->y));
        }else{
            bubble->update(dt);
        }
    }
}
Exemple #15
0
void GameBoard::checkDeleteBubbles(Bubble * bubble){
    CCArray * neighbors = getNeighbors(bubble);
    neighbors->retain();
    Bubble * tempBubble;
    bool hasChecked = false;
    CCPoint *point;
    CCPoint *checkedPoint;
    for(int i = 0; i < neighbors->count(); i++){
        point = (CCPoint *) neighbors->objectAtIndex(i);
        //CCLOG("P:%i", (int) point->y);
        //CCLOG("PP:%i", (int) point->x);
        tempBubble = getBubble(point->y, point->x);
        if (tempBubble == NULL) {
            continue;
        }
        tempBubble->retain();
        
        for (int j = 0; j < bubblesChecked->count(); j++) {
            checkedPoint = (CCPoint *) bubblesChecked->objectAtIndex(j);
            //            CCLOG("XX:%i", (int) checkedPoint->x);
            //            CCLOG("YX:%i", (int) checkedPoint->y);
            //            CCLOG("XXX:%i", (int) tempBubble->col);
            //            CCLOG("YXX:%i", (int) tempBubble->row);
            if (checkedPoint->x == tempBubble->col && checkedPoint->y == tempBubble->row) {
                hasChecked = true;
                break;
            }
        }
        
        if (hasChecked) {
            hasChecked = false;
            continue;
        }else{
            bubblesChecked->addObject(point);
        }
        
        //        CCLOG("ID:%i", (int) tempBubble->bubbleID);
        //        CCLOG("X:%i", (int) point->x);
        //        CCLOG("Y:%i", (int) point->y);
        
        if(bubble->bubbleID == tempBubble->bubbleID){
            bubblesDeleted->addObject(point);
            checkDeleteBubbles(tempBubble);
        }
    }
    return ;
}
Exemple #16
0
void GameBoard::startCollosionMotion(Bubble *bubble){
    if (bubblesConnected != NULL && bubblesConnected->count() > 0) {
        bubblesConnected->removeAllObjects();
    }else{
        bubblesConnected = new CCArray();
    }
    
    getConnectedBubble(bubble);
    Bubble *temp;
    CCPoint *point;
    for (int i = 0; i<bubblesConnected->count(); i++) {
        point =  (CCPoint *) bubblesConnected->objectAtIndex(i);
        temp = getBubble(point->y, point->x);
        temp->collosionMotion(bubble);
    }
    
    bubble->collosionMotion(bubble);
}
Exemple #17
0
  bool BubbleBand::
  AppendGoal(const Goal & global_goal, shared_ptr<const Scan> scan)
  {
    m_min_ignore_distance = 0;
    m_nf1_goal_radius = global_goal.Dr();
    m_global_goal = global_goal;
    if(m_active_blist->m_head == 0){ // no band to append to...
      m_replan_request = true;
      return false;
    }
    
    // place bubble at new goal, after verifying there's enough space
    Bubble *bubble = m_bubble_factory->New(m_reaction_radius,
					   m_global_goal.X(),
					   m_global_goal.Y());
    if(bubble == 0){
      m_active_blist->RemoveAll();
      m_replan_request = true;
      return false;
    }
    Bubble *tail(m_active_blist->m_tail);
    bubble->UpdateExternalParameters(scan, ignore_radius);
    bubble->_ignore_distance = tail->_ignore_distance;
    bubble->_dprevious = Bubble::Distance(*bubble, *tail);
    bubble->_dnext = -1;
    if(Bubble::CheckOverlap(*tail, *bubble, robot_radius)){
      tail->_alpha_int = Bubble::DEFAULTALPHAINT;
      tail->_alpha_ext = Bubble::DEFAULTALPHAEXT;
      tail->_dnext = bubble->_dprevious;
      tail->_fint.first
	= (bubble->_position.first - tail->_position.first) / tail->_dnext;
      tail->_fint.second
	= (bubble->_position.second - tail->_position.second) / tail->_dnext;
      m_active_blist->Append(bubble);
      return true;
    }
    
    // couldn't fix existing band
    m_bubble_factory->Delete(bubble);
    m_active_blist->RemoveAll();
    m_replan_request = true;
    return false;
  }
Exemple #18
0
void PlayScene::OnBubbleMove(Bubble* bubble)
{
    // Check collision
    if (Bubble* collisedBubble = CheckBubbleCollision(bubble))
    {
        bubble->OnTouch(collisedBubble);
        collisedBubble->OnTouch(bubble);

        // Set player score
        Bubble* player = nullptr;
        if (bubble->GetBubbleType() == eBubbles::Player)
            player = bubble;
        else if (collisedBubble->GetBubbleType() == eBubbles::Player)
            player = collisedBubble;

        if (player)
            m_scorePanel->SetValue(eScores::PLAYER, (uint32)player->GetCircle()->getRadius() * 2);
    }
}
Exemple #19
0
/** Pop the specified bubble if it is simple, otherwise scaffold. */
static void popOrScaffoldBubble(Graph& g, const Bubble& bubble)
{
#pragma omp atomic
	g_count.bubbles++;
	if (!popSimpleBubble(&g, bubble.front()) && opt::scaffold) {
#pragma omp atomic
		g_count.scaffold++;
		scaffoldBubble(g, bubble);
	}
}
Exemple #20
0
void CglWnd::OnMouseMove( UINT fwKeys, int xPos, int yPos )
{
	//转换为Opengl的坐标系
	xPos = xPos - 240;
	yPos = 360 - yPos;
	if (m_bEdit)
	{
		for (int i = 0; i < MAX_BUBBLES; i++)
		{
			Bubble *b = &m_bubbles[i];
			if (b->eState == ST_EDIT_SHOW && b->bSelect)
			{
				b->setPos(b->ox + xPos - m_lastPosX, b->oy + yPos - m_lastPosY);
			}
		}
	}
	else
	{
		for (int i = 0; i < MAX_BUBBLES; i++)
		{
			Bubble *b = &m_bubbles[i];
			if (b->eState == ST_NORMAL && b->bSelect)
			{
				b->mx = xPos - b->ox;
				b->my = yPos - b->oy;
				int r2 = (b->mx*b->mx + b->my*b->my);
				int rr = b->r*0.6;
				if (r2 > rr*rr)
				{
					float scaleRate = rr/sqrt(r2);
					b->mx *= scaleRate;
					b->my *= scaleRate;
				}
			}
		}
	}

	m_lastPosX = xPos;
	m_lastPosY = yPos;
	
}
void BubbleGrid::buildGrid()
{
	// Create the array with the rows
	m_pBubbles = new Bubble**[GRID_WIDTH];

	// Fill each row with the cols
	for(int i = 0; i < GRID_WIDTH; i++)
		m_pBubbles[i] = new Bubble*[GRID_HEIGHT];

	CCSize size = CCDirector::sharedDirector()->getWinSize();

	float startingPosX = BUBBLE_RADIUS;
	float startingPosY = size.height - BUBBLE_RADIUS;

	// fill the 2D array wiht bubbles
	for (int i = 0; i < GRID_WIDTH; i++)
	{
		for (int j = 0; j < GRID_HEIGHT; j++)
		{
			Bubble *bubble = Bubble::create();
			bubble->setPosition(getPosition(i, j));

			if(j < GRID_HEIGHT_START)
			{
				bubble->setType((BUBBLE_TYPE)((int)((CCRANDOM_0_1() * 4) + 1)));
				if(j % 2 != 0)
				{
					if(i == GRID_WIDTH - 1) // odd rows have 1 less bubble
						bubble->setType(EMPTY);
				}
			}
			else
			{
				bubble->setType(EMPTY);
			}

			this->addChild(bubble);
			m_pBubbles[i][j] = bubble;
		}
	}
}
Exemple #22
0
/** Return the length of the longest path through the bubble. */
static int longestPath(const Graph& g, const Bubble& topo)
{
	typedef graph_traits<Graph>::edge_descriptor E;
	typedef graph_traits<Graph>::out_edge_iterator Eit;
	typedef graph_traits<Graph>::vertex_descriptor V;

	EdgeWeightMap<Graph> weight(g);
	map<ContigNode, int> distance;
	distance[topo.front()] = 0;
	for (Bubble::const_iterator it = topo.begin();
			it != topo.end(); ++it) {
		V u = *it;
		Eit eit, elast;
		for (tie(eit, elast) = out_edges(u, g); eit != elast; ++eit) {
			E e = *eit;
			V v = target(e, g);
			distance[v] = max(distance[v], distance[u] + weight[e]);
		}
	}
	V v = topo.back();
	return distance[v] - g[v].length;
}
Exemple #23
0
void PlayScene::Update(sf::Clock const& clock)
{
    if (m_status != Status::Process)
    {
        bool win = (m_status == Status::Win) ? true : false;
        return sGame->SwitchToScene(new FinishScene(win, m_playerBubbleSizeOnEnd));
    }

    // Bubbles Loading
    if (!m_bubbleLoaded)
        LoadingBubbles(clock);

    // Bubbles update
    for (BubbleList::iterator it = m_bubbles.begin(); it != m_bubbles.end();)
    {
        Bubble* bubble = (*it);

        // To destroy the burst bubbles.
        if (bubble->IsBurst())
        {
            ++it;
            DestroyBubble(bubble);
            continue;
        }

        // Update acts
        switch (bubble->GetBubbleType())
        {
        case eBubbles::Player: UpdatePlayerAct((PlayerBubble*)bubble, clock); break;
        case eBubbles::Good:
        case eBubbles::Bad: UpdateObstacleAI((ObstacleBubble*)bubble, clock); break;
        }

        bubble->Update(clock);

        ++it;
    }
}
Exemple #24
0
/** Scaffold over the bubble between vertices u and w.
 * Add an edge (u,w) with the distance property set to the length of
 * the largest branch of the bubble.
 */
static void scaffoldBubble(Graph& g, const Bubble& bubble)
{
	typedef graph_traits<Graph>::vertex_descriptor V;
	assert(opt::scaffold);
	assert(bubble.size() > 2);

	V u = bubble.front(), w = bubble.back();
	if (edge(u, w, g).second) {
		// Already scaffolded.
		return;
	}
	assert(isBubble(g, bubble.begin(), bubble.end()));

	assert(bubble.size() > 2);
	size_t n = bubble.size() - 2;
	g_popped.reserve(g_popped.size() + n);
	for (Bubble::const_iterator it = bubble.begin() + 1;
			it != bubble.end() - 1; ++it)
		g_popped.push_back(it->contigIndex());

	add_edge(u, w, max(longestPath(g, bubble), 1), g);
}
Exemple #25
0
void GameBoard::drawSights(float rad){
    CCArray * points = CCArray::create();
    float startX = currentBubble->x;
    float startY = currentBubble->y;
    points->addObject(new CCPoint(startX, startY));
    
    float step = 30;
    float dx = step * sin(rad);
    float dy = step * cos(rad);
    
    CCPoint * p;
    bool available;
    do {
        p = new CCPoint(startX + dx, startY + dy);
        if (p->x >= BUBBLE_RIGHT_EAGE) {
            dx *= -1;
            p->x = 2*BUBBLE_RIGHT_EAGE-p->x;
            if(p->x+Bubble::RADIUS >= BUBBLE_RIGHT_EAGE) p->x = BUBBLE_RIGHT_EAGE-Bubble::RADIUS;
        }
        if (p->x <= BUBBLE_LEFT_EAGE) {
            dx *= -1;
            p->x = BUBBLE_LEFT_EAGE - p->x;
            if(p->x+Bubble::RADIUS >= BUBBLE_LEFT_EAGE) p->x = BUBBLE_LEFT_EAGE + Bubble::RADIUS;
        }
        
        startX = p->x;
        startY = p->y;
        available = true;
        Bubble * bubble;
        CCPoint bubblePos;
        float dis;
        
        if (p->y >= BUBBLE_TOP_EAGE) {
            p->y = BUBBLE_TOP_EAGE - Bubble::RADIUS;
            available = false;
        }
        
        if(available){
            for (int i=0; i<bubblesData->count(); i++) {
                bubble = (Bubble*) bubblesData->objectAtIndex(bubblesData->count() - 1 - i);
                bubblePos = bubble->getPosition();
                dis = sqrtf(powf(bubblePos.x - p->x, 2)+powf(bubblePos.y - p->y,2));
                if(dis <= Bubble::RADIUS){
                    available = false;
                    break;
                }
            }
        }
        
        if(available)   points->addObject(p);
        
    } while (available);
    
    CCPoint *pp;
    CCSprite *sp;
    CCTexture2D *pTexture2D  = sightsBatch->getTexture();
    sightsBatch->removeAllChildrenWithCleanup(true);
    for (int i=0; i<points->count(); i++) {
        pp = (CCPoint*) points->objectAtIndex(i);
        sp = CCSprite::createWithTexture(pTexture2D);
        sp->setScale(0.2);
        sp->setPosition(CCPointMake(pp->x, pp->y));
        sightsBatch->addChild(sp);
    }
}
Exemple #26
0
void Rescaler:: rebuild( Bubble &bubble )
{
    //static int fid = 0;
    
    const size_t n  = bubble.size;
    const size_t n1 = n+1;
    assert( s.size()     == n1 );
    assert( ax.size()    == n1 );
    assert( ay.size()    == n1 );
    assert(period>0);
    assert(bubble.area>0);
    assert(a_list.size >= 3);
    
#if 0
    {
        ios::ocstream fp( vformat("org%d.dat",fid), false);
        for( size_t i=1; i <= n1; ++i )
        {
            fp("%g %g %g\n", s[i], ax[i], ay[i]);
        }
        fp("%g %g %g\n", period, ax[1], ay[1]);
    }
#endif
    
    Real sa[4] = { 0 };
    Real xa[4] = { 0 };
    Real ya[4] = { 0 };
    
    //--------------------------------------------------------------------------
    // rebuild the bubble
    //--------------------------------------------------------------------------
    //std::cerr << "rebuilding " << a_list.size << " points" << std::endl;
    bubble.empty();
    for( const abscissa *a = a_list.head; a; a=a->next )
    {
        const Real s_i = a->s;
        assert(s_i>=0);
        assert(s_i<period);
        //-- locate the abscissa
        const size_t j1  = __locate_abscissa(s_i, s);
        const size_t j2  = j1+1;
        
        //-- fill the middle points
        sa[1] = s[j1]; xa[1] = ax[j1]; ya[1] = ay[j1];
        sa[2] = s[j2]; xa[2] = ax[j2]; ya[2] = ay[j2];
        
        //-- fill the left point
        if( j1 <= 1 )
        {
            sa[0] = sa[1] - (s[n1] - s[n]); xa[0] = ax[n]; ya[0] = ay[n];
        }
        else
        {
            const size_t j0 = j1-1; assert(j0>0);
            sa[0] = s[j0]; xa[0] = ax[j0]; ya[0] = ay[j0];
        }
        
        //-- fill the right point
        if( j2 >= n1 )
        {
            sa[3] = s[n1] + (s[2]-s[1]);
            xa[3] = ax[1];
            ya[3] = ay[1];
        }
        else
        {
            const size_t j3 = j2+1;
            sa[3] = s[j3]; xa[3] = ax[j3]; ya[3] = ay[j3];
        }
#if 1
        const Vertex v = __interpv(s_i, sa, xa, ya, 4);
#else
        const Real    fac = (s_i - sa[1])/(sa[2]-sa[1]);
        const Vertex  v( xa[1] + fac * ( xa[2] - xa[1]), ya[1] + fac * ( ya[2] - ya[1]) );
#endif
        bubble.append()->vertex = v;
    }
    assert(bubble.size==a_list.size);
    
#if 0
    {
        ios::ocstream fp( vformat("ref%d.dat",fid), false);
        const abscissa *a = a_list.head;
        const Tracer   *p = bubble.root;
        while(a)
        {
            fp("%g %g %g\n", a->s, p->vertex.x, p->vertex.y);
            a=a->next;
            p=p->next;
        }
        fp("%g %g %g\n", period, p->vertex.x, p->vertex.y);
        
        ++fid;
    }
#endif
    
    //--------------------------------------------------------------------------
    // rebuild its metrics
    //--------------------------------------------------------------------------
    build_metrics(bubble,RescaleWithConstantPressure);
    
}
bool BubbleGrid::checkForCollision(Bubble* playerBubble)
{
	bool collided = false;
	int collidedX = 0;
	int collidedY = 0;

	CCPoint playerBubblePosition = playerBubble->getPosition();

	// Breadth first Search through the array starting from the bottom left
	for(int y = GRID_HEIGHT - 1; y >= 0; y--)
	{
		if(collided)
			break;

		int maxWidth = GRID_WIDTH;
		if(y % 2 != 0) // odd rows have GRID_WIDTH -1 bubbles
		{
			maxWidth -= 1;
		}

		for(int x = 0; x < maxWidth; x++)
		{
			Bubble* bubble = m_pBubbles[x][y];

			if((y != 0 && bubble->getType() == EMPTY) || bubble->getFalling())
				continue;

			// NOT BUBBLE_RADIUS * 2 because it would be two accurate - allows better gameplay
			if(ccpDistance(bubble->getPosition(), playerBubblePosition) < (BUBBLE_RADIUS * 1.5f)) 
			{
				collidedX = x;
				collidedY = y;
				collided = true;
				break;
			}
		}
	}

	if(collided)
	{
		int selectedIndexX = 0;
		int selectedIndexY = 0;

		// Find a place to put the bubble
		// selectedIndexX & selectedIndexY hold the selected position
		placeInClosestEmptySlot(playerBubble, collidedX, collidedY, selectedIndexX, selectedIndexY);

		int count = 0;
		// check for matching bubbles
		checkMatchingBubbles(selectedIndexX, selectedIndexY, playerBubble->getType(), count);

		// If we found 3 or more matches
		if(count > 2)
		{
			// Mark all connected bubbles starting from [0][0]
			checkConnectedBubbles();

			// Drop any bubbles that are not marked
			dropBubbles();
		}

		return true;
	}

	return false;
}
Exemple #28
0
inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
{
  if (node == 0) return;
  if (ind == "") cerr << "####################################################################\n";
  if (dynamic_cast<Bubble*>(node)) {
    Bubble* bubble = dynamic_cast<Bubble*>(node);
    cerr << ind << "Bubble " << bubble << " " << bubble->tabs() << endl;
  } else if (dynamic_cast<At_Root_Block*>(node)) {
    At_Root_Block* root_block = dynamic_cast<At_Root_Block*>(node);
    cerr << ind << "At_Root_Block " << root_block << " " << root_block->tabs() << endl;
    if (root_block->block()) for(auto i : root_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Selector_List*>(node)) {
    Selector_List* selector = dynamic_cast<Selector_List*>(node);

    cerr << ind << "Selector_List " << selector
      << " [block:" << selector->last_block() << "]"
      << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : "")
      << " [@media:" << selector->media_block() << "]"
      << (selector->is_optional() ? " [is_optional]": " -")
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << endl;

    for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }

//  } else if (dynamic_cast<Expression*>(node)) {
//    Expression* expression = dynamic_cast<Expression*>(node);
//    cerr << ind << "Expression " << expression << " " << expression->concrete_type() << endl;

  } else if (dynamic_cast<Parent_Selector*>(node)) {
    Parent_Selector* selector = dynamic_cast<Parent_Selector*>(node);
    cerr << ind << "Parent_Selector " << selector;
    cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
    debug_ast(selector->selector(), ind + "->", env);

  } else if (dynamic_cast<Complex_Selector*>(node)) {
    Complex_Selector* selector = dynamic_cast<Complex_Selector*>(node);
    cerr << ind << "Complex_Selector " << selector
      << " [block:" << selector->last_block() << "]"
      << " [weight:" << longToHex(selector->specificity()) << "]"
      << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : "")
      << " [@media:" << selector->media_block() << "]"
      << (selector->is_optional() ? " [is_optional]": " -")
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -") << " -> ";
      switch (selector->combinator()) {
        case Complex_Selector::PARENT_OF:   cerr << "{>}"; break;
        case Complex_Selector::PRECEDES:    cerr << "{~}"; break;
        case Complex_Selector::ADJACENT_TO: cerr << "{+}"; break;
        case Complex_Selector::ANCESTOR_OF: cerr << "{ }"; break;
      }
    cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
    debug_ast(selector->head(), ind + " ", env);
    debug_ast(selector->tail(), ind + "-", env);
  } else if (dynamic_cast<Compound_Selector*>(node)) {
    Compound_Selector* selector = dynamic_cast<Compound_Selector*>(node);
    cerr << ind << "Compound_Selector " << selector;
    cerr << " [block:" << selector->last_block() << "]";
    cerr << " [weight:" << longToHex(selector->specificity()) << "]";
    // cerr << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : "");
    cerr << " [@media:" << selector->media_block() << "]";
    cerr << (selector->is_optional() ? " [is_optional]": " -");
    cerr << (selector->has_line_break() ? " [line-break]": " -");
    cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
    for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Propset*>(node)) {
    Propset* selector = dynamic_cast<Propset*>(node);
    cerr << ind << "Propset " << selector << " " << selector->tabs() << endl;
    if (selector->block()) for(auto i : selector->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Wrapped_Selector*>(node)) {
    Wrapped_Selector* selector = dynamic_cast<Wrapped_Selector*>(node);
    cerr << ind << "Wrapped_Selector " << selector << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl;
    debug_ast(selector->selector(), ind + " () ", env);
  } else if (dynamic_cast<Pseudo_Selector*>(node)) {
    Pseudo_Selector* selector = dynamic_cast<Pseudo_Selector*>(node);
    cerr << ind << "Pseudo_Selector " << selector << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl;
    debug_ast(selector->expression(), ind + " <= ", env);
  } else if (dynamic_cast<Attribute_Selector*>(node)) {
    Attribute_Selector* selector = dynamic_cast<Attribute_Selector*>(node);
    cerr << ind << "Attribute_Selector " << selector << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl;
    debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env);
  } else if (dynamic_cast<Selector_Qualifier*>(node)) {
    Selector_Qualifier* selector = dynamic_cast<Selector_Qualifier*>(node);
    cerr << ind << "Selector_Qualifier " << selector << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl;
  } else if (dynamic_cast<Type_Selector*>(node)) {
    Type_Selector* selector = dynamic_cast<Type_Selector*>(node);
    cerr << ind << "Type_Selector " << selector << " <<" << selector->name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") <<
      " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << endl;
  } else if (dynamic_cast<Selector_Placeholder*>(node)) {

    Selector_Placeholder* selector = dynamic_cast<Selector_Placeholder*>(node);
    cerr << ind << "Selector_Placeholder [" << selector->name() << "] " << selector
      << " [block:" << selector->last_block() << "]"
      << " [@media:" << selector->media_block() << "]"
      << (selector->is_optional() ? " [is_optional]": " -")
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << endl;

  } else if (dynamic_cast<Selector_Reference*>(node)) {
    Selector_Reference* selector = dynamic_cast<Selector_Reference*>(node);
    cerr << ind << "Selector_Reference " << selector << " @ref " << selector->selector() << endl;
  } else if (dynamic_cast<Simple_Selector*>(node)) {
    Simple_Selector* selector = dynamic_cast<Simple_Selector*>(node);
    cerr << ind << "Simple_Selector " << selector << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << endl;

  } else if (dynamic_cast<Selector_Schema*>(node)) {
    Selector_Schema* selector = dynamic_cast<Selector_Schema*>(node);
    cerr << ind << "Selector_Schema " << selector
      << " [block:" << selector->last_block() << "]"
      << (selector->last_block() && selector->last_block()->is_root() ? " [root]" : "")
      << " [@media:" << selector->media_block() << "]"
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << endl;

    debug_ast(selector->contents(), ind + " ");
    // for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }

  } else if (dynamic_cast<Selector*>(node)) {
    Selector* selector = dynamic_cast<Selector*>(node);
    cerr << ind << "Selector " << selector
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << endl;

  } else if (dynamic_cast<Media_Query_Expression*>(node)) {
    Media_Query_Expression* block = dynamic_cast<Media_Query_Expression*>(node);
    cerr << ind << "Media_Query_Expression " << block
      << (block->is_interpolated() ? " [is_interpolated]": " -")
    << endl;
    debug_ast(block->feature(), ind + " f) ");
    debug_ast(block->value(), ind + " v) ");

  } else if (dynamic_cast<Media_Query*>(node)) {
    Media_Query* block = dynamic_cast<Media_Query*>(node);
    cerr << ind << "Media_Query " << block
      << (block->is_negated() ? " [is_negated]": " -")
      << (block->is_restricted() ? " [is_restricted]": " -")
    << endl;
    debug_ast(block->media_type(), ind + " ");
    for(auto i : block->elements()) { debug_ast(i, ind + " ", env); }

  } else if (dynamic_cast<Media_Block*>(node)) {
    Media_Block* block = dynamic_cast<Media_Block*>(node);
    cerr << ind << "Media_Block " << block << " " << block->tabs() << endl;
    debug_ast(block->media_queries(), ind + " =@ ");
    debug_ast(block->selector(), ind + " -@ ");
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Feature_Block*>(node)) {
    Feature_Block* block = dynamic_cast<Feature_Block*>(node);
    cerr << ind << "Feature_Block " << block << " " << block->tabs() << endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Block*>(node)) {
    Block* root_block = dynamic_cast<Block*>(node);
    cerr << ind << "Block " << root_block << " " << root_block->tabs() << endl;
    if (root_block->block()) for(auto i : root_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Warning*>(node)) {
    Warning* block = dynamic_cast<Warning*>(node);
    cerr << ind << "Warning " << block << " " << block->tabs() << endl;
  } else if (dynamic_cast<Error*>(node)) {
    Error* block = dynamic_cast<Error*>(node);
    cerr << ind << "Error " << block << " " << block->tabs() << endl;
  } else if (dynamic_cast<Debug*>(node)) {
    Debug* block = dynamic_cast<Debug*>(node);
    cerr << ind << "Debug " << block << " " << block->tabs() << endl;
  } else if (dynamic_cast<Comment*>(node)) {
    Comment* block = dynamic_cast<Comment*>(node);
    cerr << ind << "Comment " << block << " " << block->tabs() <<
      " <" << prettyprint(block->pstate().token.ws_before()) << ">" << endl;
    debug_ast(block->text(), ind + "// ", env);
  } else if (dynamic_cast<If*>(node)) {
    If* block = dynamic_cast<If*>(node);
    cerr << ind << "If " << block << " " << block->tabs() << endl;
  } else if (dynamic_cast<Return*>(node)) {
    Return* block = dynamic_cast<Return*>(node);
    cerr << ind << "Return " << block << " " << block->tabs() << endl;
  } else if (dynamic_cast<Extension*>(node)) {
    Extension* block = dynamic_cast<Extension*>(node);
    cerr << ind << "Extension " << block << " " << block->tabs() << endl;
    debug_ast(block->selector(), ind + "-> ", env);
  } else if (dynamic_cast<Content*>(node)) {
    Content* block = dynamic_cast<Content*>(node);
    cerr << ind << "Content " << block << " " << block->tabs() << endl;
  } else if (dynamic_cast<Import_Stub*>(node)) {
    Import_Stub* block = dynamic_cast<Import_Stub*>(node);
    cerr << ind << "Import_Stub " << block << " " << block->tabs() << endl;
  } else if (dynamic_cast<Import*>(node)) {
    Import* block = dynamic_cast<Import*>(node);
    cerr << ind << "Import " << block << " " << block->tabs() << endl;
    // vector<string>         files_;
    for (auto imp : block->urls()) debug_ast(imp, "@ ", env);
  } else if (dynamic_cast<Assignment*>(node)) {
    Assignment* block = dynamic_cast<Assignment*>(node);
    cerr << ind << "Assignment " << block << " <<" << block->variable() << ">> " << block->tabs() << endl;
    debug_ast(block->value(), ind + "=", env);
  } else if (dynamic_cast<Declaration*>(node)) {
    Declaration* block = dynamic_cast<Declaration*>(node);
    cerr << ind << "Declaration " << block << " " << block->tabs() << endl;
    debug_ast(block->property(), ind + " prop: ", env);
    debug_ast(block->value(), ind + " value: ", env);
  } else if (dynamic_cast<Keyframe_Rule*>(node)) {
    Keyframe_Rule* has_block = dynamic_cast<Keyframe_Rule*>(node);
    cerr << ind << "Keyframe_Rule " << has_block << " " << has_block->tabs() << endl;
    if (has_block->selector()) debug_ast(has_block->selector(), ind + "@");
    if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<At_Rule*>(node)) {
    At_Rule* block = dynamic_cast<At_Rule*>(node);
    cerr << ind << "At_Rule " << block << " [" << block->keyword() << "] " << block->tabs() << endl;
    debug_ast(block->value(), ind + "+", env);
    debug_ast(block->selector(), ind + "~", env);
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Each*>(node)) {
    Each* block = dynamic_cast<Each*>(node);
    cerr << ind << "Each " << block << " " << block->tabs() << endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<For*>(node)) {
    For* block = dynamic_cast<For*>(node);
    cerr << ind << "For " << block << " " << block->tabs() << endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<While*>(node)) {
    While* block = dynamic_cast<While*>(node);
    cerr << ind << "While " << block << " " << block->tabs() << endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Definition*>(node)) {
    Definition* block = dynamic_cast<Definition*>(node);
    cerr << ind << "Definition " << block << " " << block->tabs() << endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Mixin_Call*>(node)) {
    Mixin_Call* block = dynamic_cast<Mixin_Call*>(node);
    cerr << ind << "Mixin_Call " << block << " " << block->tabs() << endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Ruleset*>(node)) {
    Ruleset* ruleset = dynamic_cast<Ruleset*>(node);
    cerr << ind << "Ruleset " << ruleset << " " << ruleset->tabs() << endl;
    debug_ast(ruleset->selector(), ind + " ");
    if (ruleset->block()) for(auto i : ruleset->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Block*>(node)) {
    Block* block = dynamic_cast<Block*>(node);
    cerr << ind << "Block " << block << " " << block->tabs() << endl;
    for(auto i : block->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Textual*>(node)) {
    Textual* expression = dynamic_cast<Textual*>(node);
    cerr << ind << "Textual ";
    if (expression->type() == Textual::NUMBER) cerr << " [NUMBER]";
    else if (expression->type() == Textual::PERCENTAGE) cerr << " [PERCENTAGE]";
    else if (expression->type() == Textual::DIMENSION) cerr << " [DIMENSION]";
    else if (expression->type() == Textual::HEX) cerr << " [HEX]";
    cerr << expression << " [" << expression->value() << "]" << endl;
  } else if (dynamic_cast<Variable*>(node)) {
    Variable* expression = dynamic_cast<Variable*>(node);
    cerr << ind << "Variable " << expression << " [" << expression->name() << "]" << endl;
    string name(expression->name());
    if (env && env->has(name)) debug_ast(static_cast<Expression*>((*env)[name]), ind + " -> ", env);
  } else if (dynamic_cast<Function_Call_Schema*>(node)) {
    Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node);
    cerr << ind << "Function_Call_Schema " << expression << "]" << endl;
    debug_ast(expression->name(), ind + "name: ", env);
    debug_ast(expression->arguments(), ind + " args: ", env);
  } else if (dynamic_cast<Function_Call*>(node)) {
    Function_Call* expression = dynamic_cast<Function_Call*>(node);
    cerr << ind << "Function_Call " << expression << " [" << expression->name() << "]" << endl;
    debug_ast(expression->arguments(), ind + " args: ", env);
  } else if (dynamic_cast<Arguments*>(node)) {
    Arguments* expression = dynamic_cast<Arguments*>(node);
    cerr << ind << "Arguments " << expression << "]" << endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Argument*>(node)) {
    Argument* expression = dynamic_cast<Argument*>(node);
    cerr << ind << "Argument " << expression << " [" << expression->value() << "]" << endl;
    debug_ast(expression->value(), ind + " value: ", env);
  } else if (dynamic_cast<Unary_Expression*>(node)) {
    Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node);
    cerr << ind << "Unary_Expression " << expression << " [" << expression->type() << "]" << endl;
    debug_ast(expression->operand(), ind + " operand: ", env);
  } else if (dynamic_cast<Binary_Expression*>(node)) {
    Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node);
    cerr << ind << "Binary_Expression " << expression << " [" << expression->type() << "]" << endl;
    debug_ast(expression->left(), ind + " left:  ", env);
    debug_ast(expression->right(), ind + " right: ", env);
  } else if (dynamic_cast<Map*>(node)) {
    Map* expression = dynamic_cast<Map*>(node);
    cerr << ind << "Map " << expression << " [Hashed]" << endl;
  } else if (dynamic_cast<List*>(node)) {
    List* expression = dynamic_cast<List*>(node);
    cerr << ind << "List " << expression << " (" << expression->length() << ") " <<
      (expression->separator() == Sass::List::Separator::COMMA ? "Comma " : "Space ") <<
      " [delayed: " << expression->is_delayed() << "] " <<
      " [interpolant: " << expression->is_interpolant() << "] " <<
      endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Content*>(node)) {
    Content* expression = dynamic_cast<Content*>(node);
    cerr << ind << "Content " << expression << " [Statement]" << endl;
  } else if (dynamic_cast<Boolean*>(node)) {
    Boolean* expression = dynamic_cast<Boolean*>(node);
    cerr << ind << "Boolean " << expression << " [" << expression->value() << "]" << endl;
  } else if (dynamic_cast<Color*>(node)) {
    Color* expression = dynamic_cast<Color*>(node);
    cerr << ind << "Color " << expression << " [" << expression->r() << ":"  << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << endl;
  } else if (dynamic_cast<Number*>(node)) {
    Number* expression = dynamic_cast<Number*>(node);
    cerr << ind << "Number " << expression << " [" << expression->value() << expression->unit() << "]" << endl;
  } else if (dynamic_cast<String_Quoted*>(node)) {
    String_Quoted* expression = dynamic_cast<String_Quoted*>(node);
    cerr << ind << "String_Quoted : " << expression << " [" << prettyprint(expression->value()) << "]" <<
      (expression->is_delayed() ? " {delayed}" : "") <<
      (expression->sass_fix_1291() ? " {sass_fix_1291}" : "") <<
      (expression->quote_mark() != 0 ? " {qm:" + string(1, expression->quote_mark()) + "}" : "") <<
      " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
  } else if (dynamic_cast<String_Constant*>(node)) {
    String_Constant* expression = dynamic_cast<String_Constant*>(node);
    cerr << ind << "String_Constant : " << expression << " [" << prettyprint(expression->value()) << "]" <<
      (expression->is_delayed() ? " {delayed}" : "") <<
      (expression->sass_fix_1291() ? " {sass_fix_1291}" : "") <<
      " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
  } else if (dynamic_cast<String_Schema*>(node)) {
    String_Schema* expression = dynamic_cast<String_Schema*>(node);
    cerr << ind << "String_Schema " << expression << " " << expression->concrete_type() <<
      (expression->has_interpolants() ? " {has_interpolants}" : "") <<
      endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<String*>(node)) {
    String* expression = dynamic_cast<String*>(node);
    cerr << ind << "String " << expression << expression->concrete_type() <<
      " " << (expression->sass_fix_1291() ? "{sass_fix_1291}" : "") <<
      endl;
  } else if (dynamic_cast<Expression*>(node)) {
    Expression* expression = dynamic_cast<Expression*>(node);
    cerr << ind << "Expression " << expression;
    switch (expression->concrete_type()) {
      case Expression::Concrete_Type::NONE: cerr << " [NONE]"; break;
      case Expression::Concrete_Type::BOOLEAN: cerr << " [BOOLEAN]"; break;
      case Expression::Concrete_Type::NUMBER: cerr << " [NUMBER]"; break;
      case Expression::Concrete_Type::COLOR: cerr << " [COLOR]"; break;
      case Expression::Concrete_Type::STRING: cerr << " [STRING]"; break;
      case Expression::Concrete_Type::LIST: cerr << " [LIST]"; break;
      case Expression::Concrete_Type::MAP: cerr << " [MAP]"; break;
      case Expression::Concrete_Type::SELECTOR: cerr << " [SELECTOR]"; break;
      case Expression::Concrete_Type::NULL_VAL: cerr << " [NULL_VAL]"; break;
      case Expression::Concrete_Type::NUM_TYPES: cerr << " [NUM_TYPES]"; break;
    }
    cerr << endl;
  } else if (dynamic_cast<Has_Block*>(node)) {
    Has_Block* has_block = dynamic_cast<Has_Block*>(node);
    cerr << ind << "Has_Block " << has_block << " " << has_block->tabs() << endl;
    if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Statement*>(node)) {
    Statement* statement = dynamic_cast<Statement*>(node);
    cerr << ind << "Statement " << statement << " " << statement->tabs() << endl;
  }

  if (ind == "") cerr << "####################################################################\n";
}
Exemple #29
0
  Statement* Cssize::debubble(Block* children, Statement* parent)
  {
    Has_Block* previous_parent = 0;
    std::vector<std::pair<bool, Block*>> baz = slice_by_bubble(children);
    Block* result = SASS_MEMORY_NEW(ctx.mem, Block, children->pstate());

    for (size_t i = 0, L = baz.size(); i < L; ++i) {
      bool is_bubble = baz[i].first;
      Block* slice = baz[i].second;

      if (!is_bubble) {
        if (!parent) {
          *result << slice;
        }
        else if (previous_parent) {
          *previous_parent->block() += slice;
        }
        else {
          previous_parent = static_cast<Has_Block*>(shallow_copy(parent));
          previous_parent->tabs(parent->tabs());

          Has_Block* new_parent = static_cast<Has_Block*>(shallow_copy(parent));
          new_parent->block(slice);
          new_parent->tabs(parent->tabs());

          *result << new_parent;
        }
        continue;
      }

      Block* wrapper_block = SASS_MEMORY_NEW(ctx.mem, Block,
                                             children->block()->pstate(),
                                             children->block()->length(),
                                             children->block()->is_root());

      for (size_t j = 0, K = slice->length(); j < K; ++j)
      {
        Statement* ss = 0;
        Bubble* b = static_cast<Bubble*>((*slice)[j]);

        if (!parent ||
            parent->statement_type() != Statement::MEDIA ||
            b->node()->statement_type() != Statement::MEDIA ||
            static_cast<Media_Block*>(b->node())->media_queries() == static_cast<Media_Block*>(parent)->media_queries())
        {
          ss = b->node();
        }
        else
        {
          List* mq = merge_media_queries(static_cast<Media_Block*>(b->node()), static_cast<Media_Block*>(parent));
          if (!mq->length()) continue;
          static_cast<Media_Block*>(b->node())->media_queries(mq);
          ss = b->node();
        }

        if (!ss) continue;

        ss->tabs(ss->tabs() + b->tabs());
        ss->group_end(b->group_end());

        if (!ss) continue;

        Block* bb = SASS_MEMORY_NEW(ctx.mem, Block,
                                    children->block()->pstate(),
                                    children->block()->length(),
                                    children->block()->is_root());
        *bb << ss->perform(this);
        Statement* wrapper = flatten(bb);
        *wrapper_block << wrapper;

        if (wrapper->block()->length()) {
          previous_parent = 0;
        }
      }

      if (wrapper_block) {
        *result << flatten(wrapper_block);
      }
    }

    return flatten(result);
  }
Exemple #30
0
inline void debug_ast(AST_Node* node, std::string ind, Env* env)
{
  if (node == 0) return;
  if (ind == "") std::cerr << "####################################################################\n";
  if (dynamic_cast<Bubble*>(node)) {
    Bubble* bubble = dynamic_cast<Bubble*>(node);
    std::cerr << ind << "Bubble " << bubble;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << bubble->tabs();
    std::cerr << std::endl;
  } else if (dynamic_cast<At_Root_Block*>(node)) {
    At_Root_Block* root_block = dynamic_cast<At_Root_Block*>(node);
    std::cerr << ind << "At_Root_Block " << root_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << root_block->tabs();
    std::cerr << std::endl;
    debug_ast(root_block->expression(), ind + ":", env);
    debug_ast(root_block->block(), ind + " ", env);
  } else if (dynamic_cast<Selector_List*>(node)) {
    Selector_List* selector = dynamic_cast<Selector_List*>(node);
    std::cerr << ind << "Selector_List " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " [@media:" << selector->media_block() << "]";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;

    for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }

//  } else if (dynamic_cast<Expression*>(node)) {
//    Expression* expression = dynamic_cast<Expression*>(node);
//    std::cerr << ind << "Expression " << expression << " " << expression->concrete_type() << std::endl;

  } else if (dynamic_cast<Parent_Selector*>(node)) {
    Parent_Selector* selector = dynamic_cast<Parent_Selector*>(node);
    std::cerr << ind << "Parent_Selector " << selector;
//    if (selector->not_selector()) cerr << " [in_declaration]";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
//    debug_ast(selector->selector(), ind + "->", env);

  } else if (dynamic_cast<Complex_Selector*>(node)) {
    Complex_Selector* selector = dynamic_cast<Complex_Selector*>(node);
    std::cerr << ind << "Complex_Selector " << selector
      << " (" << pstate_source_position(node) << ")"
      << " <" << selector->hash() << ">"
      << " [weight:" << longToHex(selector->specificity()) << "]"
      << " [@media:" << selector->media_block() << "]"
      << (selector->is_optional() ? " [is_optional]": " -")
      << (selector->has_parent_ref() ? " [has parent]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
      << (selector->has_line_break() ? " [line-break]": " -")
      << " -- ";
      std::string del;
      switch (selector->combinator()) {
        case Complex_Selector::PARENT_OF:   del = ">"; break;
        case Complex_Selector::PRECEDES:    del = "~"; break;
        case Complex_Selector::ADJACENT_TO: del = "+"; break;
        case Complex_Selector::ANCESTOR_OF: del = " "; break;
        case Complex_Selector::REFERENCE:   del = "//"; break;
      }
      // if (del = "/") del += selector->reference()->perform(&to_string) + "/";
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
    debug_ast(selector->head(), ind + " " /* + "[" + del + "]" */, env);
    if (selector->tail()) {
      debug_ast(selector->tail(), ind + "{" + del + "}", env);
    } else if(del != " ") {
      std::cerr << ind << " |" << del << "| {trailing op}" << std::endl;
    }
    SourcesSet set = selector->sources();
    // debug_sources_set(set, ind + "  @--> ");
  } else if (dynamic_cast<Compound_Selector*>(node)) {
    Compound_Selector* selector = dynamic_cast<Compound_Selector*>(node);
    std::cerr << ind << "Compound_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " [weight:" << longToHex(selector->specificity()) << "]";
    std::cerr << " [@media:" << selector->media_block() << "]";
    std::cerr << (selector->extended() ? " [extended]": " -");
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
    for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Propset*>(node)) {
    Propset* selector = dynamic_cast<Propset*>(node);
    std::cerr << ind << "Propset " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << selector->tabs() << std::endl;
    if (selector->block()) for(auto i : selector->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Wrapped_Selector*>(node)) {
    Wrapped_Selector* selector = dynamic_cast<Wrapped_Selector*>(node);
    std::cerr << ind << "Wrapped_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
    debug_ast(selector->selector(), ind + " () ", env);
  } else if (dynamic_cast<Pseudo_Selector*>(node)) {
    Pseudo_Selector* selector = dynamic_cast<Pseudo_Selector*>(node);
    std::cerr << ind << "Pseudo_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
    debug_ast(selector->expression(), ind + " <= ", env);
  } else if (dynamic_cast<Attribute_Selector*>(node)) {
    Attribute_Selector* selector = dynamic_cast<Attribute_Selector*>(node);
    std::cerr << ind << "Attribute_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
    debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env);
  } else if (dynamic_cast<Selector_Qualifier*>(node)) {
    Selector_Qualifier* selector = dynamic_cast<Selector_Qualifier*>(node);
    std::cerr << ind << "Selector_Qualifier " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << std::endl;
  } else if (dynamic_cast<Type_Selector*>(node)) {
    Type_Selector* selector = dynamic_cast<Type_Selector*>(node);
    std::cerr << ind << "Type_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <" << selector->hash() << ">";
    std::cerr << " <<" << selector->ns_name() << ">>";
    std::cerr << (selector->is_optional() ? " [is_optional]": " -");
    std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
    std::cerr << (selector->has_line_break() ? " [line-break]": " -");
    std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
    std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">";
    std::cerr << std::endl;
  } else if (dynamic_cast<Selector_Placeholder*>(node)) {

    Selector_Placeholder* selector = dynamic_cast<Selector_Placeholder*>(node);
    std::cerr << ind << "Selector_Placeholder [" << selector->ns_name() << "] " << selector
      << " <" << selector->hash() << ">"
      << " [@media:" << selector->media_block() << "]"
      << (selector->is_optional() ? " [is_optional]": " -")
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << std::endl;

  } else if (dynamic_cast<Simple_Selector*>(node)) {
    Simple_Selector* selector = dynamic_cast<Simple_Selector*>(node);
    std::cerr << ind << "Simple_Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl;

  } else if (dynamic_cast<Selector_Schema*>(node)) {
    Selector_Schema* selector = dynamic_cast<Selector_Schema*>(node);
    std::cerr << ind << "Selector_Schema " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")"
      << (selector->at_root() && selector->at_root() ? " [@ROOT]" : "")
      << " [@media:" << selector->media_block() << "]"
      << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << std::endl;

    debug_ast(selector->contents(), ind + " ");
    // for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); }

  } else if (dynamic_cast<Selector*>(node)) {
    Selector* selector = dynamic_cast<Selector*>(node);
    std::cerr << ind << "Selector " << selector;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (selector->has_line_break() ? " [line-break]": " -")
      << (selector->has_line_feed() ? " [line-feed]": " -")
    << std::endl;

  } else if (dynamic_cast<Media_Query_Expression*>(node)) {
    Media_Query_Expression* block = dynamic_cast<Media_Query_Expression*>(node);
    std::cerr << ind << "Media_Query_Expression " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (block->is_interpolated() ? " [is_interpolated]": " -")
    << std::endl;
    debug_ast(block->feature(), ind + " feature) ");
    debug_ast(block->value(), ind + " value) ");

  } else if (dynamic_cast<Media_Query*>(node)) {
    Media_Query* block = dynamic_cast<Media_Query*>(node);
    std::cerr << ind << "Media_Query " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << (block->is_negated() ? " [is_negated]": " -")
      << (block->is_restricted() ? " [is_restricted]": " -")
    << std::endl;
    debug_ast(block->media_type(), ind + " ");
    for(auto i : block->elements()) { debug_ast(i, ind + " ", env); }

  } else if (dynamic_cast<Media_Block*>(node)) {
    Media_Block* block = dynamic_cast<Media_Block*>(node);
    std::cerr << ind << "Media_Block " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->media_queries(), ind + " =@ ");
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Supports_Block*>(node)) {
    Supports_Block* block = dynamic_cast<Supports_Block*>(node);
    std::cerr << ind << "Supports_Block " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->condition(), ind + " =@ ");
  } else if (dynamic_cast<Supports_Operator*>(node)) {
    Supports_Operator* block = dynamic_cast<Supports_Operator*>(node);
    std::cerr << ind << "Supports_Operator " << block;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << std::endl;
    debug_ast(block->left(), ind + " left) ");
    debug_ast(block->right(), ind + " right) ");
  } else if (dynamic_cast<Supports_Negation*>(node)) {
    Supports_Negation* block = dynamic_cast<Supports_Negation*>(node);
    std::cerr << ind << "Supports_Negation " << block;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << std::endl;
    debug_ast(block->condition(), ind + " condition) ");
  } else if (dynamic_cast<Supports_Declaration*>(node)) {
    Supports_Declaration* block = dynamic_cast<Supports_Declaration*>(node);
    std::cerr << ind << "Supports_Declaration " << block;
    std::cerr << " (" << pstate_source_position(node) << ")"
    << std::endl;
    debug_ast(block->feature(), ind + " feature) ");
    debug_ast(block->value(), ind + " value) ");
  } else if (dynamic_cast<Block*>(node)) {
    Block* root_block = dynamic_cast<Block*>(node);
    std::cerr << ind << "Block " << root_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    if (root_block->is_root()) std::cerr << " [root]";
    std::cerr << " " << root_block->tabs() << std::endl;
    if (root_block->block()) for(auto i : root_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Warning*>(node)) {
    Warning* block = dynamic_cast<Warning*>(node);
    std::cerr << ind << "Warning " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Error*>(node)) {
    Error* block = dynamic_cast<Error*>(node);
    std::cerr << ind << "Error " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Debug*>(node)) {
    Debug* block = dynamic_cast<Debug*>(node);
    std::cerr << ind << "Debug " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Comment*>(node)) {
    Comment* block = dynamic_cast<Comment*>(node);
    std::cerr << ind << "Comment " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() <<
      " <" << prettyprint(block->pstate().token.ws_before()) << ">" << std::endl;
    debug_ast(block->text(), ind + "// ", env);
  } else if (dynamic_cast<If*>(node)) {
    If* block = dynamic_cast<If*>(node);
    std::cerr << ind << "If " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->predicate(), ind + " = ");
    debug_ast(block->block(), ind + " <>");
    debug_ast(block->alternative(), ind + " ><");
  } else if (dynamic_cast<Return*>(node)) {
    Return* block = dynamic_cast<Return*>(node);
    std::cerr << ind << "Return " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Extension*>(node)) {
    Extension* block = dynamic_cast<Extension*>(node);
    std::cerr << ind << "Extension " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->selector(), ind + "-> ", env);
  } else if (dynamic_cast<Content*>(node)) {
    Content* block = dynamic_cast<Content*>(node);
    std::cerr << ind << "Content " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Import_Stub*>(node)) {
    Import_Stub* block = dynamic_cast<Import_Stub*>(node);
    std::cerr << ind << "Import_Stub " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
  } else if (dynamic_cast<Import*>(node)) {
    Import* block = dynamic_cast<Import*>(node);
    std::cerr << ind << "Import " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->media_queries(), ind + " @ ");
    // std::vector<std::string>         files_;
    for (auto imp : block->urls()) debug_ast(imp, "@ ", env);
  } else if (dynamic_cast<Assignment*>(node)) {
    Assignment* block = dynamic_cast<Assignment*>(node);
    std::cerr << ind << "Assignment " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " <<" << block->variable() << ">> " << block->tabs() << std::endl;
    debug_ast(block->value(), ind + "=", env);
  } else if (dynamic_cast<Declaration*>(node)) {
    Declaration* block = dynamic_cast<Declaration*>(node);
    std::cerr << ind << "Declaration " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->property(), ind + " prop: ", env);
    debug_ast(block->value(), ind + " value: ", env);
  } else if (dynamic_cast<Keyframe_Rule*>(node)) {
    Keyframe_Rule* has_block = dynamic_cast<Keyframe_Rule*>(node);
    std::cerr << ind << "Keyframe_Rule " << has_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << has_block->tabs() << std::endl;
    if (has_block->selector()) debug_ast(has_block->selector(), ind + "@");
    if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<At_Rule*>(node)) {
    At_Rule* block = dynamic_cast<At_Rule*>(node);
    std::cerr << ind << "At_Rule " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << block->keyword() << "] " << block->tabs() << std::endl;
    debug_ast(block->selector(), ind + "~", env);
    debug_ast(block->value(), ind + "+", env);
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Each*>(node)) {
    Each* block = dynamic_cast<Each*>(node);
    std::cerr << ind << "Each " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<For*>(node)) {
    For* block = dynamic_cast<For*>(node);
    std::cerr << ind << "For " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<While*>(node)) {
    While* block = dynamic_cast<While*>(node);
    std::cerr << ind << "While " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << block->tabs() << std::endl;
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Definition*>(node)) {
    Definition* block = dynamic_cast<Definition*>(node);
    std::cerr << ind << "Definition " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [name: " << block->name() << "] ";
    std::cerr << " [type: " << (block->type() == Sass::Definition::Type::MIXIN ? "Mixin " : "Function ") << "] ";
    // this seems to lead to segfaults some times?
    // std::cerr << " [signature: " << block->signature() << "] ";
    std::cerr << " [native: " << block->native_function() << "] ";
    std::cerr << " " << block->tabs() << std::endl;
    debug_ast(block->parameters(), ind + " params: ", env);
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Mixin_Call*>(node)) {
    Mixin_Call* block = dynamic_cast<Mixin_Call*>(node);
    std::cerr << ind << "Mixin_Call " << block << " " << block->tabs();
    std::cerr << " [" <<  block->name() << "]";
    std::cerr << " [has_content: " << block->has_content() << "] " << std::endl;
    debug_ast(block->arguments(), ind + " args: ");
    if (block->block()) for(auto i : block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (Ruleset* ruleset = dynamic_cast<Ruleset*>(node)) {
    std::cerr << ind << "Ruleset " << ruleset;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [indent: " << ruleset->tabs() << "]";
    std::cerr << (ruleset->at_root() ? " [@ROOT]" : "");
    std::cerr << (ruleset->is_root() ? " [root]" : "");
    std::cerr << std::endl;
    debug_ast(ruleset->selector(), ind + ">");
    debug_ast(ruleset->block(), ind + " ");
  } else if (dynamic_cast<Block*>(node)) {
    Block* block = dynamic_cast<Block*>(node);
    std::cerr << ind << "Block " << block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [indent: " << block->tabs() << "]" << std::endl;
    for(auto i : block->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Textual*>(node)) {
    Textual* expression = dynamic_cast<Textual*>(node);
    std::cerr << ind << "Textual ";
    if (expression->type() == Textual::NUMBER) std::cerr << " [NUMBER]";
    else if (expression->type() == Textual::PERCENTAGE) std::cerr << " [PERCENTAGE]";
    else if (expression->type() == Textual::DIMENSION) std::cerr << " [DIMENSION]";
    else if (expression->type() == Textual::HEX) std::cerr << " [HEX]";
    std::cerr << expression << " [" << expression->value() << "]";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    std::cerr << std::endl;
  } else if (dynamic_cast<Variable*>(node)) {
    Variable* expression = dynamic_cast<Variable*>(node);
    std::cerr << ind << "Variable " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->name() << "]" << std::endl;
    std::string name(expression->name());
    if (env && env->has(name)) debug_ast(static_cast<Expression*>((*env)[name]), ind + " -> ", env);
  } else if (dynamic_cast<Function_Call_Schema*>(node)) {
    Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node);
    std::cerr << ind << "Function_Call_Schema " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << "" << std::endl;
    debug_ast(expression->name(), ind + "name: ", env);
    debug_ast(expression->arguments(), ind + " args: ", env);
  } else if (dynamic_cast<Function_Call*>(node)) {
    Function_Call* expression = dynamic_cast<Function_Call*>(node);
    std::cerr << ind << "Function_Call " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->name() << "]";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    std::cerr << std::endl;
    debug_ast(expression->arguments(), ind + " args: ", env);
  } else if (dynamic_cast<Arguments*>(node)) {
    Arguments* expression = dynamic_cast<Arguments*>(node);
    std::cerr << ind << "Arguments " << expression;
    if (expression->is_delayed()) std::cerr << " [delayed]";
    std::cerr << " (" << pstate_source_position(node) << ")";
    if (expression->has_named_arguments()) std::cerr << " [has_named_arguments]";
    if (expression->has_rest_argument()) std::cerr << " [has_rest_argument]";
    if (expression->has_keyword_argument()) std::cerr << " [has_keyword_argument]";
    std::cerr << std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Argument*>(node)) {
    Argument* expression = dynamic_cast<Argument*>(node);
    std::cerr << ind << "Argument " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->value() << "]";
    std::cerr << " [name: " << expression->name() << "] ";
    std::cerr << " [rest: " << expression->is_rest_argument() << "] ";
    std::cerr << " [keyword: " << expression->is_keyword_argument() << "] " << std::endl;
    debug_ast(expression->value(), ind + " value: ", env);
  } else if (dynamic_cast<Parameters*>(node)) {
    Parameters* expression = dynamic_cast<Parameters*>(node);
    std::cerr << ind << "Parameters " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [has_optional: " << expression->has_optional_parameters() << "] ";
    std::cerr << " [has_rest: " << expression->has_rest_parameter() << "] ";
    std::cerr << std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Parameter*>(node)) {
    Parameter* expression = dynamic_cast<Parameter*>(node);
    std::cerr << ind << "Parameter " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [name: " << expression->name() << "] ";
    std::cerr << " [default: " << expression->default_value() << "] ";
    std::cerr << " [rest: " << expression->is_rest_parameter() << "] " << std::endl;
  } else if (dynamic_cast<Unary_Expression*>(node)) {
    Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node);
    std::cerr << ind << "Unary_Expression " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->type() << "]" << std::endl;
    debug_ast(expression->operand(), ind + " operand: ", env);
  } else if (dynamic_cast<Binary_Expression*>(node)) {
    Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node);
    std::cerr << ind << "Binary_Expression " << expression;
    if (expression->is_interpolant()) std::cerr << " [is interpolant] ";
    if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
    if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
    std::cerr << " [delayed: " << expression->is_delayed() << "] ";
    std::cerr << " [ws_before: " << expression->op().ws_before << "] ";
    std::cerr << " [ws_after: " << expression->op().ws_after << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << expression->type_name() << "]" << std::endl;
    debug_ast(expression->left(), ind + " left:  ", env);
    debug_ast(expression->right(), ind + " right: ", env);
  } else if (dynamic_cast<Map*>(node)) {
    Map* expression = dynamic_cast<Map*>(node);
    std::cerr << ind << "Map " << expression;
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [Hashed]" << std::endl;
    for (auto i : expression->elements()) {
      debug_ast(i.first, ind + " key: ");
      debug_ast(i.second, ind + " val: ");
    }
  } else if (dynamic_cast<List*>(node)) {
    List* expression = dynamic_cast<List*>(node);
    std::cerr << ind << "List " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " (" << expression->length() << ") " <<
      (expression->separator() == SASS_COMMA ? "Comma " : expression->separator() == SASS_HASH ? "Map" : "Space ") <<
      " [delayed: " << expression->is_delayed() << "] " <<
      " [interpolant: " << expression->is_interpolant() << "] " <<
      " [arglist: " << expression->is_arglist() << "] " <<
      " [hash: " << expression->hash() << "] " <<
      std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Content*>(node)) {
    Content* expression = dynamic_cast<Content*>(node);
    std::cerr << ind << "Content " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [Statement]" << std::endl;
  } else if (dynamic_cast<Boolean*>(node)) {
    Boolean* expression = dynamic_cast<Boolean*>(node);
    std::cerr << ind << "Boolean " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " [" << expression->value() << "]" << std::endl;
  } else if (dynamic_cast<Color*>(node)) {
    Color* expression = dynamic_cast<Color*>(node);
    std::cerr << ind << "Color " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " [" << expression->r() << ":"  << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl;
  } else if (dynamic_cast<Number*>(node)) {
    Number* expression = dynamic_cast<Number*>(node);
    std::cerr << ind << "Number " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
    std::cerr << " [" << expression->value() << expression->unit() << "]" <<
      " [hash: " << expression->hash() << "] " <<
      std::endl;
  } else if (dynamic_cast<String_Quoted*>(node)) {
    String_Quoted* expression = dynamic_cast<String_Quoted*>(node);
    std::cerr << ind << "String_Quoted " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << prettyprint(expression->value()) << "]";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->sass_fix_1291()) std::cerr << " [sass_fix_1291]";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    if (expression->quote_mark()) std::cerr << " [quote_mark: " << expression->quote_mark() << "]";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
  } else if (dynamic_cast<String_Constant*>(node)) {
    String_Constant* expression = dynamic_cast<String_Constant*>(node);
    std::cerr << ind << "String_Constant " << expression;
    if (expression->concrete_type()) {
      std::cerr << " " << expression->concrete_type();
    }
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " [" << prettyprint(expression->value()) << "]";
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->sass_fix_1291()) std::cerr << " [sass_fix_1291]";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
  } else if (dynamic_cast<String_Schema*>(node)) {
    String_Schema* expression = dynamic_cast<String_Schema*>(node);
    std::cerr << ind << "String_Schema " << expression;
    std::cerr << " " << expression->concrete_type();
    if (expression->is_delayed()) std::cerr << " [delayed]";
    if (expression->is_interpolant()) std::cerr << " [is interpolant]";
    if (expression->has_interpolant()) std::cerr << " [has interpolant]";
    if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
    if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
    for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<String*>(node)) {
    String* expression = dynamic_cast<String*>(node);
    std::cerr << ind << "String " << expression;
    std::cerr << " " << expression->concrete_type();
    std::cerr << " (" << pstate_source_position(node) << ")";
    if (expression->sass_fix_1291()) std::cerr << " [sass_fix_1291]";
    if (expression->is_interpolant()) std::cerr << " [interpolant]";
    std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
  } else if (dynamic_cast<Expression*>(node)) {
    Expression* expression = dynamic_cast<Expression*>(node);
    std::cerr << ind << "Expression " << expression;
    std::cerr << " (" << pstate_source_position(node) << ")";
    switch (expression->concrete_type()) {
      case Expression::Concrete_Type::NONE: std::cerr << " [NONE]"; break;
      case Expression::Concrete_Type::BOOLEAN: std::cerr << " [BOOLEAN]"; break;
      case Expression::Concrete_Type::NUMBER: std::cerr << " [NUMBER]"; break;
      case Expression::Concrete_Type::COLOR: std::cerr << " [COLOR]"; break;
      case Expression::Concrete_Type::STRING: std::cerr << " [STRING]"; break;
      case Expression::Concrete_Type::LIST: std::cerr << " [LIST]"; break;
      case Expression::Concrete_Type::MAP: std::cerr << " [MAP]"; break;
      case Expression::Concrete_Type::SELECTOR: std::cerr << " [SELECTOR]"; break;
      case Expression::Concrete_Type::NULL_VAL: std::cerr << " [NULL_VAL]"; break;
      case Expression::Concrete_Type::C_WARNING: std::cerr << " [C_WARNING]"; break;
      case Expression::Concrete_Type::C_ERROR: std::cerr << " [C_ERROR]"; break;
      case Expression::Concrete_Type::NUM_TYPES: std::cerr << " [NUM_TYPES]"; break;
    }
    std::cerr << std::endl;
  } else if (dynamic_cast<Has_Block*>(node)) {
    Has_Block* has_block = dynamic_cast<Has_Block*>(node);
    std::cerr << ind << "Has_Block " << has_block;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << has_block->tabs() << std::endl;
    if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); }
  } else if (dynamic_cast<Statement*>(node)) {
    Statement* statement = dynamic_cast<Statement*>(node);
    std::cerr << ind << "Statement " << statement;
    std::cerr << " (" << pstate_source_position(node) << ")";
    std::cerr << " " << statement->tabs() << std::endl;
  }

  if (ind == "") std::cerr << "####################################################################\n";
}