File: aisc_eval.h

package info (click to toggle)
arb 6.0.6-8
  • links: PTS, VCS
  • area: non-free
  • in suites: sid, trixie
  • size: 66,204 kB
  • sloc: ansic: 394,911; cpp: 250,290; makefile: 19,644; sh: 15,879; perl: 10,473; fortran: 6,019; ruby: 683; xml: 503; python: 53; awk: 32
file content (99 lines) | stat: -rw-r--r-- 2,514 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//   Coded by Ralf Westram (coder@reallysoft.de) in March 2011   //
//   Institute of Microbiology (Technical University Munich)     //
//   http://www.arb-home.de/                                     //

#ifndef AISC_EVAL_H
#define AISC_EVAL_H

#ifndef AISC_DEF_H
#include "aisc_def.h"
#endif
#ifndef AISC_LOCATION_H
#include "aisc_location.h"
#endif
#ifndef ARBTOOLS_H
#include <arbtools.h>
#endif

class Expression : virtual Noncopyable {
    const Data&     data;
    const Location& loc;

    int   used; // currently used size
    int   bufsize; // including zero-byte
    char *ebuffer;

    bool allow_missing_ref;

    bool was_evaluated;
    int  errors_before;

    char *eval_math(char *expr, char op_char);
    char *evalPart(int start, int end, int& result_len);

    bool evalRest(int offset);

    char *evalBehind(int offset) {
        aisc_assert(!was_evaluated);
        char *toEval = strstr(ebuffer+offset, "$(");
        return (!toEval || evalRest(toEval-ebuffer)) ? ebuffer : NULL;
    }


    char *report_result(char *s, bool& failed) {
        int errors_after = Location::get_error_count();
        failed           = errors_after != errors_before;

        aisc_assert(!(failed && s));
        if (s) {
            aisc_assert(s == ebuffer);
            ebuffer = NULL; // now owned by caller
        }

        was_evaluated = true;
        return s;
    }

public:
    Expression(const Data& data_, const Location& loc_, const char *str, bool allow_missing_ref_)
        : data(data_),
          loc(loc_),
          allow_missing_ref(allow_missing_ref_), 
          was_evaluated(false),
          errors_before(Location::get_error_count())
    {
        used       = strlen(str);
        bufsize    = used*2+1;
        ebuffer = (char*)malloc(bufsize);
        aisc_assert(used<bufsize);
        memcpy(ebuffer, str, used+1);
    }
    ~Expression() {
        aisc_assert(was_evaluated); // useless Expression
        free(ebuffer);
    }

    char *evaluate(bool& failed) {
        return report_result(evalBehind(0), failed);
    }

    char *evalVarDecl(bool& failed) {
        // dont eval first '$('
    
        char *res = NULL;
        char *varDecl  = strstr(ebuffer, "$(");
        if (varDecl) {
            res = evalBehind((varDecl+2)-ebuffer);
        }
        else {
            print_error(&loc, "Expected identifier, i.e. '$(ident)'");
        }
        return report_result(res, failed);
    }
};



#else
#error aisc_eval.h included twice
#endif // AISC_EVAL_H