This repository has been archived by the owner on Sep 14, 2018. It is now read-only.
forked from matthiaskramm/mrscake
-
Notifications
You must be signed in to change notification settings - Fork 1
/
easy_ast.h
116 lines (98 loc) · 3.63 KB
/
easy_ast.h
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
#ifndef __easy_ast__
#define __easy_ast__
#include <assert.h>
#include "ast.h"
/* The macros in this file allow you to write code
in the following matter:
START_CODE
IF
GT
ADD
PARAM(column1)
PARAM(column2)
END;
PARAM(column3)
END;
THEN
INT_CONSTANT(1)
ELSE
INT_CONSTANT(2)
END;
END_CODE
*/
#define NODE_BEGIN(new_type,args...) \
do { \
node_t* new_node = node_new_with_args(new_type,##args); \
if(current_node) { \
node_append_child(current_node, (new_node)); \
} else { \
if(current_program) { \
assert(!(*current_program)); \
(*current_program) = new_node; \
} \
} \
if((new_node->type->flags) & NODE_FLAG_HAS_CHILDREN) { \
new_node->parent = current_node; \
current_node = new_node; \
} \
} while(0);
#define INSERT_NODE(new_node) \
do { \
node_append_child(current_node, (new_node)); \
} while(0);
#define NODE_CLOSE do {assert(current_node->num_children >= current_node->type->min_args && \
current_node->num_children <= current_node->type->max_args);\
current_node = current_node->parent; \
} while(0)
#define START_CODE(program) \
node_t* program = 0; \
{ \
node_t*current_node = 0; \
node_t**current_program = &program;
#define END_CODE \
}
#define END NODE_CLOSE
#define END_BLOCK NODE_CLOSE
#define BLOCK NODE_BEGIN(&node_block)
#define IF NODE_BEGIN(&node_if)
#define THEN assert(current_node && current_node->type == &node_if && current_node->num_children == 1);
#define ELSE assert(current_node && current_node->type == &node_if && current_node->num_children == 2);
#define ADD NODE_BEGIN(&node_add)
#define SUB NODE_BEGIN(&node_sub)
#define IN NODE_BEGIN(&node_in)
#define LT NODE_BEGIN(&node_lt)
#define LTE NODE_BEGIN(&node_lte)
#define GT NODE_BEGIN(&node_gt)
#define GTE NODE_BEGIN(&node_gte)
#define MUL NODE_BEGIN(&node_mul)
#define DIV NODE_BEGIN(&node_div)
#define EQUALS NODE_BEGIN(&node_equals)
#define NOT NODE_BEGIN(&node_not)
#define EXP NODE_BEGIN(&node_exp)
#define SQR NODE_BEGIN(&node_sqr)
#define NEG NODE_BEGIN(&node_neg)
#define ABS NODE_BEGIN(&node_abs)
#define NOP NODE_BEGIN(&node_nop)
#define PARAM(column) NODE_BEGIN(&node_param, (column)->index)
#define RAW_PARAM(index) NODE_BEGIN(&node_param, index)
#define GENERIC_CONSTANT(c) do {NODE_BEGIN(&node_constant, c)}while(0);
#define BOOL_CONSTANT(b) NODE_BEGIN(&node_bool, ((int)(b)))
#define MISSING_CONSTANT NODE_BEGIN(&node_missing)
#define FLOAT_CONSTANT(f) NODE_BEGIN(&node_float, f)
#define STRING_CONSTANT(s) do {VERIFY_STRING(s);NODE_BEGIN(&node_string, s)}while(0);
#define ARRAY_CONSTANT(a) INSERT_NODE(node_new_array((a)))
#define INT_CONSTANT(args...) NODE_BEGIN(&node_int, ##args)
#define CATEGORY_CONSTANT(args...) NODE_BEGIN(&node_category, ##args)
#define SETLOCAL(i) NODE_BEGIN(&node_setlocal, i)
#define GETLOCAL(i) NODE_BEGIN(&node_getlocal, i)
#define INCLOCAL(i) NODE_BEGIN(&node_inclocal, i)
#define BOOL_TO_FLOAT NODE_BEGIN(&node_bool_to_float)
#define ARG_MAX_F NODE_BEGIN(&node_arg_max)
#define ARG_MAX_I NODE_BEGIN(&node_arg_max_i)
#define ARRAY_AT_POS NODE_BEGIN(&node_array_at_pos)
#define ARRAY_AT_POS_INC NODE_BEGIN(&node_array_at_pos_inc)
#define ARRAY_ARG_MAX_I NODE_BEGIN(&node_array_arg_max_i)
#define ARRAY_NEW(size) NODE_BEGIN(&node_zero_int_array, size)
#define VERIFY_INT(n) do{if(0)(((char*)0)[(n)]);}while(0)
#define VERIFY_STRING(s) do{if(0){(s)[0];};}while(0)
#endif // __easy_ast__