VirtualBox

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

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

Storage/testcase: More scripting language work

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