source: tags/ms_r16q2/AISC/aisc_eval.h

Last change on this file was 7811, checked in by westram, 13 years ago

merge from dev [7748] [7749] [7750]

  • comments (C→C++ style)
  • fixed umlauts in TREEGEN
File size: 2.5 KB
Line 
1//   Coded by Ralf Westram (coder@reallysoft.de) in March 2011   //
2//   Institute of Microbiology (Technical University Munich)     //
3//   http://www.arb-home.de/                                     //
4
5#ifndef AISC_EVAL_H
6#define AISC_EVAL_H
7
8#ifndef AISC_DEF_H
9#include "aisc_def.h"
10#endif
11#ifndef AISC_LOCATION_H
12#include "aisc_location.h"
13#endif
14#ifndef ARBTOOLS_H
15#include <arbtools.h>
16#endif
17
18class Expression : virtual Noncopyable {
19    const Data&     data;
20    const Location& loc;
21
22    int   used; // currently used size
23    int   bufsize; // including zero-byte
24    char *ebuffer;
25
26    bool allow_missing_ref;
27
28    bool was_evaluated;
29    int  errors_before;
30
31    char *eval_math(char *expr, char op_char);
32    char *evalPart(int start, int end, int& result_len);
33
34    bool evalRest(int offset);
35
36    char *evalBehind(int offset) {
37        aisc_assert(!was_evaluated);
38        char *toEval = strstr(ebuffer+offset, "$(");
39        return (!toEval || evalRest(toEval-ebuffer)) ? ebuffer : NULL;
40    }
41
42
43    char *report_result(char *s, bool& failed) {
44        int errors_after = Location::get_error_count();
45        failed           = errors_after != errors_before;
46
47        aisc_assert(!(failed && s));
48        if (s) {
49            aisc_assert(s == ebuffer);
50            ebuffer = NULL; // now owned by caller
51        }
52
53        was_evaluated = true;
54        return s;
55    }
56
57public:
58    Expression(const Data& data_, const Location& loc_, const char *str, bool allow_missing_ref_)
59        : data(data_),
60          loc(loc_),
61          allow_missing_ref(allow_missing_ref_), 
62          was_evaluated(false),
63          errors_before(Location::get_error_count())
64    {
65        used       = strlen(str);
66        bufsize    = used*2+1;
67        ebuffer = (char*)malloc(bufsize);
68        aisc_assert(used<bufsize);
69        memcpy(ebuffer, str, used+1);
70    }
71    ~Expression() {
72        aisc_assert(was_evaluated); // useless Expression
73        free(ebuffer);
74    }
75
76    char *evaluate(bool& failed) {
77        return report_result(evalBehind(0), failed);
78    }
79
80    char *evalVarDecl(bool& failed) {
81        // dont eval first '$('
82   
83        char *res = NULL;
84        char *varDecl  = strstr(ebuffer, "$(");
85        if (varDecl) {
86            res = evalBehind((varDecl+2)-ebuffer);
87        }
88        else {
89            print_error(&loc, "Expected identifier, i.e. '$(ident)'");
90        }
91        return report_result(res, failed);
92    }
93};
94
95
96
97#else
98#error aisc_eval.h included twice
99#endif // AISC_EVAL_H
Note: See TracBrowser for help on using the repository browser.