static SilikoSyntaxTreeNode *GetExprAddSub(SilikoLexer *lexer) { SilikoSyntaxTreeNode *leftValue = NULL; SilikoSyntaxTreeNode *rest = NULL; leftValue = GetExprMulDiv(lexer); if (leftValue == NULL) return NULL; if (!(rest = GetExprAddSubRest(lexer))) { SilikoSyntaxTreeDelete(leftValue); return NULL; } if (rest->Type == SILIKO_AST_NOTHING) { SilikoSyntaxTreeDelete(rest); return leftValue; } if (SilikoSyntaxTreeGraftLeft(rest, leftValue)) return rest; SilikoSyntaxTreeDelete(rest); SilikoSyntaxTreeDelete(leftValue); return SilikoSyntaxTreeNewError(); }
static SilikoSyntaxTreeNode *GetExprAddSubRest(SilikoLexer *lexer) { char *operation = NULL; SilikoSyntaxTreeNode *leftValue = NULL; SilikoSyntaxTreeNode *rest = NULL; SilikoSyntaxTreeNode *branchNode = NULL; switch (lexer->Token.Type) { case '+': operation = "add"; break; case '-': operation = "subtract"; break; default: return SilikoSyntaxTreeNewNothing(); } SilikoLexerNext(lexer); if (!(leftValue = GetExprMulDiv(lexer))) goto memerr; if (!(rest = GetExprAddSubRest(lexer))) goto memerr; if (!(branchNode = SilikoSyntaxTreeNewBranch(operation))) goto memerr; SilikoSyntaxTreePushRight(branchNode, NULL); SilikoSyntaxTreePushRight(branchNode, leftValue); if (rest->Type != SILIKO_AST_NOTHING) { SilikoSyntaxTreeGraftLeft(rest, branchNode); return rest; } SilikoSyntaxTreeDelete(rest); return branchNode; memerr: SilikoSyntaxTreeDelete(leftValue); SilikoSyntaxTreeDelete(rest); return NULL; }
int SilikoSyntaxTreeGraftLeft(SilikoSyntaxTreeNode *Tree, SilikoSyntaxTreeNode *NewBranch) { if (Tree->Type == SILIKO_AST_BRANCH) { if (Tree->Branch->Count == 0) { return 0; } else if (Tree->Branch->Children[0] == NULL) { Tree->Branch->Children[0] = NewBranch; return -1; } else { return SilikoSyntaxTreeGraftLeft (Tree->Branch->Children[0], NewBranch); } } else { return 0; } }