librdesc
Loading...
Searching...
No Matches
bc_interpreter.h
Go to the documentation of this file.
1
6#include "../../include/rdesc.h"
7#include "../../src/detail.h"
8
9#include "../grammar/bc.h"
10
11#include <string.h>
12#include <stdlib.h>
13
14
15#ifndef BC_INTERPRETER_H
16#define BC_INTERPRETER_H
17
18
20static inline double bc_pow10(int i)
21{
22 double r = 1;
23
24 while (i--)
25 r *= 10;
26
27 return r;
28}
29
31static inline double bc_interpreter(struct rdesc_node *n)
32{
33 size_t v = n->n.nt.variant; /* variant */
34 struct rdesc_node **c = n->n.nt.children; /* children */
35
36 switch (n->n.nt.id) {
37 case NT_UNSIGNED:
38 switch (v) {
39 case 0:
40 return strtod(c[0]->n.tk.seminfo, NULL);
41 case 1:
42 return strtod(c[1]->n.tk.seminfo, NULL) /\
43 bc_pow10(strlen(c[1]->n.tk.seminfo));
44 default:
45 return strtod(c[0]->n.tk.seminfo, NULL) + \
46 strtod(c[2]->n.tk.seminfo, NULL) / \
47 bc_pow10(strlen(c[2]->n.tk.seminfo));
48 }
49
50 case NT_OPTSIGN:
51 return (v == 0) ? -1 : 1;
52
53 case NT_SIGNED:
54 return bc_interpreter(c[0]) * bc_interpreter(c[1]);
55
56 case NT_EXPR:
57 return bc_interpreter(c[0]) + bc_interpreter(c[1]);
58
59 case NT_EXPR_REST:
60 switch (v) {
61 case 0:
62 return bc_interpreter(c[1]);
63 case 1:
64 return -bc_interpreter(c[1]);
65 default:
66 return 0;
67 }
68
69 case NT_TERM:
70 return bc_interpreter(c[0]) * bc_interpreter(c[1]);
71
72 case NT_TERM_REST:
73 switch (v) {
74 case 0:
75 return bc_interpreter(c[1]);
76 case 1:
77 return 1 / bc_interpreter(c[1]);
78 default:
79 return 1;
80 }
81
82 case NT_FACTOR:
83 switch (v) {
84 case 0:
85 return bc_interpreter(c[0]);
86 default:
87 return bc_interpreter(c[1]);
88 }
89
90 case NT_STMT:
91 return bc_interpreter(c[0]);
92 }
93
94 unreachable(); // GCOV_EXCL_LINE
95}
96
98static inline void bc_tk_destroyer(struct rdesc_token *tk)
99{
100 if (tk->seminfo)
101 free(tk->seminfo);
102}
103
104
105#endif
#define r(...)
Macro to define a grammar rule. Adds end-of-body and construct sentinels to grammar rules.
Definition: bnf_dsl.h:72
A node in the CST.
Definition: rdesc.h:68
union rdesc_node::@0 n
struct rdesc_nonterminal nt
Definition: rdesc.h:74
struct rdesc_token tk
Definition: rdesc.h:73
uint16_t variant
The production rule variant being parsed.
Definition: rdesc.h:62
terminal (token) object for context-free grammar
Definition: rdesc.h:43
void * seminfo
Definition: rdesc.h:47