static void DoStatement (void) /* Handle the 'do' statement */ { /* Get the loop control labels */ unsigned LoopLabel = GetLocalLabel (); unsigned BreakLabel = GetLocalLabel (); unsigned ContinueLabel = GetLocalLabel (); /* Skip the while token */ NextToken (); /* Add the loop to the loop stack */ AddLoop (BreakLabel, ContinueLabel); /* Define the loop label */ g_defcodelabel (LoopLabel); /* Parse the loop body */ Statement (0); /* Output the label for a continue */ g_defcodelabel (ContinueLabel); /* Parse the end condition */ Consume (TOK_WHILE, "`while' expected"); TestInParens (LoopLabel, 1); ConsumeSemi (); /* Define the break label */ g_defcodelabel (BreakLabel); /* Remove the loop from the loop stack */ DelLoop (); }
static void WhileStatement (void) /* Handle the 'while' statement */ { int PendingToken; CodeMark CondCodeStart; /* Start of condition evaluation code */ CodeMark CondCodeEnd; /* End of condition evaluation code */ CodeMark Here; /* "Here" location of code */ /* Get the loop control labels */ unsigned LoopLabel = GetLocalLabel (); unsigned BreakLabel = GetLocalLabel (); unsigned CondLabel = GetLocalLabel (); /* Skip the while token */ NextToken (); /* Add the loop to the loop stack. In case of a while loop, the condition ** label is used for continue statements. */ AddLoop (BreakLabel, CondLabel); /* We will move the code that evaluates the while condition to the end of ** the loop, so generate a jump here. */ g_jump (CondLabel); /* Remember the current position */ GetCodePos (&CondCodeStart); /* Emit the code position label */ g_defcodelabel (CondLabel); /* Test the loop condition */ TestInParens (LoopLabel, 1); /* Remember the end of the condition evaluation code */ GetCodePos (&CondCodeEnd); /* Define the head label */ g_defcodelabel (LoopLabel); /* Loop body */ Statement (&PendingToken); /* Move the test code here */ GetCodePos (&Here); MoveCode (&CondCodeStart, &CondCodeEnd, &Here); /* Exit label */ g_defcodelabel (BreakLabel); /* Eat remaining tokens that were delayed because of line info ** correctness */ SkipPending (PendingToken); /* Remove the loop from the loop stack */ DelLoop (); }
static void WhileStatement (void) /* Handle the 'while' statement */ { int PendingToken; /* Get the loop control labels */ unsigned LoopLabel = GetLocalLabel (); unsigned BreakLabel = GetLocalLabel (); /* Skip the while token */ NextToken (); /* Add the loop to the loop stack. In case of a while loop, the loop head * label is used for continue statements. */ AddLoop (BreakLabel, LoopLabel); /* Define the head label */ g_defcodelabel (LoopLabel); /* Test the loop condition */ TestInParens (BreakLabel, 0); /* Loop body */ Statement (&PendingToken); /* Jump back to loop top */ g_jump (LoopLabel); /* Exit label */ g_defcodelabel (BreakLabel); /* Eat remaining tokens that were delayed because of line info * correctness */ SkipPending (PendingToken); /* Remove the loop from the loop stack */ DelLoop (); }
bool ON_Hatch::Create( const ON_Plane& plane, const ON_SimpleArray<const ON_Curve*> loops, int pattern_index, double pattern_rotation, double pattern_scale) { if( loops.Count() < 1) return false; if( pattern_index < 0) return false; SetPlane( plane); for( int i = 0; i < loops.Count(); i++) { ON_HatchLoop* pLoop = new ON_HatchLoop; pLoop->SetCurve( *loops[i]); pLoop->SetType( i?ON_HatchLoop::ltInner:ON_HatchLoop::ltOuter); AddLoop( pLoop); } SetPatternIndex( pattern_index); SetPatternRotation( pattern_rotation); SetPatternScale( pattern_scale); return true; }
void SwitchStatement (void) /* Handle a switch statement for chars with a cmp cascade for the selector */ { ExprDesc SwitchExpr; /* Switch statement expression */ CodeMark CaseCodeStart; /* Start of code marker */ CodeMark SwitchCodeStart;/* Start of switch code */ CodeMark SwitchCodeEnd; /* End of switch code */ unsigned ExitLabel; /* Exit label */ unsigned SwitchCodeLabel;/* Label for the switch code */ int HaveBreak = 0; /* True if the last statement had a break */ int RCurlyBrace; /* True if last token is right curly brace */ SwitchCtrl* OldSwitch; /* Pointer to old switch control data */ SwitchCtrl SwitchData; /* New switch data */ /* Eat the "switch" token */ NextToken (); /* Read the switch expression and load it into the primary. It must have * integer type. */ ConsumeLParen (); Expression0 (&SwitchExpr); if (!IsClassInt (SwitchExpr.Type)) { Error ("Switch quantity is not an integer"); /* To avoid any compiler errors, make the expression a valid int */ ED_MakeConstAbsInt (&SwitchExpr, 1); } ConsumeRParen (); /* Add a jump to the switch code. This jump is usually unnecessary, * because the switch code will moved up just behind the switch * expression. However, in rare cases, there's a label at the end of * the switch expression. This label will not get moved, so the code * jumps around the switch code, and after moving the switch code, * things look really weird. If we add a jump here, we will never have * a label attached to the current code position, and the jump itself * will get removed by the optimizer if it is unnecessary. */ SwitchCodeLabel = GetLocalLabel (); g_jump (SwitchCodeLabel); /* Remember the current code position. We will move the switch code * to this position later. */ GetCodePos (&CaseCodeStart); /* Setup the control structure, save the old and activate the new one */ SwitchData.Nodes = NewCollection (); SwitchData.ExprType = UnqualifiedType (SwitchExpr.Type[0].C); SwitchData.Depth = SizeOf (SwitchExpr.Type); SwitchData.DefaultLabel = 0; OldSwitch = Switch; Switch = &SwitchData; /* Get the exit label for the switch statement */ ExitLabel = GetLocalLabel (); /* Create a loop so we may use break. */ AddLoop (ExitLabel, 0); /* Make sure a curly brace follows */ if (CurTok.Tok != TOK_LCURLY) { Error ("`{' expected"); } /* Parse the following statement, which will actually be a compound * statement because of the curly brace at the current input position */ HaveBreak = Statement (&RCurlyBrace); /* Check if we had any labels */ if (CollCount (SwitchData.Nodes) == 0 && SwitchData.DefaultLabel == 0) { Warning ("No case labels"); } /* If the last statement did not have a break, we may have an open * label (maybe from an if or similar). Emitting code and then moving * this code to the top will also move the label to the top which is * wrong. So if the last statement did not have a break (which would * carry the label), add a jump to the exit. If it is useless, the * optimizer will remove it later. */ if (!HaveBreak) { g_jump (ExitLabel); } /* Remember the current position */ GetCodePos (&SwitchCodeStart); /* Output the switch code label */ g_defcodelabel (SwitchCodeLabel); /* Generate code */ if (SwitchData.DefaultLabel == 0) { /* No default label, use switch exit */ SwitchData.DefaultLabel = ExitLabel; } g_switch (SwitchData.Nodes, SwitchData.DefaultLabel, SwitchData.Depth); /* Move the code to the front */ GetCodePos (&SwitchCodeEnd); MoveCode (&SwitchCodeStart, &SwitchCodeEnd, &CaseCodeStart); /* Define the exit label */ g_defcodelabel (ExitLabel); /* Exit the loop */ DelLoop (); /* Switch back to the enclosing switch statement if any */ Switch = OldSwitch; /* Free the case value tree */ FreeCaseNodeColl (SwitchData.Nodes); /* If the case statement was (correctly) terminated by a closing curly * brace, skip it now. */ if (RCurlyBrace) { NextToken (); } }
static void ForStatement (void) /* Handle a 'for' statement */ { ExprDesc lval1; ExprDesc lval3; int HaveIncExpr; CodeMark IncExprStart; CodeMark IncExprEnd; int PendingToken; /* Get several local labels needed later */ unsigned TestLabel = GetLocalLabel (); unsigned BreakLabel = GetLocalLabel (); unsigned IncLabel = GetLocalLabel (); unsigned BodyLabel = GetLocalLabel (); /* Skip the FOR token */ NextToken (); /* Add the loop to the loop stack. A continue jumps to the start of the ** the increment condition. */ AddLoop (BreakLabel, IncLabel); /* Skip the opening paren */ ConsumeLParen (); /* Parse the initializer expression */ if (CurTok.Tok != TOK_SEMI) { Expression0 (&lval1); } ConsumeSemi (); /* Label for the test expressions */ g_defcodelabel (TestLabel); /* Parse the test expression */ if (CurTok.Tok != TOK_SEMI) { Test (BodyLabel, 1); g_jump (BreakLabel); } else { g_jump (BodyLabel); } ConsumeSemi (); /* Remember the start of the increment expression */ GetCodePos (&IncExprStart); /* Label for the increment expression */ g_defcodelabel (IncLabel); /* Parse the increment expression */ HaveIncExpr = (CurTok.Tok != TOK_RPAREN); if (HaveIncExpr) { Expression0 (&lval3); } /* Jump to the test */ g_jump (TestLabel); /* Remember the end of the increment expression */ GetCodePos (&IncExprEnd); /* Skip the closing paren */ ConsumeRParen (); /* Loop body */ g_defcodelabel (BodyLabel); Statement (&PendingToken); /* If we had an increment expression, move the code to the bottom of ** the loop. In this case we don't need to jump there at the end of ** the loop body. */ if (HaveIncExpr) { CodeMark Here; GetCodePos (&Here); MoveCode (&IncExprStart, &IncExprEnd, &Here); } else { /* Jump back to the increment expression */ g_jump (IncLabel); } /* Skip a pending token if we have one */ SkipPending (PendingToken); /* Declare the break label */ g_defcodelabel (BreakLabel); /* Remove the loop from the loop stack */ DelLoop (); }
///////////////////////////////////////////////////////////////////////////////////////// // DESC: Востановление с диска альтернативных ветвей растров /// ARGS: rast - объект CSTR_rast // in - указатель на FILE // RETS: TRUE - успешно // FALSE - ошибка ///////////////////////////////////////////////////////////////////////////////////////// Bool32 CGRAPH_RestoreLoop(CSTR_rast rast, FILE *in) { int32_t count, lcount, rcount, curr_level = 1; int32_t i, j; intptr_t *ptr; int32_t count_rast; Bool32 flg = FALSE; CSTR_rast rst = rast, curr_rst = rast; CSTR_rast beg, end; CSTR_attr attr = {0}; CSTR_rast_attr rast_attr = {0}; UniVersions uvers = {0}; CGRAPH_Data cstr = {0}; uchar *lp = NULL; LoopData ld; ALoop al; al.n = 0; al.loop = static_cast<intptr_t *>(malloc(sizeof(intptr_t) * memsize)); if(!al.loop) return FALSE; fread(&lcount, sizeof(lcount), 1, in); for(i = 0, count = 0, rcount = 0; i < lcount; i++, count = 0) { fread(&ld, sizeof(ld), 1, in); if(curr_level < ld.level) flg = TRUE; if(flg) { ptr = SetPtr(al.loop, rcount); rst = (CSTR_rast)*ptr; ++rcount; } else rst = rast; //InsertRasterDown while(rst) { if(count == ld.beg) beg = rst; if(count == ld.end) end = rst; ++count; rst = rst->next; } if(!beg || !end) return FALSE; if(!(curr_rst = CSTR_InsertRasterDown(beg, end))) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } if(ld.loop) { for(j = 0; j < ld.loop; j++) { if(!AddLoop(&al, curr_rst)) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } } } //Read Rasters fread(&count_rast, sizeof(count_rast), 1, in); fread(&attr, sizeof(CSTR_attr), 1, in); //InsertRaster for(j = 0; j < count_rast; j++) { fread(&cstr, sizeof(cstr), 1, in); fread(&rast_attr, sizeof(CSTR_rast_attr), 1, in); if(cstr.env) { if(cstr.uvers) fread(&uvers, sizeof(uvers), 1, in); if(cstr.size_linerep) { lp = (uchar *)malloc(cstr.size_linerep); if(!lp) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } fread(lp, cstr.size_linerep, 1, in); } if(!(rst = CSTR_InsertRaster(curr_rst))) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } if(!CSTR_SetAttr(rst, &rast_attr)) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } if(!CSTR_StoreComp(rst, (uchar*)((uchar*)lp), 1, cstr.scale)) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } if(cstr.uvers) { if(!CSTR_StoreCollectionUni(rst, &uvers)) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } } if(lp) free(lp); } else { if(cstr.uvers) fread(&uvers, sizeof(uvers), 1, in); if(!(rst = CSTR_InsertRaster(curr_rst))) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } if(!CSTR_SetAttr(rst, &rast_attr)) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } if(cstr.uvers) { if(!CSTR_StoreCollectionUni(rst, &uvers)) { wLowRC = CGRAPH_ERR_PARAM; return FALSE; } } } } } free(al.loop); return TRUE; }
///////////////////////////////////////////////////////////////////////////////////////// // DESC: Получить число петлей и инициализировать Aloop // ARGS: al - указатель на ALoop // rast - растр // RETS: TRUE - OK // FALSE - ошибка ///////////////////////////////////////////////////////////////////////////////////////// Bool32 CGRAPH_GetLoopCount(ALoop *al, CSTR_rast rast) { int32_t curr_level = 1; int32_t i; intptr_t *ptr; CSTR_rast curr_rst; CSTR_rast next_rst; curr_rst = rast; next_rst = rast; al->n = 0; al->loop = static_cast<intptr_t*> (malloc(sizeof(intptr_t) * memsize)); if(!al->loop) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } //get first part of loops while(next_rst) { if(next_rst->next_down) { if(!AddLoop(al, curr_rst)) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } if(!AddLoop(al, next_rst->next_down)) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } if(!AddLevel(al, curr_level)) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } } next_rst = next_rst->next; } //get next parts of loops for(i = 0; i < al->n; i++) { ptr = SetPtr(al->loop, ++i); next_rst = (CSTR_rast)*(ptr); ptr = SetPtr(al->loop, ++i); curr_level = *(ptr); curr_rst = next_rst; ++curr_level; while(next_rst) { if(next_rst->next_down) { if(!AddLoop(al, curr_rst)) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } if(!AddLoop(al, next_rst->next_down)) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } if(!AddLevel(al, curr_level)) { wLowRC = CGRAPH_ERR_MEMORY; return FALSE; } } next_rst = next_rst->next; } } return TRUE; }
LoopStructureGraph() : root_(new SimpleLoop()), loop_counter_(0) { root_->set_nesting_level(0); // make it the root node root_->set_counter(loop_counter_++); AddLoop(root_); }