From 3aefe07876179e73131a7659e758bb13a2480006 Mon Sep 17 00:00:00 2001 From: Costa Tsaousis Date: Wed, 10 Aug 2016 20:12:46 +0300 Subject: infix notation parser almost done; preparing the evaluator and variables lookup --- profile/benchmark-dictionary.c | 7 -- profile/benchmark-registry.c | 4 +- profile/test-eval.c | 165 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 profile/test-eval.c (limited to 'profile') diff --git a/profile/benchmark-dictionary.c b/profile/benchmark-dictionary.c index 846e3c61ac..8ec3ae0318 100644 --- a/profile/benchmark-dictionary.c +++ b/profile/benchmark-dictionary.c @@ -7,13 +7,6 @@ * */ -#include -#include -#include - -#include "dictionary.h" -#include "main.h" -#include "log.h" #include "common.h" struct myvalue { diff --git a/profile/benchmark-registry.c b/profile/benchmark-registry.c index 68475eae09..fd771a7a78 100755 --- a/profile/benchmark-registry.c +++ b/profile/benchmark-registry.c @@ -1,13 +1,15 @@ /* * compile with - * gcc -O1 -ggdb -Wall -Wextra -I ../src/ -I ../ -o benchmark-registry benchmark-registry.c ../src/dictionary.o ../src/log.o ../src/avl.o ../src/common.o ../src/appconfig.o ../src/web_buffer.o ../src/storage_number.o ../src/rrd.o -pthread -luuid -lm -DHAVE_CONFIG_H -DVARLIB_DIR="\"/tmp\"" + * gcc -O1 -ggdb -Wall -Wextra -I ../src/ -I ../ -o benchmark-registry benchmark-registry.c ../src/dictionary.o ../src/log.o ../src/avl.o ../src/common.o ../src/appconfig.o ../src/web_buffer.o ../src/storage_number.o ../src/rrd.o ../src/health.o -pthread -luuid -lm -DHAVE_CONFIG_H -DVARLIB_DIR="\"/tmp\"" */ char *hostname = "me"; #include "../src/registry.c" +void netdata_cleanup_and_exit(int ret) { exit(ret); } + // ---------------------------------------------------------------------------- // TESTS diff --git a/profile/test-eval.c b/profile/test-eval.c new file mode 100644 index 0000000000..509eab5662 --- /dev/null +++ b/profile/test-eval.c @@ -0,0 +1,165 @@ + +/* + * 1. build netdata (as normally) + * 2. cd profile/ + * 3. compile with: + * gcc -O1 -ggdb -Wall -Wextra -I ../src/ -I ../ -o test-eval test-eval.c ../src/log.o ../src/eval.o ../src/common.o -pthread + * + */ + +#include "common.h" + +void netdata_cleanup_and_exit(int ret) { exit(ret); } + +void indent(int level, int show) { + int i = level; + while(i--) printf(" | "); + if(show) printf(" \\_ "); + else printf(" \\_ "); +} + +void print_operand(EVAL_OPERAND *op, int level); + +void print_value(EVAL_VALUE *v, int level) { + indent(level, 0); + + switch(v->type) { + case EVAL_VALUE_INVALID: + printf("VALUE (NOP)\n"); + break; + + case EVAL_VALUE_NUMBER: + printf("VALUE %Lf (NUMBER)\n", v->number); + break; + + case EVAL_VALUE_EXPRESSION: + printf("VALUE (SUB-EXPRESSION)\n"); + print_operand(v->expression, level+1); + break; + + default: + printf("VALUE (INVALID type %d)\n", v->type); + break; + + } +} + +void print_operand(EVAL_OPERAND *op, int level) { + +// if(op->operator != EVAL_OPERATOR_NOP) { + indent(level, 1); + if(op->operator) printf("%c (OPERATOR %d, prec: %d)\n", op->operator, op->id, op->precedence); + else printf("NOP (OPERATOR %d, prec: %d)\n", op->id, op->precedence); +// } + + int i = op->count; + while(i--) print_value(&op->ops[i], level + 1); +} + +calculated_number evaluate(EVAL_OPERAND *op); + +calculated_number evaluate_value(EVAL_VALUE *v) { + switch(v->type) { + case EVAL_VALUE_NUMBER: + return v->number; + + case EVAL_VALUE_EXPRESSION: + return evaluate(v->expression); + + default: + fatal("I don't know how to handle EVAL_VALUE type %d", v->type); + } +} + +calculated_number evaluate(EVAL_OPERAND *op) { + calculated_number n1, n2, r; + + switch(op->operator) { + case EVAL_OPERATOR_SIGN_PLUS: + r = evaluate_value(&op->ops[0]); + break; + + case EVAL_OPERATOR_SIGN_MINUS: + r = -evaluate_value(&op->ops[0]); + break; + + case EVAL_OPERATOR_PLUS: + if(op->count != 2) + fatal("Operator '%c' requires 2 values, but we have %d", op->operator, op->count); + n1 = evaluate_value(&op->ops[0]); + n2 = evaluate_value(&op->ops[1]); + r = n1 + n2; + printf("%Lf = %Lf %c %Lf\n", r, n1, op->operator, n2); + break; + + case EVAL_OPERATOR_MINUS: + if(op->count != 2) + fatal("Operator '%c' requires 2 values, but we have %d", op->operator, op->count); + n1 = evaluate_value(&op->ops[0]); + n2 = evaluate_value(&op->ops[1]); + r = n1 - n2; + printf("%Lf = %Lf %c %Lf\n", r, n1, op->operator, n2); + break; + + case EVAL_OPERATOR_MULTIPLY: + if(op->count != 2) + fatal("Operator '%c' requires 2 values, but we have %d", op->operator, op->count); + n1 = evaluate_value(&op->ops[0]); + n2 = evaluate_value(&op->ops[1]); + r = n1 * n2; + printf("%Lf = %Lf %c %Lf\n", r, n1, op->operator, n2); + break; + + case EVAL_OPERATOR_DIVIDE: + if(op->count != 2) + fatal("Operator '%c' requires 2 values, but we have %d", op->operator, op->count); + n1 = evaluate_value(&op->ops[0]); + n2 = evaluate_value(&op->ops[1]); + r = n1 / n2; + printf("%Lf = %Lf %c %Lf\n", r, n1, op->operator, n2); + break; + + case EVAL_OPERATOR_EXPRESSION_OPEN: + printf("BEGIN SUB-EXPRESSION\n"); + r = evaluate_value(&op->ops[0]); + printf("END SUB-EXPRESSION\n"); + break; + + case EVAL_OPERATOR_NOP: + case EVAL_OPERATOR_VALUE: + r = evaluate_value(&op->ops[0]); + break; + + default: + fatal("I don't know how to handle operator '%c'", op->operator); + break; + } + + return r; +} + +void print_expression(EVAL_OPERAND *op, const char *failed_at, int error) { + if(op) { + printf("\n"); + print_operand(op, 0); + evaluate(op); + free_expression(op); + } + else { + printf("error: %d, failed_at: '%s'\n", error, (failed_at)?failed_at:""); + } +} + + +int main(int argc, char **argv) { + if(argc != 2) { + fprintf(stderr, "I need an epxression\n"); + exit(1); + } + + const char *failed_at = NULL; + int error; + EVAL_OPERAND *op = parse_expression(argv[1], &failed_at, &error); + print_expression(op, failed_at, error); + return 0; +} -- cgit v1.2.3