comparison lwlib/lw_expr.c @ 399:6153cb49403c

Initial commit of pragma newsource pragma newsource enables a source code variant as follows: 1. no line numbers 2. no implied comments at the end of lines 3. all comments must be introduced by a comment character 4. spaces are allowed in operands (4) is not quite complete. This commit handles "operandless" instructions (anything where the parser calls skip_operand()) and expression parsing.
author William Astle <lost@l-w.ca>
date Tue, 13 Oct 2015 23:38:02 -0600
parents 67373a053c49
children 052c5f335a92
comparison
equal deleted inserted replaced
398:4cf907aa634c 399:6153cb49403c
34 static lw_expr_fn3_t *parse_term = NULL; 34 static lw_expr_fn3_t *parse_term = NULL;
35 35
36 /* Q&D to break out of infinite recursion */ 36 /* Q&D to break out of infinite recursion */
37 static int level = 0; 37 static int level = 0;
38 static int bailing = 0; 38 static int bailing = 0;
39 static int parse_compact = 0;
39 40
40 static void (*divzero)(void *priv) = NULL; 41 static void (*divzero)(void *priv) = NULL;
41 42
42 static int expr_width = 0; 43 static int expr_width = 0;
43 44
1139 1140
1140 The end of an expression is determined by the presence of any of the 1141 The end of an expression is determined by the presence of any of the
1141 following conditions: 1142 following conditions:
1142 1143
1143 1. a NUL character 1144 1. a NUL character
1144 2. a whitespace character 1145 2. a whitespace character (if parse mode is "COMPACT")
1145 3. a ) 1146 3. a )
1146 4. a , 1147 4. a ,
1147 5. any character that is not recognized as a term 1148 5. any character that is not recognized as a term
1148 1149
1149 lw_expr_parse_term returns NULL if there is no term (end of expr, etc.) 1150 lw_expr_parse_term returns NULL if there is no term (end of expr, etc.)
1153 1154
1154 */ 1155 */
1155 1156
1156 lw_expr_t lw_expr_parse_expr(char **p, void *priv, int prec); 1157 lw_expr_t lw_expr_parse_expr(char **p, void *priv, int prec);
1157 1158
1159 static void lw_expr_parse_next_tok(char **p)
1160 {
1161 if (parse_compact)
1162 return;
1163 for (; **p && isspace(**p); (*p)++)
1164 /* do nothing */ ;
1165 }
1166
1158 lw_expr_t lw_expr_parse_term(char **p, void *priv) 1167 lw_expr_t lw_expr_parse_term(char **p, void *priv)
1159 { 1168 {
1160 lw_expr_t term, term2; 1169 lw_expr_t term, term2;
1161 1170
1162 eval_next: 1171 eval_next:
1172 lw_expr_parse_next_tok(p);
1173
1163 if (!**p || isspace(**p) || **p == ')' || **p == ']') 1174 if (!**p || isspace(**p) || **p == ')' || **p == ']')
1164 return NULL; 1175 return NULL;
1165
1166 // parentheses 1176 // parentheses
1167 if (**p == '(') 1177 if (**p == '(')
1168 { 1178 {
1169 (*p)++; 1179 (*p)++;
1170 term = lw_expr_parse_expr(p, priv, 0); 1180 term = lw_expr_parse_expr(p, priv, 0);
1181 lw_expr_parse_next_tok(p);
1171 if (**p != ')') 1182 if (**p != ')')
1172 { 1183 {
1173 lw_expr_destroy(term); 1184 lw_expr_destroy(term);
1174 return NULL; 1185 return NULL;
1175 } 1186 }
1245 }; 1256 };
1246 1257
1247 int opern, i; 1258 int opern, i;
1248 lw_expr_t term1, term2, term3; 1259 lw_expr_t term1, term2, term3;
1249 1260
1261 lw_expr_parse_next_tok(p);
1250 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';') 1262 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';')
1251 return NULL; 1263 return NULL;
1252 1264
1253 term1 = lw_expr_parse_term(p, priv); 1265 term1 = lw_expr_parse_term(p, priv);
1254 if (!term1) 1266 if (!term1)
1255 return NULL; 1267 return NULL;
1256 1268
1257 eval_next: 1269 eval_next:
1270 lw_expr_parse_next_tok(p);
1258 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';') 1271 if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';')
1259 return term1; 1272 return term1;
1260 1273
1261 // expecting an operator here 1274 // expecting an operator here
1262 for (opern = 0; operators[opern].opernum != lw_expr_oper_none; opern++) 1275 for (opern = 0; operators[opern].opernum != lw_expr_oper_none; opern++)
1310 goto eval_next; 1323 goto eval_next;
1311 } 1324 }
1312 1325
1313 lw_expr_t lw_expr_parse(char **p, void *priv) 1326 lw_expr_t lw_expr_parse(char **p, void *priv)
1314 { 1327 {
1328 parse_compact = 0;
1315 return lw_expr_parse_expr(p, priv, 0); 1329 return lw_expr_parse_expr(p, priv, 0);
1316 } 1330 }
1331
1332 lw_expr_t lw_expr_parse_compact(char **p, void *priv)
1333 {
1334 parse_compact = 1;
1335 return lw_expr_parse_expr(p, priv, 0);
1336 }
1337
1317 1338
1318 int lw_expr_testterms(lw_expr_t e, lw_expr_testfn_t *fn, void *priv) 1339 int lw_expr_testterms(lw_expr_t e, lw_expr_testfn_t *fn, void *priv)
1319 { 1340 {
1320 struct lw_expr_opers *o; 1341 struct lw_expr_opers *o;
1321 int r; 1342 int r;