VirtualBox

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

Last change on this file since 105352 was 99739, checked in by vboxsync, 19 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void).

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