2#include "interpreter.h"
13#include <rdesc/rdesc.h>
14#include <rdesc/cst_macros.h>
15#include <rdesc/util.h>
18double pm_interpreter(
struct rdesc *p,
24 return pm_interpreter(p,
rchild(p, n, 0));
33 return pm_interpret_pipe(p,
35 pm_interpreter(p,
rchild(p, n, 0)));
37 return pm_interpreter(p,
rchild(p, n, 0));
40 case NT_EXPONENTIATION_EXPR:
42 return pow(pm_extract_num(
rchild(p, n, 0)),
43 pm_interpreter(p,
rchild(p, n, 1)));
45 case NT_EXPONENTIATION_EXPR_REST:
48 return pow(pm_extract_num(
rchild(p, n, 1)),
49 pm_interpreter(p,
rchild(p, n, 2)));
61double pm_extract_num(
struct rdesc_node *num)
69 memcpy(&seminfo,
rseminfo(num),
sizeof(
char *));
71 double seminfo_num = atof(seminfo);
82double pm_interpret_pipe(
struct rdesc *p,
83 struct rdesc_node *pipe,
88 return pm_interpret_function(p,
rchild(p, pipe, 2),
89 pm_interpret_pipe(p,
rchild(p, pipe, 0), lhs));
92 return pm_interpret_function(p,
rchild(p, pipe, 0), lhs);
97static void collect_function_args(
struct rdesc *p,
98 struct rdesc_node *args,
99 size_t *argc,
double **argv)
104 case NT_FUNCTION_ARG_LS:
105 current_idx = (*argc)++;
107 collect_function_args(p,
rchild(p, args, 1), argc, argv);
111 case NT_FUNCTION_ARG_LS_REST:
114 current_idx = (*argc)++;
116 collect_function_args(p,
rchild(p, args, 2), argc, argv);
121 assert(*argv = malloc(
sizeof(
double) * *argc));
127 (*argv)[current_idx] =
128 pm_interpreter(p,
rchild(p, args,
rid(args) == NT_FUNCTION_ARG_LS ? 0 : 1));
131double pm_interpret_function(
struct rdesc *p,
132 struct rdesc_node *function,
138 memcpy(&function_name,
rseminfo(
rchild(p, function, 0)),
sizeof(
char *));
142 for (function_id = 0; function_id < pm_function_count; function_id++) {
143 if (strcmp(function_name, pm_function_names[function_id]) == 0)
152 collect_function_args(p,
rchild(p, function, 2), &argc, &argv);
155 if (function_id == pm_function_count) {
156 fprintf(stderr,
"Unknown function %s, ignoring\n", function_name);
160 result = pm_functions[function_id](lhs, argc, argv);
#define rid(node)
Returns the 15-bit identifier for underlying token/nonterminal.
#define rchild(p, nt_node, child_idx)
Returns child of the node by its index.
#define ralt_idx(nt_node)
Returns index of the nonterminal alternative in production rule.
#define rseminfo(tk_node)
Returns a reference to the token's seminfo field.
Recursive descent parser state.
void rdesc_flip_left(struct rdesc *parser, struct rdesc_node *parent, uint16_t child_index)
Rotates a right-recursive concrete syntax tree into a left-recursive form.