summaryrefslogtreecommitdiffstats
path: root/oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base
diff options
context:
space:
mode:
authorroot <root@krebs>2011-08-20 23:33:40 +0200
committerroot <root@krebs>2011-08-20 23:33:40 +0200
commit6b2cd5bb85d257f432923e22178c0559fe9656aa (patch)
tree46f16983868954dd5aec208cdbcfc8466d87eef3 /oncology/dpfhack_display/lcd4linux/.svn/text-base/evaluator.c.svn-base
parenta130ff747711005511c33f4c0714550f32e707f2 (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-base1430
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, &param);
- } 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->Child[0]);
- EvalTree(Root->Child[1]);
- number = (strcmp(R2S(Root->Child[0]->Result), R2S(Root->Child[1]->Result)) > 0);
- break;
-
- case O_SGE: /* string greater equal */
- type = R_NUMBER;
- EvalTree(Root->Child[0]);
- EvalTre