1 #include "exprast.h"
2 #include <ctype.h>
3
4 #define arglist_sizeof(l) (sizeof(RSArgList) + ((l) * sizeof(RSExpr *)))
5
RS_NewArgList(RSExpr * e)6 RSArgList *RS_NewArgList(RSExpr *e) {
7 RSArgList *ret = rm_malloc(arglist_sizeof(e ? 1 : 0));
8 ret->len = e ? 1 : 0;
9 if (e) ret->args[0] = e;
10 return ret;
11 }
12
RSArgList_Append(RSArgList * l,RSExpr * e)13 RSArgList *RSArgList_Append(RSArgList *l, RSExpr *e) {
14 l = rm_realloc(l, arglist_sizeof(l->len + 1));
15 l->args[l->len++] = e;
16 return l;
17 }
18
newExpr(RSExprType t)19 static RSExpr *newExpr(RSExprType t) {
20 RSExpr *e = rm_calloc(1, sizeof(*e));
21 e->t = t;
22 return e;
23 }
24
25 // unquote and unescape a stirng literal, and return a cleaned copy of it
unescpeStringDup(const char * s,size_t sz)26 char *unescpeStringDup(const char *s, size_t sz) {
27
28 char *dst = rm_malloc(sz);
29 char *dstStart = dst;
30 char *src = (char *)s + 1; // we start after the first quote
31 char *end = (char *)s + sz - 1; // we end at the last quote
32 while (src < end) {
33 // unescape
34 if (*src == '\\' && src + 1 < end && (ispunct(*(src + 1)) || isspace(*(src + 1)))) {
35 ++src;
36 continue;
37 }
38 *dst++ = *src++;
39 }
40 *dst = '\0';
41 return dstStart;
42 }
RS_NewStringLiteral(const char * str,size_t len)43 RSExpr *RS_NewStringLiteral(const char *str, size_t len) {
44 RSExpr *e = newExpr(RSExpr_Literal);
45 e->literal = RS_StaticValue(RSValue_String);
46 e->literal.strval.str = unescpeStringDup(str, len);
47 e->literal.strval.len = strlen(e->literal.strval.str);
48 e->literal.strval.stype = RSString_Malloc;
49 return e;
50 }
51
RS_NewNullLiteral()52 RSExpr *RS_NewNullLiteral() {
53 RSExpr *e = newExpr(RSExpr_Literal);
54 RSValue_MakeReference(&e->literal, RS_NullVal());
55 return e;
56 }
57
RS_NewNumberLiteral(double n)58 RSExpr *RS_NewNumberLiteral(double n) {
59 RSExpr *e = newExpr(RSExpr_Literal);
60
61 e->literal = RS_StaticValue(RSValue_Number);
62 e->literal.numval = n;
63 return e;
64 }
65
RS_NewOp(unsigned char op,RSExpr * left,RSExpr * right)66 RSExpr *RS_NewOp(unsigned char op, RSExpr *left, RSExpr *right) {
67 RSExpr *e = newExpr(RSExpr_Op);
68 e->op.op = op;
69 e->op.left = left;
70 e->op.right = right;
71 return e;
72 }
73
RS_NewPredicate(RSCondition cond,RSExpr * left,RSExpr * right)74 RSExpr *RS_NewPredicate(RSCondition cond, RSExpr *left, RSExpr *right) {
75 RSExpr *e = newExpr(RSExpr_Predicate);
76 e->pred.cond = cond;
77 e->pred.left = left;
78 e->pred.right = right;
79 // e->pred = (RSPredicate){
80 // .cond = cond,
81 // .left = left,
82 // .right = right,
83 // };
84 return e;
85 }
86
RS_NewFunc(const char * str,size_t len,RSArgList * args,RSFunction cb)87 RSExpr *RS_NewFunc(const char *str, size_t len, RSArgList *args, RSFunction cb) {
88 RSExpr *e = newExpr(RSExpr_Function);
89 e->func.args = args;
90 e->func.name = rm_strndup(str, len);
91 e->func.Call = cb;
92 return e;
93 }
94
RS_NewProp(const char * str,size_t len)95 RSExpr *RS_NewProp(const char *str, size_t len) {
96 RSExpr *e = newExpr(RSExpr_Property);
97 e->property.key = rm_strndup(str, len);
98 e->property.lookupObj = NULL;
99 return e;
100 }
101
RS_NewInverted(RSExpr * child)102 RSExpr *RS_NewInverted(RSExpr *child) {
103 RSExpr *e = newExpr(RSExpr_Inverted);
104 e->inverted.child = child;
105 return e;
106 }
107
RSArgList_Free(RSArgList * l)108 void RSArgList_Free(RSArgList *l) {
109 if (!l) return;
110 for (size_t i = 0; i < l->len; i++) {
111 RSExpr_Free(l->args[i]);
112 }
113 rm_free(l);
114 }
RSExpr_Free(RSExpr * e)115 void RSExpr_Free(RSExpr *e) {
116 if (!e) return;
117 switch (e->t) {
118 case RSExpr_Literal:
119 RSValue_Clear(&e->literal);
120 break;
121 case RSExpr_Function:
122 rm_free((char *)e->func.name);
123 RSArgList_Free(e->func.args);
124 break;
125 case RSExpr_Op:
126 RSExpr_Free(e->op.left);
127 RSExpr_Free(e->op.right);
128 break;
129 case RSExpr_Predicate:
130 RSExpr_Free(e->pred.left);
131 RSExpr_Free(e->pred.right);
132 break;
133 case RSExpr_Property:
134 rm_free((char *)e->property.key);
135 break;
136 case RSExpr_Inverted:
137 RSExpr_Free(e->inverted.child);
138 }
139 rm_free(e);
140 }
141
RSExpr_Print(const RSExpr * e)142 void RSExpr_Print(const RSExpr *e) {
143 if (!e) {
144 printf("NULL");
145 return;
146 }
147 switch (e->t) {
148 case RSExpr_Literal:
149 RSValue_Print(&e->literal);
150 break;
151 case RSExpr_Function:
152 printf("%s(", e->func.name);
153 for (size_t i = 0; e->func.args != NULL && i < e->func.args->len; i++) {
154 RSExpr_Print(e->func.args->args[i]);
155 if (i < e->func.args->len - 1) printf(", ");
156 }
157 printf(")");
158 break;
159 case RSExpr_Op:
160 printf("(");
161 RSExpr_Print(e->op.left);
162 printf(" %c ", e->op.op);
163 RSExpr_Print(e->op.right);
164 printf(")");
165 break;
166
167 case RSExpr_Predicate:
168 printf("(");
169 RSExpr_Print(e->pred.left);
170 printf(" %s ", RSConditionStrings[e->pred.cond]);
171 RSExpr_Print(e->pred.right);
172 printf(")");
173
174 break;
175 case RSExpr_Property:
176 printf("@%s", e->property.key);
177 break;
178 case RSExpr_Inverted:
179 printf("!");
180 RSExpr_Print(e->inverted.child);
181 break;
182 }
183 }
184
ExprAST_Free(RSExpr * e)185 void ExprAST_Free(RSExpr *e) {
186 RSExpr_Free(e);
187 }
188
ExprAST_Print(const RSExpr * e)189 void ExprAST_Print(const RSExpr *e) {
190 RSExpr_Print(e);
191 }
192
ExprAST_Parse(const char * e,size_t n,QueryError * status)193 RSExpr *ExprAST_Parse(const char *e, size_t n, QueryError *status) {
194 char *errtmp = NULL;
195 assert(!QueryError_HasError(status));
196
197 RSExpr *ret = RSExpr_Parse(e, n, &errtmp);
198 if (!ret) {
199 QueryError_SetError(status, QUERY_EEXPR, errtmp);
200 }
201 rm_free(errtmp);
202 return ret;
203 }
204