3 * - Script AST Manipulator
10 tAST_Script *AST_NewScript(void)
12 tAST_Script *ret = malloc( sizeof(tAST_Script) );
14 ret->Functions = NULL;
15 ret->LastFunction = NULL;
21 * \brief Append a function to a script
23 tAST_Function *AST_AppendFunction(tAST_Script *Script, const char *Name)
27 ret = malloc( sizeof(tAST_Function) );
29 ret->Name = strdup(Name);
31 ret->Arguments = NULL;
33 if(Script->LastFunction == NULL) {
34 Script->Functions = Script->LastFunction = ret;
37 Script->LastFunction->Next = ret;
38 Script->LastFunction = ret;
44 void AST_SetFunctionCode(tAST_Function *Function, tAST_Node *Root)
46 Function->Code = Root;
50 * \name Node Manipulation
53 void AST_FreeNode(tAST_Node *Node)
60 for( node = Node->Block.FirstChild; node; )
62 tAST_Node *savedNext = node->NextSibling;
69 case NODETYPE_FUNCTIONCALL:
70 for( node = Node->FunctionCall.FirstArg; node; )
72 tAST_Node *savedNext = node->NextSibling;
80 AST_FreeNode(Node->Assign.Dest);
81 AST_FreeNode(Node->Assign.Value);
86 AST_FreeNode(Node->UniOp.Value);
91 case NODETYPE_SUBTRACT:
92 case NODETYPE_MULTIPLY:
95 case NODETYPE_BITSHIFTLEFT:
96 case NODETYPE_BITSHIFTRIGHT:
97 case NODETYPE_BITROTATELEFT:
98 case NODETYPE_BWAND: case NODETYPE_LOGICALAND:
99 case NODETYPE_BWOR: case NODETYPE_LOGICALOR:
100 case NODETYPE_BWXOR: case NODETYPE_LOGICALXOR:
101 case NODETYPE_EQUALS:
102 case NODETYPE_LESSTHAN:
103 case NODETYPE_GREATERTHAN:
104 AST_FreeNode( Node->BinOp.Left );
105 AST_FreeNode( Node->BinOp.Right );
108 // Node types with no children
109 case NODETYPE_NOP: break;
110 case NODETYPE_VARIABLE: break;
111 case NODETYPE_CONSTANT: break;
112 case NODETYPE_STRING: break;
113 case NODETYPE_INTEGER: break;
114 case NODETYPE_REAL: break;
119 tAST_Node *AST_NewCodeBlock(void)
121 tAST_Node *ret = malloc( sizeof(tAST_Node) );
123 ret->NextSibling = NULL;
124 ret->Type = NODETYPE_BLOCK;
125 ret->Block.FirstChild = NULL;
126 ret->Block.LastChild = NULL;
131 void AST_AppendNode(tAST_Node *Parent, tAST_Node *Child)
133 if(Parent->Type != NODETYPE_BLOCK) return ;
135 if(Parent->Block.FirstChild == NULL) {
136 Parent->Block.FirstChild = Parent->Block.LastChild = Child;
139 Parent->Block.LastChild->NextSibling = Child;
140 Parent->Block.LastChild = Child;
144 tAST_Node *AST_NewAssign(int Operation, tAST_Node *Dest, tAST_Node *Value)
146 tAST_Node *ret = malloc( sizeof(tAST_Node) );
148 ret->NextSibling = NULL;
149 ret->Type = NODETYPE_ASSIGN;
150 ret->Assign.Operation = Operation;
151 ret->Assign.Dest = Dest;
152 ret->Assign.Value = Value;
157 tAST_Node *AST_NewBinOp(int Operation, tAST_Node *Left, tAST_Node *Right)
159 tAST_Node *ret = malloc( sizeof(tAST_Node) );
161 ret->NextSibling = NULL;
162 ret->Type = Operation;
163 ret->BinOp.Left = Left;
164 ret->BinOp.Right = Right;
170 * \brief Create a new string node
172 tAST_Node *AST_NewString(const char *String, int Length)
174 tAST_Node *ret = malloc( sizeof(tAST_Node) + Length + 1 );
176 ret->NextSibling = NULL;
177 ret->Type = NODETYPE_STRING;
178 ret->String.Length = Length;
179 memcpy(ret->String.Data, String, Length);
180 ret->String.Data[Length] = '\0';
186 * \brief Create a new integer node
188 tAST_Node *AST_NewInteger(uint64_t Value)
190 tAST_Node *ret = malloc( sizeof(tAST_Node) );
191 ret->NextSibling = NULL;
192 ret->Type = NODETYPE_INTEGER;
193 ret->Integer = Value;
198 * \brief Create a new variable reference node
200 tAST_Node *AST_NewVariable(const char *Name)
202 tAST_Node *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
203 ret->NextSibling = NULL;
204 ret->Type = NODETYPE_VARIABLE;
205 strcpy(ret->Variable.Name, Name);
210 * \brief Create a new runtime constant reference node
212 tAST_Node *AST_NewConstant(const char *Name)
214 tAST_Node *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
215 ret->NextSibling = NULL;
216 ret->Type = NODETYPE_CONSTANT;
217 strcpy(ret->Variable.Name, Name);
222 * \brief Create a function call node
223 * \note Argument list is manipulated using AST_AppendFunctionCallArg
225 tAST_Node *AST_NewFunctionCall(const char *Name)
227 tAST_Node *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
229 ret->NextSibling = NULL;
230 ret->Type = NODETYPE_FUNCTIONCALL;
231 ret->FunctionCall.FirstArg = NULL;
232 ret->FunctionCall.LastArg = NULL;
233 strcpy(ret->FunctionCall.Name, Name);
238 * \brief Append an argument to a function call
240 void AST_AppendFunctionCallArg(tAST_Node *Node, tAST_Node *Arg)
242 if( Node->Type != NODETYPE_FUNCTIONCALL ) return ;
244 if(Node->FunctionCall.LastArg) {
245 Node->FunctionCall.LastArg->NextSibling = Arg;
246 Node->FunctionCall.LastArg = Arg;
249 Node->FunctionCall.FirstArg = Arg;
250 Node->FunctionCall.LastArg = Arg;