static void ContinueStatement (void) /* Handle the 'continue' statement */ { LoopDesc* L; /* Skip the continue */ NextToken (); /* Get the current loop descriptor */ L = CurrentLoop (); if (L) { /* Search for a loop that has a continue label. */ do { if (L->ContinueLabel) { break; } L = L->Next; } while (L); } /* Did we find it? */ if (L == 0) { Error ("`continue' statement not within a loop"); return; } /* Correct the stackpointer if needed */ g_space (StackPtr - L->StackPtr); /* Jump to next loop iteration */ g_jump (L->ContinueLabel); }
void F_AllocLocalSpace (Function* F) /* Allocate any local space previously reserved. The function will do * nothing if there is no reserved local space. */ { if (F->Reserved > 0) { /* Create space on the stack */ g_space (F->Reserved); /* Correct the stack pointer */ StackPtr -= F->Reserved; /* Nothing more reserved */ F->Reserved = 0; } }
static int CompoundStatement (void) /* Compound statement. Allow any number of statements inside braces. The ** function returns true if the last statement was a break or return. */ { int GotBreak; /* Remember the stack at block entry */ int OldStack = StackPtr; /* Enter a new lexical level */ EnterBlockLevel (); /* Parse local variable declarations if any */ DeclareLocals (); /* Now process statements in this block */ GotBreak = 0; while (CurTok.Tok != TOK_RCURLY) { if (CurTok.Tok != TOK_CEOF) { GotBreak = Statement (0); } else { break; } } /* Clean up the stack. */ if (!GotBreak) { g_space (StackPtr - OldStack); } StackPtr = OldStack; /* Emit references to imports/exports for this block */ EmitExternals (); /* Leave the lexical level */ LeaveBlockLevel (); return GotBreak; }
static void ReturnStatement (void) /* Handle the 'return' statement */ { ExprDesc Expr; NextToken (); if (CurTok.Tok != TOK_SEMI) { /* Evaluate the return expression */ hie0 (&Expr); /* If we return something in a void function, print an error and ** ignore the value. Otherwise convert the value to the type of the ** return. */ if (F_HasVoidReturn (CurrentFunc)) { Error ("Returning a value in function with return type void"); } else { /* Convert the return value to the type of the function result */ TypeConversion (&Expr, F_GetReturnType (CurrentFunc)); /* Load the value into the primary */ LoadExpr (CF_NONE, &Expr); } } else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) { Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc)); } /* Mark the function as having a return statement */ F_ReturnFound (CurrentFunc); /* Cleanup the stack in case we're inside a block with locals */ g_space (StackPtr - F_GetTopLevelSP (CurrentFunc)); /* Output a jump to the function exit code */ g_jump (F_GetRetLab (CurrentFunc)); }
static void BreakStatement (void) /* Handle the 'break' statement */ { LoopDesc* L; /* Skip the break */ NextToken (); /* Get the current loop descriptor */ L = CurrentLoop (); /* Check if we are inside a loop */ if (L == 0) { /* Error: No current loop */ Error ("`break' statement not within loop or switch"); return; } /* Correct the stack pointer if needed */ g_space (StackPtr - L->StackPtr); /* Jump to the exit label of the loop */ g_jump (L->BreakLabel); }