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 *GetExprRoll(SilikoLexer *lexer) { SilikoSyntaxTreeNode *leftValue = NULL; SilikoSyntaxTreeNode *rest = NULL; SilikoSyntaxTreeNode *rVal; if (!(leftValue = GetAtom(lexer))) goto memerr; if (!(rest = GetExprRollLeftFactor(lexer))) goto memerr; if (rest->Type == SILIKO_AST_NOTHING) { SilikoSyntaxTreeDelete(rest); return leftValue; } if (!(rVal = SilikoSyntaxTreeNewBranch("dice"))) goto memerr; SilikoSyntaxTreePushRight(rVal, leftValue); SilikoSyntaxTreePushRight(rVal, rest); return rVal; memerr: SilikoSyntaxTreeDelete(leftValue); SilikoSyntaxTreeDelete(rest); return NULL; }
static SilikoSyntaxTreeNode *GetNumber(SilikoLexer *lexer) { SilikoSyntaxTreeNode * uNumber = NULL; switch (lexer->Token.Type) { case SILIKO_TOK_INTEGER: case SILIKO_TOK_FLOAT: return GetUNumber(lexer); case '-': SilikoLexerNext(lexer); if (!(uNumber = GetUNumber(lexer))) return NULL; if (!SilikoSyntaxTreeNegate(uNumber)) { SilikoSyntaxTreeDelete(uNumber); return SilikoSyntaxTreeNewError(); } return uNumber; default: return SilikoSyntaxTreeNewError(); } }
static SilikoSyntaxTreeNode *GetAtom(SilikoLexer *lexer) { SilikoSyntaxTreeNode *value; switch(lexer->Token.Type) { case '-': case SILIKO_TOK_INTEGER: case SILIKO_TOK_FLOAT: return GetNumber(lexer); case '(': SilikoLexerNext(lexer); if (!(value = GetExprAddSub(lexer))) return NULL; if (lexer->Token.Type != ')') { SilikoSyntaxTreeDelete(value); return SilikoSyntaxTreeNewError(); } SilikoLexerNext(lexer); return value; case SILIKO_TOK_ID: return GetFCall(lexer); default: 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; }
void SilikoSyntaxTreeDelete(SilikoSyntaxTreeNode *Node) { if (Node) if (Node->Type == SILIKO_AST_BRANCH) { free(Node->Branch->Id); for (int i = 0; i < Node->Branch->Count; i++) SilikoSyntaxTreeDelete(Node->Branch->Children[i]); free(Node->Branch->Children); free(Node->Branch); } free(Node); }
static void Calculate(GtkWidget *Widget, gpointer EvalWindow) { SilikoSyntaxTreeNode *ResultTree = SilikoParseInfix( SilikoStringSourceNew( gtk_entry_get_text( GTK_ENTRY( gtk_builder_get_object(GTK_BUILDER(EvalWindow), "Input"))))); SilikoValue Value = SilikoSyntaxTreeEvaluate(ResultTree); SilikoSyntaxTreeDelete(ResultTree); char *ResultString = SilikoValueToString(Value); gtk_label_set_text( GTK_LABEL( gtk_builder_get_object( GTK_BUILDER(EvalWindow), "Output")), ResultString); free(ResultString); }
SilikoSyntaxTreeNode *SilikoParseInfix(SilikoDataSource *Input) { SilikoSyntaxTreeNode *rVal = NULL; SilikoLexer *lexer = NULL; if (!(lexer = SilikoLexerNew(Input))) return NULL; rVal = (lexer->Token.Type == SILIKO_TOK_EOL) ? SilikoSyntaxTreeNewInteger(0) : GetExprAddSub(lexer); if (lexer->Token.Type != SILIKO_TOK_EOL) { SilikoSyntaxTreeDelete(rVal); rVal = SilikoSyntaxTreeNewError(); } SilikoLexerDelete(lexer); return rVal; }
int main(int argc, char *argv[]) { SilikoValue value; SilikoSyntaxTreeNode *tree; const char *prompt; const char *response; if (ISATTY()) { prompt = "> "; response = "= "; } else { prompt = ""; response = ""; } SilikoFunctionCallerSetUp(); char *expression = NULL; char *old_expression = NULL; while(-1) { expression = readline(prompt); if(!expression) { free(old_expression); old_expression = NULL; break; } if(*expression && (!old_expression || strcmp(expression, old_expression) != 0)) add_history(expression); free(old_expression); old_expression = NULL; tree = SilikoParseInfix( SilikoStringSourceNew(expression)); value = SilikoSyntaxTreeEvaluate(tree); SilikoSyntaxTreeDelete(tree); char *ResultString = SilikoValueToString(value); printf("%s\n", ResultString); free(ResultString); old_expression = expression; } SilikoFunctionCallerTearDown(); if (ISATTY()) { fputc('\n', stdout); fflush(stdout); } return 0; }