diff options
| author | root <root@krebs> | 2011-08-20 23:33:40 +0200 |
|---|---|---|
| committer | root <root@krebs> | 2011-08-20 23:33:40 +0200 |
| commit | 6b2cd5bb85d257f432923e22178c0559fe9656aa (patch) | |
| tree | 46f16983868954dd5aec208cdbcfc8466d87eef3 /oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base | |
| parent | a130ff747711005511c33f4c0714550f32e707f2 (diff) | |
lcd4linux: removed trash
Diffstat (limited to 'oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base')
| -rw-r--r-- | oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base | 1430 |
1 files changed, 0 insertions, 1430 deletions
diff --git a/oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base b/oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base deleted file mode 100644 index d0d49288..00000000 --- a/oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base +++ /dev/null @@ -1,1430 +0,0 @@ -/* $Id$ - * $URL$ - * - * expression evaluation - * - * Copyright (C) 1999, 2000 Michael Reinelt <michael@reinelt.co.at> - * Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> - * - * This file is part of LCD4Linux. - * - * LCD4Linux is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * LCD4Linux is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* - * exported functions: - * - * int SetVariable (char *name, RESULT *value) - * adds a generic variable to the evaluator - * - * int SetVariableNumeric (char *name, double value) - * adds a numerical variable to the evaluator - * - * int SetVariableString (char *name, char *value) - * adds a numerical variable to the evaluator - * - * int AddFunction (char *name, int argc, void (*func)()) - * adds a function to the evaluator - * - * void DeleteVariables (void); - * frees all allocated variables - * - * void DeleteFunctions (void); - * frees all allocated functions - * - * void DelResult (RESULT *result) - * sets a result to none - * frees a probably allocated memory - * - * RESULT* SetResult (RESULT **result, int type, void *value) - * initializes a result - * - * double R2N (RESULT *result) - * converts a result into a number - * - * char* R2S (RESULT *result) - * converts a result into a string - * - * - * int Compile (char* expression, void **tree) - * compiles a expression into a tree - * - * int Eval (void *tree, RESULT *result) - * evaluates an expression - * - * void DelTree (void *tree) - * frees a compiled tree - */ - - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <math.h> -#include <setjmp.h> - -#include "debug.h" -#include "evaluator.h" - -#ifdef WITH_DMALLOC -#include <dmalloc.h> -#endif - -/* string buffer chunk size */ -#define CHUNK_SIZE 16 - -typedef enum { - T_UNDEF, - T_NAME, - T_NUMBER, - T_STRING, - T_OPERATOR, - T_VARIABLE, - T_FUNCTION -} TOKEN; - -typedef enum { - O_UNDEF, /* undefined */ - O_LST, /* expression lists */ - O_SET, /* variable assignements */ - O_CND, /* conditional a?b:c */ - O_COL, /* colon in a?b:c */ - O_OR, /* logical OR */ - O_AND, /* logical AND */ - O_NEQ, /* numeric equal */ - O_NNE, /* numeric not equal */ - O_NLT, /* numeric less than */ - O_NLE, /* numeric less or equal */ - O_NGT, /* numeric greater than */ - O_NGE, /* numeric greater or equal */ - O_SEQ, /* string equal */ - O_SNE, /* string not equal */ - O_SLT, /* string less than */ - O_SLE, /* string less or equal */ - O_SGT, /* string greater than */ - O_SGE, /* string greater or equal */ - O_ADD, /* addition */ - O_SUB, /* subtraction */ - O_SGN, /* sign '-' */ - O_CAT, /* string concatenation */ - O_MUL, /* multiplication */ - O_DIV, /* division */ - O_MOD, /* modulo */ - O_POW, /* power */ - O_NOT, /* logical NOT */ - O_BRO, /* open brace */ - O_COM, /* comma (argument seperator) */ - O_BRC /* closing brace */ -} OPERATOR; - -typedef struct { - char *pattern; - int len; - OPERATOR op; -} PATTERN; - -typedef struct { - char *name; - RESULT *value; -} VARIABLE; - -typedef struct { - char *name; - int argc; - void (*func) (); -} FUNCTION; - -typedef struct _NODE { - TOKEN Token; - OPERATOR Operator; - RESULT *Result; - VARIABLE *Variable; - FUNCTION *Function; - int Children; - struct _NODE **Child; -} NODE; - - - -/* non-alphanumeric operators */ -/* IMPORTANT! list must be sorted by length! */ -static PATTERN Pattern1[] = { - {";", 1, O_LST}, /* expression lists */ - {"=", 1, O_SET}, /* variable assignements */ - {"?", 1, O_CND}, /* conditional a?b:c */ - {":", 1, O_COL}, /* colon a?b:c */ - {"|", 1, O_OR}, /* logical OR */ - {"&", 1, O_AND}, /* logical AND */ - {"<", 1, O_NLT}, /* numeric less than */ - {">", 1, O_NGT}, /* numeric greater than */ - {"+", 1, O_ADD}, /* addition */ - {"-", 1, O_SUB}, /* subtraction or sign */ - {".", 1, O_CAT}, /* string concatenation */ - {"*", 1, O_MUL}, /* multiplication */ - {"/", 1, O_DIV}, /* division */ - {"%", 1, O_MOD}, /* modulo */ - {"^", 1, O_POW}, /* power */ - {"!", 1, O_NOT}, /* logical NOT */ - {"(", 1, O_BRO}, /* open brace */ - {",", 1, O_COM}, /* comma (argument seperator) */ - {")", 1, O_BRC}, /* closing brace */ - {"==", 2, O_NEQ}, /* numeric equal */ - {"!=", 2, O_NNE}, /* numeric not equal */ - {"<=", 2, O_NLE}, /* numeric less or equal */ - {">=", 2, O_NGE} /* numeric greater or equal */ -}; - -/* alphanumeric operators */ -/* IMPORTANT! list must be sorted by length! */ -static PATTERN Pattern2[] = { - {"eq", 2, O_SEQ}, /* string equal */ - {"ne", 2, O_SNE}, /* string not equal */ - {"lt", 2, O_SLT}, /* string less than */ - {"le", 2, O_SLE}, /* string less or equal */ - {"gt", 2, O_SGT}, /* string greater than */ - {"ge", 2, O_SGE} /* string greater or equal */ -}; - - -static char *Expression = NULL; -static char *ExprPtr = NULL; -static char *Word = NULL; -static TOKEN Token = T_UNDEF; -static OPERATOR Operator = O_UNDEF; - -static VARIABLE Variable[255]; -static unsigned int nVariable = 0; - -static FUNCTION *Function = NULL; -static unsigned int nFunction = 0; - - -/* strndup() may be not available on several platforms */ -#ifndef HAVE_STRNDUP -char *strndup(const char *source, size_t len) -{ - char *tmp = NULL; - - if (source == NULL) - return NULL; - - if (len >= strlen(source)) - return strdup(source); - - tmp = malloc(len + 1); - if (tmp == 0) - return NULL; - - strncpy(tmp, source, len); - tmp[len] = '\0'; - - return (tmp); -} -#endif - - -void DelResult(RESULT * result) -{ - result->type = 0; - result->size = 0; - result->number = 0.0; - if (result->string) { - free(result->string); - result->string = NULL; - } -} - - -static void FreeResult(RESULT * result) -{ - if (result != NULL) { - DelResult(result); - free(result); - } -} - - -static RESULT *NewResult(void) -{ - RESULT *result = malloc(sizeof(RESULT)); - if (result == NULL) { - error("Evaluator: cannot allocate result: out of memory!"); - return NULL; - } - result->type = 0; - result->size = 0; - result->number = 0.0; - result->string = NULL; - - return result; -} - - -RESULT *SetResult(RESULT ** result, const int type, const void *value) -{ - if (*result == NULL) { - if ((*result = NewResult()) == NULL) - return NULL; - } else if (type == R_NUMBER) { - DelResult(*result); - } - - if (type == R_NUMBER) { - (*result)->type = R_NUMBER; - (*result)->size = 0; - (*result)->number = *(double *) value; - (*result)->string = NULL; - } - - else if (type == R_STRING) { - int len = strlen((char *) value); - (*result)->type = R_STRING; - (*result)->number = 0.0; - if ((*result)->string == NULL || len >= (*result)->size) { - /* buffer is either empty or too small */ - if ((*result)->string) - free((*result)->string); - /* allocate memory in multiples of CHUNK_SIZE */ - (*result)->size = CHUNK_SIZE * ((len + 1) / CHUNK_SIZE + 1); - (*result)->string = malloc((*result)->size); - } - strcpy((*result)->string, value); - } else { - error("Evaluator: internal error: invalid result type %d", type); - return NULL; - } - - return *result; -} - - -RESULT *CopyResult(RESULT ** result, RESULT * value) -{ - if (*result == NULL) { - if ((*result = NewResult()) == NULL) - return NULL; - } - - (*result)->type = value->type; - (*result)->number = value->number; - - if (value->string == NULL) { - (*result)->size = 0; - if ((*result)->string) - free((*result)->string); - (*result)->string = NULL; - } else { - /* is buffer large enough? */ - if ((*result)->string == NULL || value->size > (*result)->size) { - if ((*result)->string) - free((*result)->string); - (*result)->size = value->size; - (*result)->string = malloc((*result)->size); - } - strcpy((*result)->string, value->string); - } - return *result; -} - - -double R2N(RESULT * result) -{ - if (result == NULL) { - error("Evaluator: internal error: NULL result"); - return 0.0; - } - - if (result->type == 0) { - return 0.0; - } - - if (result->type & R_NUMBER) { - return result->number; - } - - if (result->type & R_STRING) { - result->type |= R_NUMBER; - result->number = atof(result->string); - return result->number; - } - - error("Evaluator: internal error: invalid result type %d", result->type); - return 0.0; -} - - -char *R2S(RESULT * result) -{ - if (result == NULL) { - error("Evaluator: internal error: NULL result"); - return NULL; - } - - if (result->type == 0) { - return NULL; - } - - if (result->type & R_STRING) { - return result->string; - } - - if (result->type & R_NUMBER) { - result->type |= R_STRING; - if (result->string) - free(result->string); - result->size = CHUNK_SIZE; - result->string = malloc(result->size); - snprintf(result->string, result->size, "%g", result->number); - return result->string; - } - - error("Evaluator: internal error: invalid result type %d", result->type); - return NULL; - -} - - -static VARIABLE *FindVariable(const char *name) -{ - unsigned int i; - - for (i = 0; i < nVariable; i++) { - if (strcmp(name, Variable[i].name) == 0) { - return &Variable[i]; - } - } - return NULL; -} - - -int SetVariable(const char *name, RESULT * value) -{ - VARIABLE *V; - - V = FindVariable(name); - if (V != NULL) { - CopyResult(&V->value, value); - return 1; - } - - if (nVariable >= sizeof(Variable) / sizeof(Variable[0])) { - error("Evaluator: cannot set variable <%s>: out of slots", name); - return -1; - } - - nVariable++; - Variable[nVariable - 1].name = strdup(name); - Variable[nVariable - 1].value = NULL; - CopyResult(&Variable[nVariable - 1].value, value); - - return 0; -} - - -int SetVariableNumeric(const char *name, const double value) -{ - RESULT result = { 0, 0, 0, NULL }; - RESULT *rp = &result; - - SetResult(&rp, R_NUMBER, &value); - - return SetVariable(name, rp); -} - - -int SetVariableString(const char *name, const char *value) -{ - RESULT result = { 0, 0, 0, NULL }; - RESULT *rp = &result; - - SetResult(&rp, R_STRING, value); - - return SetVariable(name, rp); -} - - -void DeleteVariables(void) -{ - unsigned int i; - - for (i = 0; i < nVariable; i++) { - free(Variable[i].name); - FreeResult(Variable[i].value); - } - nVariable = 0; -} - - -/* bsearch compare function for functions */ -static int LookupFunction(const void *a, const void *b) -{ - char *n = (char *) a; - FUNCTION *f = (FUNCTION *) b; - - return strcmp(n, f->name); -} - - -/* qsort compare function for functions */ -static int SortFunction(const void *a, const void *b) -{ - FUNCTION *fa = (FUNCTION *) a; - FUNCTION *fb = (FUNCTION *) b; - - return strcmp(fa->name, fb->name); -} - - -static FUNCTION *FindFunction(const char *name) -{ - return bsearch(name, Function, nFunction, sizeof(FUNCTION), LookupFunction); -} - - -int AddFunction(const char *name, const int argc, void (*func) ()) -{ - nFunction++; - Function = realloc(Function, nFunction * sizeof(FUNCTION)); - Function[nFunction - 1].name = strdup(name); - Function[nFunction - 1].argc = argc; - Function[nFunction - 1].func = func; - - qsort(Function, nFunction, sizeof(FUNCTION), SortFunction); - - return 0; -} - - -void DeleteFunctions(void) -{ - unsigned int i; - - for (i = 0; i < nFunction; i++) { - free(Function[i].name); - } - free(Function); - Function = NULL; - nFunction = 0; -} - - -#define is_space(c) ((c) == ' ' || (c) == '\t') -#define is_digit(c) ((c) >= '0' && (c) <= '9') -#define is_alpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z') || ((c) == '_')) -#define is_alnum(c) (is_alpha(c) || is_digit(c)) - -static void Parse(void) -{ - Token = T_UNDEF; - Operator = O_UNDEF; - - if (Word) { - free(Word); - Word = NULL; - } - - /* NULL expression? */ - if (ExprPtr == NULL) { - Word = strdup(""); - return; - } - - /* skip leading whitespace */ - while (is_space(*ExprPtr)) - ExprPtr++; - - /* names */ - if (is_alpha(*ExprPtr)) { - int i; - char *start = ExprPtr; - while (is_alnum(*ExprPtr)) - ExprPtr++; - if (*ExprPtr == ':' && *(ExprPtr + 1) == ':' && is_alpha(*(ExprPtr + 2))) { - ExprPtr += 3; - while (is_alnum(*ExprPtr)) - ExprPtr++; - } - Word = strndup(start, ExprPtr - start); - Token = T_NAME; - - /* check for alphanumeric operators */ - for (i = sizeof(Pattern2) / sizeof(Pattern2[0]) - 1; i >= 0; i--) { - if (strcmp(Word, Pattern2[i].pattern) == 0) { - Token = T_OPERATOR; - Operator = Pattern2[i].op; - break; - } - } - - } - - /* numbers */ - else if (is_digit(*ExprPtr) || (*ExprPtr == '.' && is_digit(*(ExprPtr + 1)))) { - char *start = ExprPtr; - while (is_digit(*ExprPtr)) - ExprPtr++; - if (*ExprPtr == '.') { - ExprPtr++; - while (is_digit(*ExprPtr)) - ExprPtr++; - } - Word = strndup(start, ExprPtr - start); - Token = T_NUMBER; - } - - /* strings */ - else if (*ExprPtr == '\'') { - size_t length = 0; - size_t size = CHUNK_SIZE; - Word = malloc(size); - ExprPtr++; - while (*ExprPtr != '\0' && *ExprPtr != '\'') { - if (*ExprPtr == '\\') { - switch (*(ExprPtr + 1)) { - case '\\': - case '\'': - Word[length++] = *(ExprPtr + 1); - ExprPtr += 2; - break; - case 'a': - Word[length++] = '\a'; - ExprPtr += 2; - break; - case 'b': - Word[length++] = '\b'; - ExprPtr += 2; - break; - case 't': - Word[length++] = '\t'; - ExprPtr += 2; - break; - case 'n': - Word[length++] = '\n'; - ExprPtr += 2; - break; - case 'v': - Word[length++] = '\v'; - ExprPtr += 2; - break; - case 'f': - Word[length++] = '\f'; - ExprPtr += 2; - break; - case 'r': - Word[length++] = '\r'; - ExprPtr += 2; - break; - case '0': - case '1': - case '2': - case '3': - if (*(ExprPtr + 2) >= '0' && *(ExprPtr + 2) <= '7' && - *(ExprPtr + 3) >= '0' && *(ExprPtr + 3) <= '7') { - Word[length++] = - (*(ExprPtr + 1) - '0') * 64 + (*(ExprPtr + 2) - '0') * 8 + (*(ExprPtr + 3) - '0'); - ExprPtr += 4; - } else { - error("Evaluator: illegal octal sequence '\\%c%c%c' in <%s>", - *(ExprPtr + 1), *(ExprPtr + 2), *(ExprPtr + 3), Expression); - Word[length++] = *ExprPtr++; - } - break; - default: - error("Evaluator: unknown escape sequence '\\%c' in <%s>", *(ExprPtr + 1), Expression); - Word[length++] = *ExprPtr++; - } - } else { - Word[length++] = *ExprPtr++; - } - if (length >= size) { - size += CHUNK_SIZE; - Word = realloc(Word, size); - } - } - Word[length] = '\0'; - Token = T_STRING; - if (*ExprPtr == '\'') { - ExprPtr++; - } else { - error("Evaluator: unterminated string in <%s>", Expression); - } - } - - /* non-alpha operators */ - else { - int i; - for (i = sizeof(Pattern1) / sizeof(Pattern1[0]) - 1; i >= 0; i--) { - int len = Pattern1[i].len; - if (strncmp(ExprPtr, Pattern1[i].pattern, Pattern1[i].len) == 0) { - Word = strndup(ExprPtr, len); - Token = T_OPERATOR; - Operator = Pattern1[i].op; - ExprPtr += len; - break; - } - } - } - - /* syntax check */ - if (Token == T_UNDEF && *ExprPtr != '\0') { - error("Evaluator: parse error in <%s>: garbage <%s>", Expression, ExprPtr); - } - - /* skip trailing whitespace */ - while (is_space(*ExprPtr)) - ExprPtr++; - - /* empty token */ - if (Word == NULL) - Word = strdup(""); -} - - -static NODE *NewNode(NODE * Child) -{ - NODE *N; - - N = malloc(sizeof(NODE)); - if (N == NULL) - return NULL; - - memset(N, 0, sizeof(NODE)); - N->Token = Token; - N->Operator = Operator; - - if (Child != NULL) { - N->Children = 1; - N->Child = malloc(sizeof(NODE *)); - N->Child[0] = Child; - } - - return N; - -} - - -static NODE *JunkNode(void) -{ - NODE *Junk; - - Junk = NewNode(NULL); - Junk->Token = T_STRING; - SetResult(&Junk->Result, R_STRING, ""); - - return Junk; -} - - -static void LinkNode(NODE * Root, NODE * Child) -{ - - if (Child == NULL) - return; - - Root->Children++; - Root->Child = realloc(Root->Child, Root->Children * sizeof(NODE *)); - if (Root->Child == NULL) - return; - Root->Child[Root->Children - 1] = Child; -} - - -/* forward declaration */ -static NODE *Level01(void); - - -/* literal numbers, variables, functions */ -static NODE *Level12(void) -{ - NODE *Root = NULL; - - if (Token == T_OPERATOR && Operator == O_BRO) { - Parse(); - Root = Level01(); - if (Token != T_OPERATOR || Operator != O_BRC) { - error("Evaluator: unbalanced parentheses in <%s>", Expression); - LinkNode(Root, JunkNode()); - } - } - - else if (Token == T_NUMBER) { - double value = atof(Word); - Root = NewNode(NULL); - SetResult(&Root->Result, R_NUMBER, &value); - } - - else if (Token == T_STRING) { - Root = NewNode(NULL); - SetResult(&Root->Result, R_STRING, Word); - } - - else if (Token == T_NAME) { - - /* look-ahead for opening brace */ - if (*ExprPtr == '(') { - int argc = 0; - Root = NewNode(NULL); - Root->Token = T_FUNCTION; - Root->Result = NewResult(); - Root->Function = FindFunction(Word); - if (Root->Function == NULL) { - error("Evaluator: unknown function '%s' in <%s>", Word, Expression); - Root->Token = T_STRING; - SetResult(&Root->Result, R_STRING, ""); - } - - /* opening brace */ - Parse(); - do { - Parse(); /* read argument */ - if (Token == T_OPERATOR && Operator == O_BRC) { - break; - } else if (Token == T_OPERATOR && Operator == O_COM) { - error("Evaluator: empty argument in <%s>", Expression); - LinkNode(Root, JunkNode()); - } else { - LinkNode(Root, Level01()); - } - argc++; - } while (Token == T_OPERATOR && Operator == O_COM); - - /* check for closing brace */ - if (Token != T_OPERATOR || Operator != O_BRC) { - error("Evaluator: missing closing brace in <%s>", Expression); - } - - /* check number of arguments */ - if (Root->Function != NULL && Root->Function->argc >= 0 && Root->Function->argc != argc) { - error("Evaluator: wrong number of arguments in <%s>", Expression); - while (argc < Root->Function->argc) { - LinkNode(Root, JunkNode()); - argc++; - } - } - - } else { - Root = NewNode(NULL); - Root->Token = T_VARIABLE; - Root->Result = NewResult(); - Root->Variable = FindVariable(Word); - if (Root->Variable == NULL) { - SetVariableString(Word, ""); - Root->Variable = FindVariable(Word); - } - } - } - - else { - error("Evaluator: syntax error in <%s>: <%s>", Expression, Word); - Root = NewNode(NULL); - Root->Token = T_STRING; - SetResult(&Root->Result, R_STRING, ""); - } - - Parse(); - return Root; - -} - - -/* unary + or - signs or logical 'not' */ -static NODE *Level11(void) -{ - NODE *Root; - TOKEN sign = T_UNDEF; - - if (Token == T_OPERATOR && (Operator == O_ADD || Operator == O_SUB || Operator == O_NOT)) { - sign = Operator; - if (sign == O_SUB) - sign = O_SGN; - Parse(); - } - - Root = Level12(); - - if (sign == O_SGN || sign == O_NOT) { - Root = NewNode(Root); - Root->Token = T_OPERATOR; - Root->Operator = sign; - } - - return Root; -} - - -/* x^y */ -static NODE *Level10(void) -{ - NODE *Root; - - Root = Level11(); - - while (Token == T_OPERATOR && Operator == O_POW) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level11()); - } - - return Root; -} - - -/* multiplication, division, modulo */ -static NODE *Level09(void) -{ - NODE *Root; - - Root = Level10(); - - while (Token == T_OPERATOR && (Operator == O_MUL || Operator == O_DIV || Operator == O_MOD)) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level10()); - } - - return Root; -} - - -/* addition, subtraction, string concatenation */ -static NODE *Level08(void) -{ - NODE *Root; - - Root = Level09(); - - while (Token == T_OPERATOR && (Operator == O_ADD || Operator == O_SUB || Operator == O_CAT)) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level09()); - } - - return Root; -} - - -/* relational operators */ -static NODE *Level07(void) -{ - NODE *Root; - - Root = Level08(); - - while (Token == T_OPERATOR && (Operator == O_NGT || Operator == O_NGE || Operator == O_NLT || Operator == O_NLE || - Operator == O_SGT || Operator == O_SGE || Operator == O_SLT || Operator == O_SLE)) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level08()); - } - - return Root; -} - - -/* equal, not equal */ -static NODE *Level06(void) -{ - NODE *Root; - - Root = Level07(); - - while (Token == T_OPERATOR && (Operator == O_NEQ || Operator == O_NNE || Operator == O_SEQ || Operator == O_SNE)) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level07()); - } - - return Root; -} - -/* logical 'and' */ -static NODE *Level05(void) -{ - NODE *Root; - - Root = Level06(); - - while (Token == T_OPERATOR && Operator == O_AND) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level06()); - } - - return Root; -} - - -/* logical 'or' */ -static NODE *Level04(void) -{ - NODE *Root; - - Root = Level05(); - - while (Token == T_OPERATOR && Operator == O_OR) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level05()); - } - - return Root; -} - - -/* conditional expression a?b:c */ -static NODE *Level03(void) -{ - NODE *Root; - - Root = Level04(); - - if (Token == T_OPERATOR && Operator == O_CND) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level04()); - if (Token == T_OPERATOR && Operator == O_COL) { - Parse(); - LinkNode(Root, Level04()); - } else { - error("Evaluator: syntax error in <%s>: expecting ':' got '%s'", Expression, Word); - LinkNode(Root, JunkNode()); - } - } - - return Root; -} - - -/* variable assignments */ -static NODE *Level02(void) -{ - NODE *Root; - - /* we have to do a look-ahead if it's really an assignment */ - if ((Token == T_NAME) && (*ExprPtr == '=') && (*(ExprPtr + 1) != '=')) { - char *name = strdup(Word); - VARIABLE *V = FindVariable(name); - if (V == NULL) { - SetVariableString(name, ""); - V = FindVariable(name); - } - Parse(); - Root = NewNode(NULL); - Root->Variable = V; - Parse(); - LinkNode(Root, Level03()); - free(name); - } else { - Root = Level03(); - } - - return Root; -} - - -/* expression lists */ -static NODE *Level01(void) -{ - NODE *Root; - - Root = Level02(); - - while (Token == T_OPERATOR && Operator == O_LST) { - Root = NewNode(Root); - Parse(); - LinkNode(Root, Level02()); - } - - return Root; -} - - -static int EvalTree(NODE * Root) -{ - int i; - int argc; - int type = -1; - double number = 0.0; - double dummy; - int freeme = 0; - char *string = NULL; - char *s1, *s2; - RESULT *param[10]; - - switch (Root->Token) { - - case T_NUMBER: - case T_STRING: - /* Root->Result already contains the value */ - return 0; - - case T_VARIABLE: - CopyResult(&Root->Result, Root->Variable->value); - return 0; - - case T_FUNCTION: - DelResult(Root->Result); - /* prepare parameter list */ - argc = Root->Children; - if (argc > 10) { - error("evaluator: more than 10 children (operands) not supported!"); - argc = 10; - } - for (i = 0; i < argc; i++) { - EvalTree(Root->Child[i]); - param[i] = Root->Child[i]->Result; - } - if (Root->Function->argc < 0) { - /* Function with variable argument list: */ - /* pass number of arguments as first parameter */ - Root->Function->func(Root->Result, argc, ¶m); - } else { - Root->Function->func(Root->Result, param[0], param[1], param[2], param[3], param[4], param[5], param[6], - param[7], param[8], param[9]); - } - return 0; - - case T_OPERATOR: - switch (Root->Operator) { - - case O_LST: /* expression list: result is last expression */ - for (i = 0; i < Root->Children; i++) { - EvalTree(Root->Child[i]); - } - i = Root->Children - 1; - type = Root->Child[i]->Result->type; - number = Root->Child[i]->Result->number; - string = Root->Child[i]->Result->string; - break; - - case O_SET: /* variable assignment */ - EvalTree(Root->Child[0]); - CopyResult(&Root->Variable->value, Root->Child[0]->Result); - type = Root->Child[0]->Result->type; - number = Root->Child[0]->Result->number; - string = Root->Child[0]->Result->string; - break; - - case O_CND: /* conditional expression */ - EvalTree(Root->Child[0]); - i = 1 + (R2N(Root->Child[0]->Result) == 0.0); - EvalTree(Root->Child[i]); - type = Root->Child[i]->Result->type; - number = Root->Child[i]->Result->number; - string = Root->Child[i]->Result->string; - break; - - case O_OR: /* logical OR */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - if (R2N(Root->Child[0]->Result) == 0.0) { - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[1]->Result) != 0.0); - } else { - number = 1.0; - } - break; - - case O_AND: /* logical AND */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - if (R2N(Root->Child[0]->Result) != 0.0) { - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[1]->Result) != 0.0); - } else { - number = 0.0; - } - break; - - case O_NEQ: /* numeric equal */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[0]->Result) == R2N(Root->Child[1]->Result)); - break; - - case O_NNE: /* numeric not equal */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[0]->Result) != R2N(Root->Child[1]->Result)); - break; - - case O_NLT: /* numeric less than */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[0]->Result) < R2N(Root->Child[1]->Result)); - break; - - case O_NLE: /* numeric less equal */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[0]->Result) <= R2N(Root->Child[1]->Result)); - break; - - case O_NGT: /* numeric greater than */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[0]->Result) > R2N(Root->Child[1]->Result)); - break; - - case O_NGE: /* numeric greater equal */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (R2N(Root->Child[0]->Result) >= R2N(Root->Child[1]->Result)); - break; - - case O_SEQ: /* string equal */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (strcmp(R2S(Root->Child[0]->Result), R2S(Root->Child[1]->Result)) == 0); - break; - - case O_SNE: /* string not equal */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (strcmp(R2S(Root->Child[0]->Result), R2S(Root->Child[1]->Result)) != 0); - break; - - case O_SLT: /* string less than */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (strcmp(R2S(Root->Child[0]->Result), R2S(Root->Child[1]->Result)) < 0); - break; - - case O_SLE: /* string less equal */ - type = R_NUMBER; - EvalTree(Root->Child[0]); - EvalTree(Root->Child[1]); - number = (strcmp(R2S(Root->Child[0]->Result), R2S(Root->Child[1]->Result)) <= 0); - break; - - case O_SGT: /* string greater than */ - type = R_NUMBER; - EvalTree(Root-& |
