Mercurial > hg > index.cgi
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; |