comparison lwasm/pseudo.c @ 55:bad2ee25acdd

Added string comparison pseudo ops
author lost@l-w.ca
date Tue, 05 Apr 2011 23:59:41 -0600
parents c6b8b455d67f
children 62372522ce9c
comparison
equal deleted inserted replaced
54:2077b755b8b4 55:bad2ee25acdd
20 */ 20 */
21 21
22 #include <stdio.h> 22 #include <stdio.h>
23 #include <ctype.h> 23 #include <ctype.h>
24 #include <string.h> 24 #include <string.h>
25 #include <stdlib.h>
25 26
26 #include <lw_alloc.h> 27 #include <lw_alloc.h>
27 28
28 #include "lwasm.h" 29 #include "lwasm.h"
29 #include "instab.h" 30 #include "instab.h"
1159 for (i = 0; i < l -> len; i++) 1160 for (i = 0; i < l -> len; i++)
1160 { 1161 {
1161 lwasm_emitexpr(l, e, 1); 1162 lwasm_emitexpr(l, e, 1);
1162 } 1163 }
1163 } 1164 }
1165
1166 /* string conditional argument parser */
1167 /*
1168 argument syntax:
1169
1170 a bare word ended by whitespace, comma, or NUL
1171 a double quote delimited string containing arbitrary printable characters
1172 a single quote delimited string containing arbitrary printable characters
1173
1174 In a double quoted string, a double quote cannot be represented.
1175 In a single quoted string, a single quote cannot be represented.
1176
1177 */
1178 char *strcond_parsearg(char **p)
1179 {
1180 char *arg;
1181 char *tstr;
1182 int i;
1183 tstr = *p;
1184
1185 if (!**p || isspace(**p))
1186 {
1187 return lw_strdup("");
1188 }
1189
1190 if (*tstr == '"')
1191 {
1192 // double quote delim
1193 tstr++;
1194 for (i = 0; tstr[i] && tstr[i] != '"'; i++)
1195 /* do nothing */ ;
1196
1197 arg = lw_alloc(i + 1);
1198 strncpy(arg, tstr, i);
1199 arg[i] = 0;
1200
1201 if (tstr[i])
1202 i++;
1203
1204 *p += i;
1205 return arg;
1206 }
1207 else if (*tstr == '\'')
1208 {
1209 // single quote delim
1210 tstr++;
1211 for (i = 0; tstr[i] && tstr[i] != '\''; i++)
1212 /* do nothing */ ;
1213
1214 arg = lw_alloc(i + 1);
1215 strncpy(arg, tstr, i);
1216 arg[i] = 0;
1217
1218 if (tstr[i])
1219 i++;
1220
1221 *p += i;
1222 return arg;
1223 }
1224 else
1225 {
1226 // bare word - whitespace or comma delim
1227 for (i = 0; tstr[i] && !isspace(tstr[i]) && tstr[i] != ','; i++)
1228 /* do nothing */ ;
1229
1230 arg = lw_alloc(i + 1);
1231 strncpy(arg, tstr, i);
1232 arg[i] = 0;
1233 if (tstr[i] == ',')
1234 i++;
1235
1236 *p += i;
1237 return arg;
1238 }
1239 }
1240
1241 /* string conditional helpers */
1242 /* return "1" for true, "0" for false */
1243 int strcond_eq(char **p)
1244 {
1245 char *arg1;
1246 char *arg2;
1247 int c = 0;
1248
1249 arg1 = strcond_parsearg(p);
1250 arg2 = strcond_parsearg(p);
1251
1252 if (strcmp(arg1, arg2) == 0)
1253 c = 1;
1254 lw_free(arg1);
1255 lw_free(arg2);
1256 return c;
1257 }
1258
1259 int strcond_ieq(char **p)
1260 {
1261 char *arg1;
1262 char *arg2;
1263 int c = 0;
1264
1265 arg1 = strcond_parsearg(p);
1266 arg2 = strcond_parsearg(p);
1267
1268 if (strcasecmp(arg1, arg2) == 0)
1269 c = 1;
1270 lw_free(arg1);
1271 lw_free(arg2);
1272 return c;
1273 }
1274
1275 int strcond_ne(char **p)
1276 {
1277 char *arg1;
1278 char *arg2;
1279 int c = 0;
1280
1281 arg1 = strcond_parsearg(p);
1282 arg2 = strcond_parsearg(p);
1283
1284 if (strcmp(arg1, arg2) != 0)
1285 c = 1;
1286 lw_free(arg1);
1287 lw_free(arg2);
1288 return c;
1289 }
1290
1291 int strcond_ine(char **p)
1292 {
1293 char *arg1;
1294 char *arg2;
1295 int c = 0;
1296
1297 arg1 = strcond_parsearg(p);
1298 arg2 = strcond_parsearg(p);
1299
1300 if (strcasecmp(arg1, arg2) != 0)
1301 c = 1;
1302 lw_free(arg1);
1303 lw_free(arg2);
1304 return c;
1305 }
1306
1307 int strcond_peq(char **p)
1308 {
1309 char *arg0;
1310 char *arg1;
1311 char *arg2;
1312 int plen;
1313 int c = 0;
1314
1315 arg0 = strcond_parsearg(p);
1316 arg1 = strcond_parsearg(p);
1317 arg2 = strcond_parsearg(p);
1318
1319 plen = strtol(arg0, NULL, 10);
1320 if (strlen(arg1) > plen)
1321 arg1[plen] = 0;
1322 if (strlen(arg2) > plen)
1323 arg2[plen] = 0;
1324
1325 if (strcmp(arg1, arg2) == 0)
1326 c = 1;
1327 lw_free(arg0);
1328 lw_free(arg1);
1329 lw_free(arg2);
1330 return c;
1331 }
1332
1333 int strcond_ipeq(char **p)
1334 {
1335 char *arg0;
1336 char *arg1;
1337 char *arg2;
1338 int plen;
1339 int c = 0;
1340
1341 arg0 = strcond_parsearg(p);
1342 arg1 = strcond_parsearg(p);
1343 arg2 = strcond_parsearg(p);
1344
1345 plen = strtol(arg0, NULL, 10);
1346 if (strlen(arg1) > plen)
1347 arg1[plen] = 0;
1348 if (strlen(arg2) > plen)
1349 arg2[plen] = 0;
1350
1351 if (strcasecmp(arg1, arg2) == 0)
1352 c = 1;
1353 lw_free(arg0);
1354 lw_free(arg1);
1355 lw_free(arg2);
1356 return c;
1357 }
1358
1359 int strcond_pne(char **p)
1360 {
1361 char *arg0;
1362 char *arg1;
1363 char *arg2;
1364 int plen;
1365 int c = 0;
1366
1367 arg0 = strcond_parsearg(p);
1368 arg1 = strcond_parsearg(p);
1369 arg2 = strcond_parsearg(p);
1370
1371 plen = strtol(arg0, NULL, 10);
1372 if (strlen(arg1) > plen)
1373 arg1[plen] = 0;
1374 if (strlen(arg2) > plen)
1375 arg2[plen] = 0;
1376
1377 if (strcmp(arg1, arg2) != 0)
1378 c = 1;
1379 lw_free(arg0);
1380 lw_free(arg1);
1381 lw_free(arg2);
1382 return c;
1383 }
1384
1385 int strcond_ipne(char **p)
1386 {
1387 char *arg0;
1388 char *arg1;
1389 char *arg2;
1390 int plen;
1391 int c = 0;
1392
1393 arg0 = strcond_parsearg(p);
1394 arg1 = strcond_parsearg(p);
1395 arg2 = strcond_parsearg(p);
1396
1397 plen = strtol(arg0, NULL, 10);
1398 if (strlen(arg1) > plen)
1399 arg1[plen] = 0;
1400 if (strlen(arg2) > plen)
1401 arg2[plen] = 0;
1402
1403 if (strcasecmp(arg1, arg2) != 0)
1404 c = 1;
1405 lw_free(arg0);
1406 lw_free(arg1);
1407 lw_free(arg2);
1408 return c;
1409 }
1410
1411 int strcond_seq(char **p)
1412 {
1413 char *arg0;
1414 char *arg1;
1415 char *arg2;
1416 char *rarg1;
1417 char *rarg2;
1418
1419 int plen;
1420 int c = 0;
1421
1422 arg0 = strcond_parsearg(p);
1423 arg1 = strcond_parsearg(p);
1424 arg2 = strcond_parsearg(p);
1425
1426 rarg1 = arg1;
1427 rarg2 = arg2;
1428
1429 plen = strtol(arg0, NULL, 10);
1430 if (strlen(arg1) > plen)
1431 {
1432 rarg1 += strlen(arg1) - plen;
1433 }
1434 if (strlen(arg2) > plen)
1435 {
1436 rarg2 += strlen(arg2) - plen;
1437 }
1438 if (strcmp(rarg1, rarg2) == 0)
1439 c = 1;
1440 lw_free(arg0);
1441 lw_free(arg1);
1442 lw_free(arg2);
1443 return c;
1444 }
1445
1446 int strcond_iseq(char **p)
1447 {
1448 char *arg0;
1449 char *arg1;
1450 char *arg2;
1451 char *rarg1;
1452 char *rarg2;
1453
1454 int plen;
1455 int c = 0;
1456
1457 arg0 = strcond_parsearg(p);
1458 arg1 = strcond_parsearg(p);
1459 arg2 = strcond_parsearg(p);
1460
1461 rarg1 = arg1;
1462 rarg2 = arg2;
1463
1464 plen = strtol(arg0, NULL, 10);
1465 if (strlen(arg1) > plen)
1466 {
1467 rarg1 += strlen(arg1) - plen;
1468 }
1469 if (strlen(arg2) > plen)
1470 {
1471 rarg2 += strlen(arg2) - plen;
1472 }
1473
1474 if (strcasecmp(rarg1, rarg2) == 0)
1475 c = 1;
1476 lw_free(arg0);
1477 lw_free(arg1);
1478 lw_free(arg2);
1479 return c;
1480 }
1481
1482
1483 int strcond_sne(char **p)
1484 {
1485 char *arg0;
1486 char *arg1;
1487 char *arg2;
1488 char *rarg1;
1489 char *rarg2;
1490
1491 int plen;
1492 int c = 0;
1493
1494 arg0 = strcond_parsearg(p);
1495 arg1 = strcond_parsearg(p);
1496 arg2 = strcond_parsearg(p);
1497
1498 rarg1 = arg1;
1499 rarg2 = arg2;
1500
1501 plen = strtol(arg0, NULL, 10);
1502 if (strlen(arg1) > plen)
1503 {
1504 rarg1 += strlen(arg1) - plen;
1505 }
1506 if (strlen(arg2) > plen)
1507 {
1508 rarg2 += strlen(arg2) - plen;
1509 }
1510
1511 if (strcmp(rarg1, rarg2) != 0)
1512 c = 1;
1513 lw_free(arg0);
1514 lw_free(arg1);
1515 lw_free(arg2);
1516 return c;
1517 }
1518
1519 int strcond_isne(char **p)
1520 {
1521 char *arg0;
1522 char *arg1;
1523 char *arg2;
1524 char *rarg1;
1525 char *rarg2;
1526
1527 int plen;
1528 int c = 0;
1529
1530 arg0 = strcond_parsearg(p);
1531 arg1 = strcond_parsearg(p);
1532 arg2 = strcond_parsearg(p);
1533
1534 rarg1 = arg1;
1535 rarg2 = arg2;
1536
1537 plen = strtol(arg0, NULL, 10);
1538 if (strlen(arg1) > plen)
1539 {
1540 rarg1 += strlen(arg1) - plen;
1541 }
1542 if (strlen(arg2) > plen)
1543 {
1544 rarg2 += strlen(arg2) - plen;
1545 }
1546
1547 if (strcasecmp(rarg1, rarg2) != 0)
1548 c = 1;
1549 lw_free(arg0);
1550 lw_free(arg1);
1551 lw_free(arg2);
1552 return c;
1553 }
1554
1555 /* string conditionals */
1556 PARSEFUNC(pseudo_parse_ifstr)
1557 {
1558 static struct strconds
1559 {
1560 char *str;
1561 int (*fn)(char **ptr);
1562 } strops[] = {
1563 { "eq", strcond_eq },
1564 { "ieq", strcond_ieq },
1565 { "ne", strcond_ne },
1566 { "ine", strcond_ine },
1567 { "peq", strcond_peq },
1568 { "ipeq", strcond_ipeq },
1569 { "pne", strcond_pne },
1570 { "ipne", strcond_ipne },
1571 { "seq", strcond_seq },
1572 { "iseq", strcond_iseq },
1573 { "sne", strcond_sne },
1574 { "isne", strcond_isne },
1575 { NULL, 0 }
1576 };
1577 int tv = 0;
1578 char *tstr;
1579 int i, strop;
1580
1581 l -> len = 0;
1582
1583 if (as -> skipcond && !(as -> skipmacro))
1584 {
1585 as -> skipcount++;
1586 skip_operand(p);
1587 return;
1588 }
1589
1590 tstr = strcond_parsearg(p);
1591 if (!**p || isspace(**p))
1592 {
1593 lwasm_register_error(as, l, "Bad string condition");
1594 return;
1595 }
1596
1597 for (strop = 0; strops[strop].str != NULL; strop++)
1598 if (strcasecmp(strops[strop].str, tstr) == 0)
1599 break;
1600
1601 lw_free(tstr);
1602
1603 if (strops[strop].str == NULL)
1604 {
1605 lwasm_register_error(as, l, "Bad string condition");
1606 }
1607
1608 tv = (*(strops[strop].fn))(p);
1609
1610 if (!tv)
1611 {
1612 as -> skipcond = 1;
1613 as -> skipcount = 1;
1614 }
1615 }