VirtualBox

Changeset 44962 in vbox for trunk/src/VBox/Storage


Ignore:
Timestamp:
Mar 7, 2013 9:37:22 PM (12 years ago)
Author:
vboxsync
Message:

Storage/testcase: Interpret while loops

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/testcase/VDScriptInterp.cpp

    r44941 r44962  
    146146                PVDSCRIPTASTSTMT   pStmtCurr;
    147147            } Compound;
     148            /** Pointer to an AST node. */
     149            PVDSCRIPTASTCORE       pAstNode;
    148150        } Ctrl;
    149151    };
     
    195197    vdScriptStackPush(&pThis->StackValues);
    196198    return VINF_SUCCESS;
     199}
     200
     201/**
     202 * Pushes an AST node onto the control stack.
     203 *
     204 * @returns VBox status code.
     205 * @param   pThis          The interpreter context.
     206 * @param   enmCtrlType    The control entry type.
     207 */
     208DECLINLINE(int) vdScriptInterpreterPushAstEntry(PVDSCRIPTINTERPCTX pThis,
     209                                                PVDSCRIPTASTCORE pAstNode)
     210{
     211    PVDSCRIPTINTERPCTRL pCtrl = NULL;
     212
     213    pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl);
     214
     215    if (pCtrl)
     216    {
     217        pCtrl->fEvalAst = true;
     218        pCtrl->pAstNode = pAstNode;
     219        vdScriptStackPush(&pThis->StackCtrl);
     220        return VINF_SUCCESS;
     221    }
     222
     223    return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack");
    197224}
    198225
     
    247274
    248275/**
    249  * Pushes an AST node onto the control stack.
     276 * Pushes a while statement control entry onto the stack.
    250277 *
    251278 * @returns VBox status code.
    252279 * @param   pThis          The interpreter context.
    253  * @param   enmCtrlType    The control entry type.
    254  */
    255 DECLINLINE(int) vdScriptInterpreterPushAstEntry(PVDSCRIPTINTERPCTX pThis,
    256                                                 PVDSCRIPTASTCORE pAstNode)
    257 {
     280 * @param   pStmt          The while statement.
     281 */
     282DECLINLINE(int) vdScriptInterpreterPushWhileCtrlEntry(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt)
     283{
     284    int rc = VINF_SUCCESS;
    258285    PVDSCRIPTINTERPCTRL pCtrl = NULL;
    259286
    260287    pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl);
    261 
    262288    if (pCtrl)
    263289    {
    264         pCtrl->fEvalAst = true;
    265         pCtrl->pAstNode = pAstNode;
     290        pCtrl->fEvalAst = false;
     291        pCtrl->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_WHILE;
     292        pCtrl->Ctrl.pAstNode    = &pStmt->Core;
    266293        vdScriptStackPush(&pThis->StackCtrl);
    267         return VINF_SUCCESS;
    268     }
    269 
    270     return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack");
     294
     295        rc = vdScriptInterpreterPushAstEntry(pThis, &pStmt->While.pCond->Core);
     296        if (   RT_SUCCESS(rc)
     297            && pStmt->While.fDoWhile)
     298        {
     299            /* Push the statement to execute for do ... while loops because they run at least once. */
     300            rc = vdScriptInterpreterPushAstEntry(pThis, &pStmt->While.pStmt->Core);
     301            if (RT_FAILURE(rc))
     302            {
     303                /* Cleanup while control statement and AST node. */
     304                vdScriptStackPop(&pThis->StackCtrl);
     305                vdScriptStackPop(&pThis->StackCtrl);
     306            }
     307        }
     308        else if (RT_FAILURE(rc))
     309            vdScriptStackPop(&pThis->StackCtrl); /* Cleanup the while control statement. */
     310    }
     311    else
     312        rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack");
     313
     314    return rc;
    271315}
    272316
     
    494538        case VDSCRIPTSTMTTYPE_IF:
    495539        case VDSCRIPTSTMTTYPE_SWITCH:
     540            AssertMsgFailed(("TODO\n"));
     541            break;
    496542        case VDSCRIPTSTMTTYPE_WHILE:
     543        {
     544            rc = vdScriptInterpreterPushWhileCtrlEntry(pThis, pStmt);
     545            break;
     546        }
    497547        case VDSCRIPTSTMTTYPE_FOR:
    498548        case VDSCRIPTSTMTTYPE_CONTINUE:
     
    501551        case VDSCRIPTSTMTTYPE_CASE:
    502552        case VDSCRIPTSTMTTYPE_DEFAULT:
     553            AssertMsgFailed(("TODO\n"));
     554            break;
    503555        default:
    504556            AssertMsgFailed(("Invalid statement type: %d\n", pStmt->enmStmtType));
     
    699751            break;
    700752        }
     753        case VDSCRIPTINTERPCTRLTYPE_WHILE:
     754        {
     755            PVDSCRIPTASTSTMT pWhileStmt = (PVDSCRIPTASTSTMT)pCtrl->Ctrl.pAstNode;
     756
     757            /* Check whether the condition passed. */
     758            VDSCRIPTARG Cond;
     759            vdScriptInterpreterPopValue(pThis, &Cond);
     760            AssertMsg(Cond.enmType == VDSCRIPTTYPE_BOOL,
     761                      ("Value on stack is not of boolean type\n"));
     762
     763            if (Cond.f)
     764            {
     765                /* Execute the loop another round. */
     766                rc = vdScriptInterpreterPushAstEntry(pThis, &pWhileStmt->While.pCond->Core);
     767                if (RT_SUCCESS(rc))
     768                {
     769                    rc = vdScriptInterpreterPushAstEntry(pThis, &pWhileStmt->While.pStmt->Core);
     770                    if (RT_FAILURE(rc))
     771                        vdScriptStackPop(&pThis->StackCtrl);
     772                }
     773            }
     774            else
     775                vdScriptStackPop(&pThis->StackCtrl); /* Remove while control statement. */
     776            break;
     777        }
    701778        default:
    702779            AssertMsgFailed(("Invalid evaluation control type on the stack: %d\n",
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette