#include <string.h>
#include "ast.h"
+// === IMPORTS ===
+extern void SyntaxError(tParser *Parser, int bFatal, const char *Message, ...);
+
// === CODE ===
tAST_Script *AST_NewScript(void)
{
/**
* \brief Append a function to a script
*/
-tAST_Function *AST_AppendFunction(tAST_Script *Script, const char *Name)
+tAST_Function *AST_AppendFunction(tAST_Script *Script, const char *Name, int ReturnType)
{
tAST_Function *ret;
ret = malloc( sizeof(tAST_Function) + strlen(Name) + 1 );
+ if(!ret) return NULL;
+
ret->Next = NULL;
strcpy(ret->Name, Name);
ret->Code = NULL;
ret->Arguments = NULL;
+ ret->ReturnType = ReturnType;
if(Script->LastFunction == NULL) {
Script->Functions = Script->LastFunction = ret;
for( fcn = Script->Functions; fcn; fcn = fcn->Next )
{
+// printf("fcn = %p, fcn->Name = %p\n", fcn, fcn->Name);
ptr = ret;
WRITE_32(Buffer, ret, 0); // Next
WRITE_STR(Buffer, ret, fcn->Name);
size_t baseOfs = Offset;
if(!Node) {
- fprintf(stderr, "Possible Bug - NULL passed to AST_WriteNode\n");
+ //fprintf(stderr, "Possible Bug - NULL passed to AST_WriteNode\n");
+ WRITE_32(Buffer, Offset, 0);
+ WRITE_16(Buffer, Offset, NODETYPE_NOP);
+ WRITE_16(Buffer, Offset, 0); // Line (0)
return 0;
}
// Looping Construct (For loop node)
case NODETYPE_LOOP:
WRITE_8(Buffer, Offset, Node->For.bCheckAfter);
-
+ WRITE_STR(Buffer, Offset, Node->For.Tag);
Offset += AST_WriteNode(Buffer, Offset, Node->For.Init);
Offset += AST_WriteNode(Buffer, Offset, Node->For.Condition);
Offset += AST_WriteNode(Buffer, Offset, Node->For.Increment);
WRITE_STR(Buffer, Offset, Node->DefVar.Name);
WRITE_NODELIST(Buffer, Offset, Node->DefVar.LevelSizes);
+ Offset += AST_WriteNode(Buffer, Offset, Node->DefVar.InitialValue);
break;
// Scope Reference
break;
case NODETYPE_VARIABLE:
case NODETYPE_CONSTANT:
+ case NODETYPE_BREAK:
+ case NODETYPE_CONTINUE:
// TODO: De-Duplicate the strings
WRITE_STR(Buffer, Offset, Node->Variable.Name);
break;
if(!Node) return ;
+ // Referenced counted file name
+ (*(int*)(Node->File - sizeof(int))) -= 1;
+ if( *(int*)(Node->File - sizeof(int)) == 0 )
+ free( (void*)(Node->File - sizeof(int)) );
+
switch(Node->Type)
{
// Block of code
AST_FreeNode(node);
node = savedNext;
}
+ AST_FreeNode(Node->DefVar.InitialValue);
break;
// Unary Operations
case NODETYPE_NOP: break;
case NODETYPE_VARIABLE: break;
case NODETYPE_CONSTANT: break;
+ case NODETYPE_BREAK: break;
+ case NODETYPE_CONTINUE: break;
case NODETYPE_STRING:
case NODETYPE_INTEGER:
{
tAST_Node *ret = malloc( sizeof(tAST_Node) + ExtraSize );
ret->NextSibling = NULL;
- ret->File = "<unk>";
+ ret->File = Parser->Filename; *(int*)(Parser->Filename - sizeof(int)) += 1;
ret->Line = Parser->CurLine;
ret->Type = Type;
void AST_AppendNode(tAST_Node *Parent, tAST_Node *Child)
{
+ // Ignore NULL children
+ if( !Child ) return ;
+
Child->NextSibling = NULL;
switch( Parent->Type )
{
return ret;
}
-tAST_Node *AST_NewLoop(tParser *Parser, tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code)
+tAST_Node *AST_NewLoop(tParser *Parser, const char *Tag, tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code)
{
- tAST_Node *ret = AST_int_AllocateNode(Parser, NODETYPE_LOOP, 0);
+ tAST_Node *ret = AST_int_AllocateNode(Parser, NODETYPE_LOOP, strlen(Tag) + 1);
ret->For.Init = Init;
ret->For.bCheckAfter = !!bPostCheck;
ret->For.Condition = Condition;
ret->For.Increment = Increment;
ret->For.Code = Code;
+ strcpy(ret->For.Tag, Tag);
return ret;
}
{
tAST_Node *ret = AST_int_AllocateNode(Parser, NODETYPE_ASSIGN, 0);
+ if( Dest->Type != NODETYPE_VARIABLE && Dest->Type != NODETYPE_ELEMENT ) {
+ free(ret);
+ SyntaxError(Parser, 1, "Assign target is not a variable or attribute (instead %i)",
+ Dest->Type);
+ AST_FreeNode(Dest);
+ AST_FreeNode(Value);
+ return NULL;
+ }
+
ret->Assign.Operation = Operation;
ret->Assign.Dest = Dest;
ret->Assign.Value = Value;
return ret;
}
+tAST_Node *AST_NewBreakout(tParser *Parser, int Type, const char *DestTag)
+{
+ int len = (DestTag ? strlen(DestTag) : 0);
+ tAST_Node *ret = AST_int_AllocateNode(Parser, Type, len + 1);
+
+ if( DestTag )
+ strcpy(ret->Variable.Name, DestTag);
+ else
+ ret->Variable.Name[0] = '\0';
+
+ return ret;
+}
+
tAST_Node *AST_NewNop(tParser *Parser)
{
tAST_Node *ret = AST_int_AllocateNode(Parser, NODETYPE_NOP, 0);
ret->DefVar.DataType = Type;
ret->DefVar.LevelSizes = NULL;
+ ret->DefVar.LevelSizes_Last = NULL;
+ ret->DefVar.InitialValue = NULL;
strcpy(ret->DefVar.Name, Name);
return ret;