aboutsummaryrefslogtreecommitdiff
path: root/Source/Parser/wp_parser_c.h
blob: d810bd6857142acc75db03f21c8afb2c2083338f (plain) (blame)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef WP_PARSER_C_H_
#define WP_PARSER_C_H_

#include "wp_parser_y.h"

#ifdef __cplusplus
extern "C" {
#endif

    struct wp_parser* wp_c_parser_new (char const* function_body);

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

#include <set>
#include <string>

inline
double
wp_ast_eval (struct wp_node* node)
{
    double result;

    switch (node->type)
    {
    case WP_NUMBER:
        result = ((struct wp_number*)node)->value;
        break;
    case WP_SYMBOL:
        result = *(((struct wp_symbol*)node)->pointer);
        break;
    case WP_ADD:
        result = wp_ast_eval(node->l) + wp_ast_eval(node->r);
        break;
    case WP_SUB:
        result = wp_ast_eval(node->l) - wp_ast_eval(node->r);
        break;
    case WP_MUL:
        result = wp_ast_eval(node->l) * wp_ast_eval(node->r);
        break;
    case WP_DIV:
        result = wp_ast_eval(node->l) / wp_ast_eval(node->r);
        break;
    case WP_NEG:
        result = -wp_ast_eval(node->l);
        break;
    case WP_F1:
        result = wp_call_f1(((struct wp_f1*)node)->ftype,
                wp_ast_eval(((struct wp_f1*)node)->l));
        break;
    case WP_F2:
        result = wp_call_f2(((struct wp_f2*)node)->ftype,
                wp_ast_eval(((struct wp_f2*)node)->l),
                wp_ast_eval(((struct wp_f2*)node)->r));
        break;
    case WP_ADD_VP:
        result = node->lvp.v + *(node->rp);
        break;
    case WP_ADD_PP:
        result = *(node->lvp.p) + *(node->rp);
        break;
    case WP_SUB_VP:
        result = node->lvp.v - *(node->rp);
        break;
    case WP_SUB_PP:
        result = *(node->lvp.p) - *(node->rp);
        break;
    case WP_MUL_VP:
        result = node->lvp.v * *(node->rp);
        break;
    case WP_MUL_PP:
        result = *(node->lvp.p) * *(node->rp);
        break;
    case WP_DIV_VP:
        result = node->lvp.v / *(node->rp);
        break;
    case WP_DIV_PP:
        result = *(node->lvp.p) / *(node->rp);
        break;
    case WP_NEG_P:
        result = -*(node->lvp.p);
        break;
    default:
        yyerror("wp_ast_eval: unknown node type %d\n", node->type);
    }

    return result;
}

inline
void
wp_ast_get_symbols (struct wp_node* node, std::set<std::string>& symbols)
{
    switch (node->type)
    {
    case WP_NUMBER:
        break;
    case WP_SYMBOL:
        symbols.emplace(((struct wp_symbol*)node)->name);
        break;
    case WP_ADD:
    case WP_SUB:
    case WP_MUL:
    case WP_DIV:
    case WP_ADD_PP:
    case WP_SUB_PP:
    case WP_MUL_PP:
    case WP_DIV_PP:
        wp_ast_get_symbols(node->l, symbols);
        wp_ast_get_symbols(node->r, symbols);
        break;
    case WP_NEG:
    case WP_NEG_P:
        wp_ast_get_symbols(node->l, symbols);
        break;
    case WP_F1:
        wp_ast_get_symbols(((struct wp_f1*)node)->l, symbols);
        break;
    case WP_F2:
        wp_ast_get_symbols(((struct wp_f2*)node)->l, symbols);
        wp_ast_get_symbols(((struct wp_f2*)node)->r, symbols);
        break;
    case WP_ADD_VP:
    case WP_SUB_VP:
    case WP_MUL_VP:
    case WP_DIV_VP:
        wp_ast_get_symbols(node->r, symbols);
        break;
    default:
        yyerror("wp_ast_get_symbols: unknown node type %d\n", node->type);
    }
}

#endif

#endif