VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/VDScriptAst.cpp@ 44891

Last change on this file since 44891 was 44891, checked in by vboxsync, 12 years ago

Storage/VDScript: Updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
1/** @file
2 *
3 * VBox HDD container test utility - scripting engine AST node related functions.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#define LOGGROUP LOGGROUP_DEFAULT
18#include <iprt/list.h>
19#include <iprt/mem.h>
20#include <iprt/assert.h>
21#include <iprt/string.h>
22
23#include <VBox/log.h>
24
25#include "VDScriptAst.h"
26
27/**
28 * Put all child nodes of the given expression AST node onto the given to free list.
29 *
30 * @returns nothing.
31 * @param pList The free list to append everything to.
32 * @param pAstNode The expression node to free.
33 */
34static void vdScriptAstNodeExpressionPutOnFreeList(PRTLISTANCHOR pList, PVDSCRIPTASTCORE pAstNode)
35{
36 AssertMsgReturnVoid(pAstNode->enmClass == VDSCRIPTASTCLASS_EXPRESSION,
37 ("Given AST node is not a statement\n"));
38
39 PVDSCRIPTASTEXPR pExpr = (PVDSCRIPTASTEXPR)pAstNode;
40 switch (pExpr->enmType)
41 {
42 case VDSCRIPTEXPRTYPE_PRIMARY_NUMCONST:
43 break;
44 case VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST:
45 RTStrFree((char *)pExpr->pszStr);
46 break;
47 case VDSCRIPTEXPRTYPE_PRIMARY_IDENTIFIER:
48 {
49 RTListAppend(pList, &pExpr->pIde->Core.ListNode);
50 break;
51 }
52 case VDSCRIPTEXPRTYPE_ASSIGNMENT_LIST:
53 {
54 while (!RTListIsEmpty(&pExpr->ListExpr))
55 {
56 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pExpr->ListExpr, VDSCRIPTASTCORE, ListNode);
57 RTListNodeRemove(&pNode->ListNode);
58 RTListAppend(pList, &pNode->ListNode);
59 }
60 break;
61 }
62 case VDSCRIPTEXPRTYPE_POSTFIX_FNCALL:
63 {
64 RTListAppend(pList, &pExpr->FnCall.pFnIde->Core.ListNode);
65 while (!RTListIsEmpty(&pExpr->FnCall.ListArgs))
66 {
67 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pExpr->FnCall.ListArgs, VDSCRIPTASTCORE, ListNode);
68 RTListNodeRemove(&pNode->ListNode);
69 RTListAppend(pList, &pNode->ListNode);
70 }
71 break;
72 }
73 case VDSCRIPTEXPRTYPE_POSTFIX_INCREMENT:
74 case VDSCRIPTEXPRTYPE_POSTFIX_DECREMENT:
75 case VDSCRIPTEXPRTYPE_UNARY_INCREMENT:
76 case VDSCRIPTEXPRTYPE_UNARY_DECREMENT:
77 case VDSCRIPTEXPRTYPE_UNARY_POSSIGN:
78 case VDSCRIPTEXPRTYPE_UNARY_NEGSIGN:
79 case VDSCRIPTEXPRTYPE_UNARY_INVERT:
80 case VDSCRIPTEXPRTYPE_UNARY_NEGATE:
81 {
82 RTListAppend(pList, &pExpr->pExpr->Core.ListNode);
83 break;
84 }
85 case VDSCRIPTEXPRTYPE_MULTIPLICATION:
86 case VDSCRIPTEXPRTYPE_DIVISION:
87 case VDSCRIPTEXPRTYPE_MODULUS:
88 case VDSCRIPTEXPRTYPE_ADDITION:
89 case VDSCRIPTEXPRTYPE_SUBTRACTION:
90 case VDSCRIPTEXPRTYPE_LSR:
91 case VDSCRIPTEXPRTYPE_LSL:
92 case VDSCRIPTEXPRTYPE_LOWER:
93 case VDSCRIPTEXPRTYPE_HIGHER:
94 case VDSCRIPTEXPRTYPE_LOWEREQUAL:
95 case VDSCRIPTEXPRTYPE_HIGHEREQUAL:
96 case VDSCRIPTEXPRTYPE_EQUAL:
97 case VDSCRIPTEXPRTYPE_NOTEQUAL:
98 case VDSCRIPTEXPRTYPE_BITWISE_AND:
99 case VDSCRIPTEXPRTYPE_BITWISE_XOR:
100 case VDSCRIPTEXPRTYPE_BITWISE_OR:
101 case VDSCRIPTEXPRTYPE_LOGICAL_AND:
102 case VDSCRIPTEXPRTYPE_LOGICAL_OR:
103 case VDSCRIPTEXPRTYPE_ASSIGN:
104 case VDSCRIPTEXPRTYPE_ASSIGN_MULT:
105 case VDSCRIPTEXPRTYPE_ASSIGN_DIV:
106 case VDSCRIPTEXPRTYPE_ASSIGN_MOD:
107 case VDSCRIPTEXPRTYPE_ASSIGN_ADD:
108 case VDSCRIPTEXPRTYPE_ASSIGN_SUB:
109 case VDSCRIPTEXPRTYPE_ASSIGN_LSL:
110 case VDSCRIPTEXPRTYPE_ASSIGN_LSR:
111 case VDSCRIPTEXPRTYPE_ASSIGN_AND:
112 case VDSCRIPTEXPRTYPE_ASSIGN_XOR:
113 case VDSCRIPTEXPRTYPE_ASSIGN_OR:
114 {
115 RTListAppend(pList, &pExpr->BinaryOp.pLeftExpr->Core.ListNode);
116 RTListAppend(pList, &pExpr->BinaryOp.pRightExpr->Core.ListNode);
117 break;
118 }
119 case VDSCRIPTEXPRTYPE_INVALID:
120 default:
121 AssertMsgFailedReturnVoid(("Invalid AST node expression type %d\n",
122 pExpr->enmType));
123 }
124}
125
126/**
127 * Free a given statement AST node and put everything on the given to free list.
128 *
129 * @returns nothing.
130 * @param pList The free list to append everything to.
131 * @param pAstNode The statement node to free.
132 */
133static void vdScriptAstNodeStatmentPutOnFreeList(PRTLISTANCHOR pList, PVDSCRIPTASTCORE pAstNode)
134{
135 AssertMsgReturnVoid(pAstNode->enmClass == VDSCRIPTASTCLASS_STATEMENT,
136 ("Given AST node is not a statement\n"));
137
138 PVDSCRIPTASTSTMT pStmt = (PVDSCRIPTASTSTMT)pAstNode;
139 switch (pStmt->enmStmtType)
140 {
141 case VDSCRIPTSTMTTYPE_COMPOUND:
142 {
143 /* Put all declarations on the to free list. */
144 while (!RTListIsEmpty(&pStmt->Compound.ListDecls))
145 {
146 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListDecls, VDSCRIPTASTCORE, ListNode);
147 RTListNodeRemove(&pNode->ListNode);
148 RTListAppend(pList, &pNode->ListNode);
149 }
150
151 /* Put all statements on the to free list. */
152 while (!RTListIsEmpty(&pStmt->Compound.ListStmts))
153 {
154 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListDecls, VDSCRIPTASTCORE, ListNode);
155 RTListNodeRemove(&pNode->ListNode);
156 RTListAppend(pList, &pNode->ListNode);
157 }
158 break;
159 }
160 case VDSCRIPTSTMTTYPE_EXPRESSION:
161 {
162 RTListAppend(pList, &pStmt->pExpr->Core.ListNode);
163 break;
164 }
165 case VDSCRIPTSTMTTYPE_IF:
166 {
167 RTListAppend(pList, &pStmt->If.pCond->Core.ListNode);
168 RTListAppend(pList, &pStmt->If.pTrueStmt->Core.ListNode);
169 if (pStmt->If.pElseStmt)
170 RTListAppend(pList, &pStmt->If.pElseStmt->Core.ListNode);
171 break;
172 }
173 case VDSCRIPTSTMTTYPE_SWITCH:
174 {
175 RTListAppend(pList, &pStmt->Switch.pCond->Core.ListNode);
176 RTListAppend(pList, &pStmt->Switch.pStmt->Core.ListNode);
177 break;
178 }
179 case VDSCRIPTSTMTTYPE_WHILE:
180 {
181 RTListAppend(pList, &pStmt->While.pCond->Core.ListNode);
182 RTListAppend(pList, &pStmt->While.pStmt->Core.ListNode);
183 break;
184 }
185 case VDSCRIPTSTMTTYPE_FOR:
186 {
187 RTListAppend(pList, &pStmt->For.pExprStart->Core.ListNode);
188 RTListAppend(pList, &pStmt->For.pExprCond->Core.ListNode);
189 RTListAppend(pList, &pStmt->For.pExpr3->Core.ListNode);
190 RTListAppend(pList, &pStmt->For.pStmt->Core.ListNode);
191 break;
192 }
193 case VDSCRIPTSTMTTYPE_RETURN:
194 {
195 if (pStmt->pExpr)
196 RTListAppend(pList, &pStmt->pExpr->Core.ListNode);
197 break;
198 }
199 case VDSCRIPTSTMTTYPE_CASE:
200 {
201 RTListAppend(pList, &pStmt->Case.pExpr->Core.ListNode);
202 RTListAppend(pList, &pStmt->Case.pStmt->Core.ListNode);
203 break;
204 }
205 case VDSCRIPTSTMTTYPE_DEFAULT:
206 {
207 RTListAppend(pList, &pStmt->Case.pStmt->Core.ListNode);
208 break;
209 }
210 case VDSCRIPTSTMTTYPE_CONTINUE:
211 case VDSCRIPTSTMTTYPE_BREAK:
212 break;
213 case VDSCRIPTSTMTTYPE_INVALID:
214 default:
215 AssertMsgFailedReturnVoid(("Invalid AST node statement type %d\n",
216 pStmt->enmStmtType));
217 }
218}
219
220DECLHIDDEN(void) vdScriptAstNodeFree(PVDSCRIPTASTCORE pAstNode)
221{
222 RTLISTANCHOR ListFree;
223
224 /*
225 * The node is not allowed to be part of a list because we need it
226 * for the nodes to free list.
227 */
228 Assert(RTListIsEmpty(&pAstNode->ListNode));
229 RTListInit(&ListFree);
230 RTListAppend(&ListFree, &pAstNode->ListNode);
231
232 do
233 {
234 pAstNode = RTListGetFirst(&ListFree, VDSCRIPTASTCORE, ListNode);
235 RTListNodeRemove(&pAstNode->ListNode);
236
237 switch (pAstNode->enmClass)
238 {
239 case VDSCRIPTASTCLASS_FUNCTION:
240 {
241 PVDSCRIPTASTFN pFn = (PVDSCRIPTASTFN)pAstNode;
242
243 if (pFn->pRetType)
244 RTListAppend(&ListFree, &pFn->pRetType->Core.ListNode);
245 if (pFn->pFnIde)
246 RTListAppend(&ListFree, &pFn->pFnIde->Core.ListNode);
247
248 /* Put argument list on the to free list. */
249 while (!RTListIsEmpty(&pFn->ListArgs))
250 {
251 PVDSCRIPTASTCORE pArg = RTListGetFirst(&pFn->ListArgs, VDSCRIPTASTCORE, ListNode);
252 RTListNodeRemove(&pArg->ListNode);
253 RTListAppend(&ListFree, &pArg->ListNode);
254 }
255
256 /* Put compound statement onto the list. */
257 RTListAppend(&ListFree, &pFn->pCompoundStmts->Core.ListNode);
258 break;
259 }
260 case VDSCRIPTASTCLASS_FUNCTIONARG:
261 {
262 PVDSCRIPTASTFNARG pAstNodeArg = (PVDSCRIPTASTFNARG)pAstNode;
263 if (pAstNodeArg->pType)
264 RTListAppend(&ListFree, &pAstNodeArg->pType->Core.ListNode);
265 if (pAstNodeArg->pArgIde)
266 RTListAppend(&ListFree, &pAstNodeArg->pArgIde->Core.ListNode);
267 break;
268 }
269 case VDSCRIPTASTCLASS_IDENTIFIER:
270 break;
271 case VDSCRIPTASTCLASS_DECLARATION:
272 break;
273 case VDSCRIPTASTCLASS_STATEMENT:
274 {
275 vdScriptAstNodeStatmentPutOnFreeList(&ListFree, pAstNode);
276 break;
277 }
278 case VDSCRIPTASTCLASS_EXPRESSION:
279 {
280 vdScriptAstNodeExpressionPutOnFreeList(&ListFree, pAstNode);
281 break;
282 }
283 case VDSCRIPTASTCLASS_INVALID:
284 default:
285 AssertMsgFailedReturnVoid(("Invalid AST node class given %d\n", pAstNode->enmClass));
286 }
287
288 RTMemFree(pAstNode);
289 } while (!RTListIsEmpty(&ListFree));
290
291}
292
293DECLHIDDEN(PVDSCRIPTASTCORE) vdScriptAstNodeAlloc(VDSCRIPTASTCLASS enmClass)
294{
295 size_t cbAlloc = 0;
296
297 switch (enmClass)
298 {
299 case VDSCRIPTASTCLASS_FUNCTION:
300 cbAlloc = sizeof(VDSCRIPTASTFN);
301 break;
302 case VDSCRIPTASTCLASS_FUNCTIONARG:
303 cbAlloc = sizeof(VDSCRIPTASTFNARG);
304 break;
305 case VDSCRIPTASTCLASS_DECLARATION:
306 cbAlloc = sizeof(VDSCRIPTASTDECL);
307 break;
308 case VDSCRIPTASTCLASS_STATEMENT:
309 cbAlloc = sizeof(VDSCRIPTASTSTMT);
310 break;
311 case VDSCRIPTASTCLASS_EXPRESSION:
312 cbAlloc = sizeof(VDSCRIPTASTEXPR);
313 break;
314 case VDSCRIPTASTCLASS_IDENTIFIER:
315 case VDSCRIPTASTCLASS_INVALID:
316 default:
317 AssertMsgFailedReturn(("Invalid AST node class given %d\n", enmClass), NULL);
318 }
319
320 PVDSCRIPTASTCORE pAstNode = (PVDSCRIPTASTCORE)RTMemAllocZ(cbAlloc);
321 if (pAstNode)
322 {
323 pAstNode->enmClass = enmClass;
324 RTListInit(&pAstNode->ListNode);
325 }
326
327 return pAstNode;
328}
329
330DECLHIDDEN(PVDSCRIPTASTIDE) vdScriptAstNodeIdeAlloc(unsigned cchIde)
331{
332 PVDSCRIPTASTIDE pAstNode = (PVDSCRIPTASTIDE)RTMemAllocZ(RT_OFFSETOF(VDSCRIPTASTIDE, aszIde[cchIde + 1]));
333 if (pAstNode)
334 {
335 pAstNode->Core.enmClass = VDSCRIPTASTCLASS_IDENTIFIER;
336 RTListInit(&pAstNode->Core.ListNode);
337 }
338
339 return pAstNode;
340}
Note: See TracBrowser for help on using the repository browser.

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