|
|
@@ -1347,2579 +1347,2515 @@ Listing:
|
|
|
1329 | DisposeStat
|
|
|
1330 | IncDecStat
|
|
|
1331 | InclExclStat
|
|
|
- 1332 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
- 1333 QbeGen.Jmp(lx)
|
|
|
- 1334 ELSE SemError(230) END;
|
|
|
- 1335 astStmt := AST.MakeNode(AST.NkExit); .) ) .
|
|
|
- 1336 (* INCL(set, elem) / EXCL(set, elem): PIM set-element builtins. *)
|
|
|
- 1337 InclExclStat (. VAR at, et2: SymTab.TypeIndex;
|
|
|
- 1338 dk: INTEGER;
|
|
|
- 1339 qd, qe: QbeGen.QVal;
|
|
|
- 1340 qn: SymTab.Name;
|
|
|
- 1341 sfx, isInc: BOOLEAN;
|
|
|
- 1342 astNode, astD: AST.Node; .)
|
|
|
- 1343 = ( "INCL" (. isInc := TRUE; .)
|
|
|
- 1344 | "EXCL" (. isInc := FALSE; .) )
|
|
|
- 1345 "(" Design<at, dk, qd, qn, sfx> (. astD := astCur; .) ","
|
|
|
- 1346 Expr<et2, qe> ")"
|
|
|
- 1347 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1348 IF isInc THEN
|
|
|
- 1349 AST.SetChild(astNode, 0,
|
|
|
- 1350 AST.MakeLeaf(AST.NkIdent, "INCL"))
|
|
|
- 1351 ELSE AST.SetChild(astNode, 0,
|
|
|
- 1352 AST.MakeLeaf(AST.NkIdent, "EXCL"))
|
|
|
- 1353 END;
|
|
|
- 1354 IF astD # AST.NoNode THEN
|
|
|
- 1355 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1356 IF astCur # AST.NoNode THEN
|
|
|
- 1357 AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 1358 astStmt := astNode; .)
|
|
|
- 1359 (. IF at = SymTab.InvalidType THEN
|
|
|
- 1360 ELSIF SymTab.ClassOf(at) #
|
|
|
- 1361 SymTab.ClSet THEN
|
|
|
- 1362 SemError(222)
|
|
|
- 1363 ELSE
|
|
|
- 1364 IF isInc THEN
|
|
|
- 1365 QbeGen.SetBit(qd, qe,
|
|
|
- 1366 SymTab.SetBaseLo(at),
|
|
|
- 1367 SymTab.SetCount(at))
|
|
|
- 1368 ELSE
|
|
|
- 1369 QbeGen.SetClearBit(qd, qe,
|
|
|
- 1370 SymTab.SetBaseLo(at),
|
|
|
- 1371 SymTab.SetCount(at))
|
|
|
- 1372 END
|
|
|
- 1373 END; .) .
|
|
|
- 1374 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
- 1375 integer designator. *)
|
|
|
- 1376 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
- 1377 dk: INTEGER;
|
|
|
- 1378 qd, qv, qn2, qstep:
|
|
|
- 1379 QbeGen.QVal;
|
|
|
- 1380 qn: SymTab.Name;
|
|
|
- 1381 sfx, isInc: BOOLEAN;
|
|
|
- 1382 astNode, astD, astStep:
|
|
|
- 1383 AST.Node; .)
|
|
|
- 1384 = (. isInc := TRUE; .)
|
|
|
- 1385 ( "INC" (. isInc := TRUE; .)
|
|
|
- 1386 | "DEC" (. isInc := FALSE; .) )
|
|
|
- 1387 "(" (. QbeGen.CopyOp("1", qstep); astStep := AST.NoNode; .)
|
|
|
- 1388 Design<dt, dk, qd, qn, sfx> (. astD := astCur; .)
|
|
|
- 1389 [ "," Expr<et2, qstep> (. astStep := astCur; .) ]
|
|
|
- 1390 ")" (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1391 IF isInc THEN
|
|
|
- 1392 AST.SetChild(astNode, 0,
|
|
|
- 1393 AST.MakeLeaf(AST.NkIdent, "INC"))
|
|
|
- 1394 ELSE AST.SetChild(astNode, 0,
|
|
|
- 1395 AST.MakeLeaf(AST.NkIdent, "DEC"))
|
|
|
- 1396 END;
|
|
|
- 1397 IF astD # AST.NoNode THEN
|
|
|
- 1398 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1399 IF astStep # AST.NoNode THEN
|
|
|
- 1400 AST.SetChild(astNode, 2, astStep) END;
|
|
|
- 1401 astStmt := astNode; .) (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1402 ELSIF (dk # SymTab.KindVar)
|
|
|
- 1403 AND (dk # SymTab.KindParam)
|
|
|
- 1404 AND (dk # SymTab.KindField) THEN
|
|
|
- 1405 SemError(210)
|
|
|
- 1406 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
- 1407 SemError(211)
|
|
|
- 1408 ELSE
|
|
|
- 1409 IF sfx
|
|
|
- 1410 OR (dk = SymTab.KindField) THEN
|
|
|
- 1411 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
- 1412 ELSE QbeGen.LoadVar(qn,
|
|
|
- 1413 FALSE, qv)
|
|
|
- 1414 END;
|
|
|
- 1415 QbeGen.NewTemp(qn2);
|
|
|
- 1416 IF isInc THEN
|
|
|
- 1417 QbeGen.Op3("add", qn2, qv,
|
|
|
- 1418 qstep, FALSE)
|
|
|
- 1419 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
- 1420 qstep, FALSE)
|
|
|
- 1421 END;
|
|
|
- 1422 IF sfx
|
|
|
- 1423 OR (dk = SymTab.KindField) THEN
|
|
|
- 1424 QbeGen.ElemStore(qd, qn2,
|
|
|
- 1425 dt)
|
|
|
- 1426 ELSE QbeGen.StoreVar(qn,
|
|
|
- 1427 qn2, FALSE)
|
|
|
- 1428 END
|
|
|
- 1429 END; .) .
|
|
|
- 1430 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
- 1431 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
- 1432 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
- 1433 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 1434 dk: INTEGER;
|
|
|
- 1435 qd, qm: QbeGen.QVal;
|
|
|
- 1436 qn: SymTab.Name;
|
|
|
- 1437 sfx: BOOLEAN;
|
|
|
- 1438 bt: SymTab.TypeIndex;
|
|
|
- 1439 astNode, astD: AST.Node; .)
|
|
|
- 1440 = "NEW" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
- 1441 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1442 AST.SetChild(astNode, 0,
|
|
|
- 1443 AST.MakeLeaf(AST.NkIdent, "NEW"));
|
|
|
- 1444 IF astD # AST.NoNode THEN
|
|
|
- 1445 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1446 astStmt := astNode; .)
|
|
|
- 1447 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1448 ELSIF (dk # SymTab.KindVar)
|
|
|
- 1449 AND (dk # SymTab.KindParam)
|
|
|
- 1450 AND (dk # SymTab.KindField) THEN
|
|
|
- 1451 SemError(210)
|
|
|
- 1452 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 1453 SymTab.ClPtr THEN
|
|
|
- 1454 SemError(219)
|
|
|
- 1455 ELSE bt := SymTab.PtrBase(dt);
|
|
|
- 1456 IF bt #
|
|
|
- 1457 SymTab.InvalidType THEN
|
|
|
- 1458 QbeGen.NewHeap(bt, qm);
|
|
|
- 1459 QbeGen.InitHeap(qm, bt);
|
|
|
- 1460 IF sfx
|
|
|
- 1461 OR (dk =
|
|
|
- 1462 SymTab.KindField) THEN
|
|
|
- 1463 QbeGen.ElemStore(qd, qm,
|
|
|
- 1464 dt)
|
|
|
- 1465 ELSE QbeGen.StorePtr(qn,
|
|
|
- 1466 qm)
|
|
|
- 1467 END
|
|
|
- 1468 END
|
|
|
- 1469 END; .) .
|
|
|
- 1470 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 1471 dk: INTEGER;
|
|
|
- 1472 qd, qv: QbeGen.QVal;
|
|
|
- 1473 qn: SymTab.Name;
|
|
|
- 1474 sfx: BOOLEAN;
|
|
|
- 1475 astNode, astD: AST.Node; .)
|
|
|
- 1476 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
- 1477 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1478 AST.SetChild(astNode, 0,
|
|
|
- 1479 AST.MakeLeaf(AST.NkIdent, "DISPOSE"));
|
|
|
- 1480 IF astD # AST.NoNode THEN
|
|
|
- 1481 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1482 astStmt := astNode; .)
|
|
|
- 1483 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1484 ELSIF (dk # SymTab.KindVar)
|
|
|
- 1485 AND (dk # SymTab.KindParam)
|
|
|
- 1486 AND (dk # SymTab.KindField) THEN
|
|
|
- 1487 SemError(210)
|
|
|
- 1488 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 1489 SymTab.ClPtr THEN
|
|
|
- 1490 SemError(219)
|
|
|
- 1491 ELSE
|
|
|
- 1492 IF sfx
|
|
|
- 1493 OR (dk =
|
|
|
- 1494 SymTab.KindField) THEN
|
|
|
- 1495 QbeGen.ElemLoad(qd, dt,
|
|
|
- 1496 qv)
|
|
|
- 1497 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
- 1498 END;
|
|
|
- 1499 QbeGen.FreeHeap(qv);
|
|
|
- 1500 IF sfx
|
|
|
- 1501 OR (dk =
|
|
|
- 1502 SymTab.KindField) THEN
|
|
|
- 1503 QbeGen.ElemStore(qd, "0",
|
|
|
- 1504 dt)
|
|
|
- 1505 ELSE QbeGen.StorePtr(qn,
|
|
|
- 1506 "0")
|
|
|
- 1507 END
|
|
|
- 1508 END; .) .
|
|
|
- 1509 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
- 1510 address; field designators resolve through both stacks. *)
|
|
|
- 1511 WithStat (. VAR nW: CARDINAL;
|
|
|
- 1512 astNode: AST.Node; .)
|
|
|
- 1513 = "WITH" (. nW := 0;
|
|
|
- 1514 astNode := AST.MakeNode(AST.NkWith); .)
|
|
|
- 1515 WithItem<nW, astNode> { "," WithItem<nW, astNode> }
|
|
|
- 1516 "DO" (. astStmt := AST.NoNode; .)
|
|
|
- 1517 [ StatSeq ] "END" (. AST.SetChild(astNode,
|
|
|
- 1518 AST.NChild(astNode), astStmt);
|
|
|
- 1519 astStmt := astNode;
|
|
|
- 1520 WHILE nW > 0 DO
|
|
|
- 1521 SymTab.PopScope;
|
|
|
- 1522 QbeGen.PopWith;
|
|
|
- 1523 DEC(nW)
|
|
|
- 1524 END; .) .
|
|
|
- 1525 WithItem<VAR nW: CARDINAL; wnode: AST.Node>
|
|
|
- 1526 (. VAR dt: SymTab.TypeIndex;
|
|
|
- 1527 dk: INTEGER;
|
|
|
- 1528 qd, qe: QbeGen.QVal;
|
|
|
- 1529 qn: SymTab.Name;
|
|
|
- 1530 sfx: BOOLEAN; .)
|
|
|
- 1531 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 1532 (. IF astCur # AST.NoNode THEN
|
|
|
- 1533 AST.SetChild(wnode,
|
|
|
- 1534 AST.NChild(wnode), astCur) END;
|
|
|
- 1535 IF dt = SymTab.InvalidType THEN
|
|
|
- 1536 ELSIF (SymTab.ClassOf(dt) #
|
|
|
- 1537 SymTab.ClRecord)
|
|
|
- 1538 AND (SymTab.ClassOf(dt) #
|
|
|
- 1539 SymTab.ClClass) THEN
|
|
|
- 1540 SemError(215)
|
|
|
- 1541 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
- 1542 QbeGen.PushWith(qd);
|
|
|
- 1543 INC(nW)
|
|
|
- 1544 END; .) .
|
|
|
- 1545 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
- 1546 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
- 1547 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
- 1548 dk: INTEGER;
|
|
|
- 1549 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
- 1550 qn: SymTab.Name;
|
|
|
- 1551 ct2, res0: SymTab.TypeIndex;
|
|
|
- 1552 q2, mg0: QbeGen.QVal;
|
|
|
- 1553 isR, conv, wconv: BOOLEAN;
|
|
|
- 1554 called, sfx: BOOLEAN;
|
|
|
- 1555 astLhs: AST.Node; .)
|
|
|
- 1556 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 1557 (. astLhs := astCur; astNArgs := 0; .)
|
|
|
- 1558 ( ":="
|
|
|
- 1559 Expr<et, qe> (. astStmt := AST.MakeBin(
|
|
|
- 1560 AST.NkAssign, 0, astLhs, astCur);
|
|
|
- 1561 IF (dt # SymTab.InvalidType)
|
|
|
- 1562 AND (dk # SymTab.KindVar)
|
|
|
- 1563 AND (dk # SymTab.KindParam)
|
|
|
- 1564 AND (dk # SymTab.KindField) THEN
|
|
|
- 1565 SemError(210)
|
|
|
- 1566 ELSIF NOT SymTab.Assignable(et,
|
|
|
- 1567 dt) THEN
|
|
|
- 1568 SemError(210)
|
|
|
- 1569 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 1570 AND (SymTab.ClassOf(dt) =
|
|
|
- 1571 SymTab.ClClass) THEN
|
|
|
- 1572 SemError(230) END;
|
|
|
- 1573 isR := (dt #
|
|
|
- 1574 SymTab.InvalidType)
|
|
|
- 1575 AND (SymTab.ClassOf(dt)
|
|
|
- 1576 = SymTab.ClReal);
|
|
|
- 1577 conv := isR
|
|
|
- 1578 AND SymTab.IsIntFamily(et);
|
|
|
- 1579 wconv := (dt #
|
|
|
- 1580 SymTab.InvalidType)
|
|
|
- 1581 AND SymTab.IsLongFamily(dt)
|
|
|
- 1582 AND SymTab.IsIntFamily(et);
|
|
|
- 1583 IF ((dk = SymTab.KindVar)
|
|
|
- 1584 OR (dk = SymTab.KindParam)
|
|
|
- 1585 OR (dk = SymTab.KindField))
|
|
|
- 1586 AND (dt # SymTab.InvalidType)
|
|
|
- 1587 AND (et # SymTab.InvalidType)
|
|
|
- 1588 AND (SymTab.ClassOf(dt) #
|
|
|
- 1589 SymTab.ClClass) THEN
|
|
|
- 1590 IF sfx
|
|
|
- 1591 OR (dk = SymTab.KindField) THEN
|
|
|
- 1592 IF SymTab.ClassOf(dt) =
|
|
|
- 1593 SymTab.ClArray THEN
|
|
|
- 1594 IF (et # SymTab.InvalidType)
|
|
|
- 1595 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
- 1596 AND SymTab.IsUCharArray(dt) THEN
|
|
|
- 1597 QbeGen.UAssign(qd, qe)
|
|
|
- 1598 ELSIF SymTab.StrCompat(dt,
|
|
|
- 1599 et) THEN
|
|
|
- 1600 QbeGen.StrAssign(qd,
|
|
|
- 1601 qe)
|
|
|
- 1602 ELSE
|
|
|
- 1603 QbeGen.CopyArray(qd,
|
|
|
- 1604 qe, dt)
|
|
|
- 1605 END
|
|
|
- 1606 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1607 SymTab.ClSet THEN
|
|
|
- 1608 QbeGen.CopySet(qd, qe,
|
|
|
- 1609 SymTab.SetWords(dt),
|
|
|
- 1610 SymTab.SetWords(et))
|
|
|
- 1611 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1612 SymTab.ClRecord THEN
|
|
|
- 1613 QbeGen.CopyRecord(qd, qe,
|
|
|
- 1614 dt)
|
|
|
- 1615 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 1616 IF wconv THEN
|
|
|
- 1617 QbeGen.WidenLong(qe, ql);
|
|
|
- 1618 QbeGen.ElemStore(qd, ql,
|
|
|
- 1619 dt)
|
|
|
- 1620 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 1621 dt)
|
|
|
- 1622 END
|
|
|
- 1623 ELSIF conv THEN
|
|
|
- 1624 QbeGen.ConvIR(qe, qt);
|
|
|
- 1625 QbeGen.ElemStore(qd, qt,
|
|
|
- 1626 dt)
|
|
|
- 1627 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 1628 dt)
|
|
|
- 1629 END
|
|
|
- 1630 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1631 SymTab.ClArray THEN
|
|
|
- 1632 IF (et # SymTab.InvalidType)
|
|
|
- 1633 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
- 1634 AND SymTab.IsUCharArray(dt) THEN
|
|
|
- 1635 QbeGen.UAssign(qd, qe)
|
|
|
- 1636 ELSIF SymTab.StrCompat(dt,
|
|
|
- 1637 et) THEN
|
|
|
- 1638 QbeGen.StrAssign(qd, qe)
|
|
|
- 1639 ELSE
|
|
|
- 1640 QbeGen.CopyArray(qd, qe,
|
|
|
- 1641 dt)
|
|
|
- 1642 END
|
|
|
- 1643 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1644 SymTab.ClSet THEN
|
|
|
- 1645 QbeGen.CopySet(qd, qe,
|
|
|
- 1646 SymTab.SetWords(dt),
|
|
|
- 1647 SymTab.SetWords(et))
|
|
|
- 1648 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1649 SymTab.ClRecord THEN
|
|
|
- 1650 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
- 1651 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1652 SymTab.ClPtr)
|
|
|
- 1653 OR (SymTab.ClassOf(dt) =
|
|
|
- 1654 SymTab.ClProc) THEN
|
|
|
- 1655 QbeGen.StorePtr(qn, qe)
|
|
|
- 1656 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 1657 IF wconv THEN
|
|
|
- 1658 QbeGen.WidenLong(qe, ql);
|
|
|
- 1659 QbeGen.StoreLong(qn, ql)
|
|
|
- 1660 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
- 1661 END
|
|
|
- 1662 ELSIF conv THEN
|
|
|
- 1663 QbeGen.ConvIR(qe, qt);
|
|
|
- 1664 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
- 1665 ELSE
|
|
|
- 1666 QbeGen.StoreVar(qn, qe, isR)
|
|
|
- 1667 END
|
|
|
- 1668 END; .)
|
|
|
- 1669 | ArgList<qn, dt, qd, FALSE, FALSE, methCls, ct2, q2, called>
|
|
|
- 1670 (. astStmt := AstCallNode(astLhs); .)
|
|
|
- 1671 | (* bare `P;`: proper parameterless
|
|
|
- 1672 procedure call; anything else
|
|
|
- 1673 here is 233 (was a bare syntax
|
|
|
- 1674 error before 4.2) *)
|
|
|
- 1675 (. astStmt := AstCallNode(astLhs);
|
|
|
- 1676 IF (dk = SymTab.KindProc)
|
|
|
- 1677 AND NOT sfx THEN
|
|
|
- 1678 res0 := SymTab.ProcRes(qn);
|
|
|
- 1679 IF res0 #
|
|
|
- 1680 SymTab.InvalidType THEN
|
|
|
- 1681 SemError(233)
|
|
|
- 1682 ELSIF SymTab.ProcNPar(qn) #
|
|
|
- 1683 0 THEN
|
|
|
- 1684 SemError(233)
|
|
|
- 1685 ELSE QbeGen.Mangled(qn,
|
|
|
- 1686 SymTab.ProcUid(qn), mg0);
|
|
|
- 1687 QbeGen.CallBegin(mg0,
|
|
|
- 1688 res0,
|
|
|
- 1689 SymTab.ProcDepthOf(qn),
|
|
|
- 1690 SymTab.IsExternal(qn));
|
|
|
- 1691 QbeGen.CallEnd(FALSE, q2)
|
|
|
- 1692 END
|
|
|
- 1693 ELSE SemError(233)
|
|
|
- 1694 END; .) ) .
|
|
|
- 1695 (* Actual-parameter list shared by statement and expression calls.
|
|
|
- 1696 want selects CallEnd's result handling; t/q carry the call
|
|
|
- 1697 value (statement calls discard). Arity/type failures are 233;
|
|
|
- 1698 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
- 1699 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
- 1700 want: BOOLEAN; soft: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
- 1701 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 1702 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
- 1703 vs: INTEGER;
|
|
|
- 1704 res: SymTab.TypeIndex;
|
|
|
- 1705 mg: QbeGen.QVal;
|
|
|
- 1706 ok, ind, isMeth, va: BOOLEAN; .)
|
|
|
- 1707 = "(" (. called := TRUE;
|
|
|
- 1708 ok := TRUE;
|
|
|
- 1709 ind := FALSE;
|
|
|
- 1710 isMeth := methCls #
|
|
|
- 1711 SymTab.InvalidType;
|
|
|
- 1712 IF isMeth THEN
|
|
|
- 1713 (* class method: the
|
|
|
- 1714 receiver is armed.
|
|
|
- 1715 Virtual -> dispatch
|
|
|
- 1716 through the vtable;
|
|
|
- 1717 otherwise a static
|
|
|
- 1718 call. *)
|
|
|
- 1719 res := SymTab.ClassMethodRes(
|
|
|
- 1720 methCls, pn);
|
|
|
- 1721 vs := SymTab.VirtSlot(
|
|
|
- 1722 methCls, pn);
|
|
|
- 1723 IF vs >= 0 THEN
|
|
|
- 1724 QbeGen.VirtCallBegin(
|
|
|
- 1725 callee, vs, res)
|
|
|
- 1726 ELSE
|
|
|
- 1727 QbeGen.Mangled(pn,
|
|
|
- 1728 SymTab.ClassMethodUid(
|
|
|
- 1729 methCls, pn), mg);
|
|
|
- 1730 QbeGen.CallBegin(mg, res, 0,
|
|
|
- 1731 FALSE)
|
|
|
- 1732 END
|
|
|
- 1733 ELSIF SymTab.SymKind(pn) =
|
|
|
- 1734 SymTab.KindProc THEN
|
|
|
- 1735 res := SymTab.ProcRes(pn);
|
|
|
- 1736 QbeGen.Mangled(pn,
|
|
|
- 1737 SymTab.ProcUid(pn), mg);
|
|
|
- 1738 QbeGen.CallBegin(mg, res,
|
|
|
- 1739 SymTab.ProcDepthOf(pn),
|
|
|
- 1740 SymTab.IsExternal(pn))
|
|
|
- 1741 ELSIF (pt # SymTab.InvalidType)
|
|
|
- 1742 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
- 1743 ind := TRUE;
|
|
|
- 1744 res :=
|
|
|
- 1745 SymTab.ProcTypeRes(pt);
|
|
|
- 1746 QbeGen.CallBeginInd(callee,
|
|
|
- 1747 res, FALSE)
|
|
|
- 1748 ELSE SemError(233);
|
|
|
- 1749 ok := FALSE;
|
|
|
- 1750 res := SymTab.InvalidType
|
|
|
- 1751 END;
|
|
|
- 1752 i := 0; .)
|
|
|
- 1753 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
- 1754 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
- 1755 ")" (. IF ok THEN
|
|
|
- 1756 IF isMeth THEN
|
|
|
- 1757 np := SymTab.ClassMethodNPar(
|
|
|
- 1758 methCls, pn)
|
|
|
- 1759 ELSIF ind THEN
|
|
|
- 1760 np := SymTab.ProcTypeNPar(pt)
|
|
|
- 1761 ELSE np := SymTab.ProcNPar(pn)
|
|
|
- 1762 END;
|
|
|
- 1763 va := (NOT isMeth) AND (NOT ind)
|
|
|
- 1764 AND (SymTab.SymKind(pn) =
|
|
|
- 1765 SymTab.KindProc)
|
|
|
- 1766 AND SymTab.Varargs(pn);
|
|
|
- 1767 IF (i # np) AND NOT va THEN
|
|
|
- 1768 SemError(233); ok := FALSE
|
|
|
- 1769 END
|
|
|
- 1770 END;
|
|
|
- 1771 IF NOT ok THEN
|
|
|
- 1772 t := SymTab.InvalidType;
|
|
|
- 1773 QbeGen.CopyOp("0", q)
|
|
|
- 1774 ELSIF want THEN
|
|
|
- 1775 IF res =
|
|
|
- 1776 SymTab.InvalidType THEN
|
|
|
- 1777 SemError(233);
|
|
|
- 1778 t := SymTab.InvalidType;
|
|
|
- 1779 QbeGen.CopyOp("0", q)
|
|
|
- 1780 ELSE t := res;
|
|
|
- 1781 QbeGen.CallEnd(TRUE, q)
|
|
|
- 1782 END
|
|
|
- 1783 ELSE
|
|
|
- 1784 IF res #
|
|
|
- 1785 SymTab.InvalidType THEN
|
|
|
- 1786 SemError(233)
|
|
|
- 1787 END;
|
|
|
- 1788 t := SymTab.InvalidType;
|
|
|
- 1789 QbeGen.CopyOp("0", q);
|
|
|
- 1790 QbeGen.CallEnd(FALSE, q)
|
|
|
- 1791 END; .) .
|
|
|
- 1792 (* One actual: VAR formals take recorded designator addresses
|
|
|
- 1793 (233 otherwise); value formals take converted expressions. *)
|
|
|
- 1794 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
- 1795 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
- 1796 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
- 1797 qe, qa, qt: QbeGen.QVal;
|
|
|
- 1798 isV, conv, va: BOOLEAN;
|
|
|
- 1799 cl: CHAR;
|
|
|
- 1800 savedN, aj: CARDINAL;
|
|
|
- 1801 savedArgs: ARRAY [0 .. 31]
|
|
|
- 1802 OF AST.Node; .)
|
|
|
- 1803 = (. (* Parsing the actual can clobber
|
|
|
- 1804 the enclosing call's argument
|
|
|
- 1805 list (Factor resets astNArgs),
|
|
|
- 1806 so save/restore it. *)
|
|
|
- 1807 savedN := astNArgs; aj := 0;
|
|
|
- 1808 WHILE aj <= HIGH(astArgs) DO
|
|
|
- 1809 savedArgs[aj] := astArgs[aj];
|
|
|
- 1810 INC(aj)
|
|
|
- 1811 END; .)
|
|
|
- 1812 Expr<at, qe> (. astNArgs := savedN; aj := 0;
|
|
|
- 1813 WHILE aj <= HIGH(astArgs) DO
|
|
|
- 1814 astArgs[aj] := savedArgs[aj];
|
|
|
- 1815 INC(aj)
|
|
|
- 1816 END;
|
|
|
- 1817 IF astNArgs <= HIGH(astArgs) THEN
|
|
|
- 1818 astArgs[astNArgs] := astCur;
|
|
|
- 1819 INC(astNArgs)
|
|
|
- 1820 END;
|
|
|
- 1821 va := (NOT ind)
|
|
|
- 1822 AND (methCls =
|
|
|
- 1823 SymTab.InvalidType)
|
|
|
- 1824 AND (SymTab.SymKind(pn) =
|
|
|
- 1825 SymTab.KindProc)
|
|
|
- 1826 AND SymTab.Varargs(pn);
|
|
|
- 1827 IF ind THEN
|
|
|
- 1828 ft :=
|
|
|
- 1829 SymTab.ProcTypeParamType(pt,
|
|
|
- 1830 i);
|
|
|
- 1831 isV :=
|
|
|
- 1832 SymTab.ProcTypeParamIsVar(pt,
|
|
|
- 1833 i)
|
|
|
- 1834 ELSIF methCls #
|
|
|
- 1835 SymTab.InvalidType THEN
|
|
|
- 1836 ft :=
|
|
|
- 1837 SymTab.ClassMethodParamType(
|
|
|
- 1838 methCls, pn, i);
|
|
|
- 1839 isV :=
|
|
|
- 1840 SymTab.ClassMethodParamIsVar(
|
|
|
- 1841 methCls, pn, i)
|
|
|
- 1842 ELSE
|
|
|
- 1843 ft := SymTab.ParamType(pn, i);
|
|
|
- 1844 isV := SymTab.ParamIsVar(pn, i)
|
|
|
- 1845 END;
|
|
|
- 1846 IF (at = SymTab.InvalidType) THEN
|
|
|
- 1847 ELSIF ft = SymTab.InvalidType THEN
|
|
|
- 1848 IF va THEN
|
|
|
- 1849 QbeGen.CArgAdd(qe, at, qa, cl)
|
|
|
- 1850 END
|
|
|
- 1851 ELSIF isV THEN
|
|
|
- 1852 IF (SymTab.ClassOf(at)
|
|
|
- 1853 = SymTab.ClChar)
|
|
|
- 1854 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1855 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1856 = SymTab.ClChar)
|
|
|
- 1857 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1858 (* 1-char string
|
|
|
- 1859 literal passed to
|
|
|
- 1860 a VAR ARRAY OF CHAR *)
|
|
|
- 1861 QbeGen.DeclCharStr(qe,
|
|
|
- 1862 qa);
|
|
|
- 1863 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1864 "l") THEN
|
|
|
- 1865 SemError(233)
|
|
|
- 1866 END
|
|
|
- 1867 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
- 1868 qa) THEN
|
|
|
- 1869 SemError(233)
|
|
|
- 1870 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
- 1871 ft) THEN
|
|
|
- 1872 SemError(233)
|
|
|
- 1873 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
- 1874 "l") THEN
|
|
|
- 1875 SemError(233)
|
|
|
- 1876 END
|
|
|
- 1877 ELSE
|
|
|
- 1878 IF (SymTab.ClassOf(at)
|
|
|
- 1879 = SymTab.ClChar)
|
|
|
- 1880 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1881 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1882 = SymTab.ClChar)
|
|
|
- 1883 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1884 (* 1-char string
|
|
|
- 1885 literal passed to
|
|
|
- 1886 ARRAY OF CHAR *)
|
|
|
- 1887 QbeGen.DeclCharStr(qe,
|
|
|
- 1888 qa);
|
|
|
- 1889 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1890 "l") THEN
|
|
|
- 1891 SemError(233)
|
|
|
- 1892 END
|
|
|
- 1893 ELSIF NOT SymTab.Assignable(at,
|
|
|
- 1894 ft) THEN
|
|
|
- 1895 SemError(233)
|
|
|
- 1896 ELSE
|
|
|
- 1897 conv := (SymTab.ClassOf(
|
|
|
- 1898 ft) = SymTab.ClReal)
|
|
|
- 1899 AND SymTab.IsIntFamily(at);
|
|
|
- 1900 IF conv THEN
|
|
|
- 1901 QbeGen.ConvIR(qe, qt);
|
|
|
- 1902 IF NOT QbeGen.CallArg(qt,
|
|
|
- 1903 "d") THEN
|
|
|
- 1904 SemError(233)
|
|
|
- 1905 END
|
|
|
- 1906 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
- 1907 QbeGen.ArgClass(ft)) THEN
|
|
|
- 1908 SemError(233)
|
|
|
- 1909 END
|
|
|
- 1910 END
|
|
|
- 1911 END; .) .
|
|
|
- 1912 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1913 q, lThen, lElse, lEnd:
|
|
|
- 1914 QbeGen.QVal;
|
|
|
- 1915 hasElse: BOOLEAN;
|
|
|
- 1916 astCond, astIf, astLast,
|
|
|
- 1917 astNode: AST.Node; .)
|
|
|
- 1918 = "IF" (. hasElse := FALSE; .)
|
|
|
- 1919 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
- 1920 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1921 SemError(214) END;
|
|
|
- 1922 QbeGen.NewLabel(lThen);
|
|
|
- 1923 QbeGen.NewLabel(lElse);
|
|
|
- 1924 QbeGen.NewLabel(lEnd);
|
|
|
- 1925 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 1926 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1927 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
- 1928 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1929 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1930 astIf := astNode;
|
|
|
- 1931 astLast := astNode;
|
|
|
- 1932 QbeGen.Jmp(lEnd); .)
|
|
|
- 1933 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1934 QbeGen.NewLabel(lElse); .)
|
|
|
- 1935 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
- 1936 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1937 SemError(214) END;
|
|
|
- 1938 QbeGen.NewLabel(lThen);
|
|
|
- 1939 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 1940 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1941 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
- 1942 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1943 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1944 AST.SetChild(astLast, 2, astNode);
|
|
|
- 1945 astLast := astNode;
|
|
|
- 1946 QbeGen.Jmp(lEnd); .) }
|
|
|
- 1947 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1948 hasElse := TRUE;
|
|
|
- 1949 astStmt := AST.NoNode; .)
|
|
|
- 1950 [ StatSeq ] (. AST.SetChild(astLast, 2, astStmt); .) ]
|
|
|
- 1951 "END" (. astStmt := astIf;
|
|
|
- 1952 IF hasElse THEN
|
|
|
- 1953 QbeGen.EmitLabel(lEnd)
|
|
|
- 1954 ELSE QbeGen.EmitLabel(lElse);
|
|
|
- 1955 QbeGen.EmitLabel(lEnd)
|
|
|
- 1956 END; .) .
|
|
|
- 1957 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1958 q, lTop, lBody, lEnd:
|
|
|
- 1959 QbeGen.QVal;
|
|
|
- 1960 astCond, astNode: AST.Node; .)
|
|
|
- 1961 = "WHILE" (. astStmt := AST.NoNode;
|
|
|
- 1962 QbeGen.NewLabel(lTop);
|
|
|
- 1963 QbeGen.NewLabel(lBody);
|
|
|
- 1964 QbeGen.NewLabel(lEnd);
|
|
|
- 1965 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1966 Expr<t, q> (. astCond := astCur;
|
|
|
- 1967 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1968 SemError(214) END;
|
|
|
- 1969 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
- 1970 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1971 "DO" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkWhile);
|
|
|
- 1972 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1973 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1974 astStmt := astNode;
|
|
|
- 1975 QbeGen.Jmp(lTop); .)
|
|
|
- 1976 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1977 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1978 q, lTop, lEnd: QbeGen.QVal;
|
|
|
- 1979 astCond, astBody, astNode:
|
|
|
- 1980 AST.Node; .)
|
|
|
- 1981 = "REPEAT" (. astStmt := AST.NoNode;
|
|
|
- 1982 QbeGen.NewLabel(lTop);
|
|
|
- 1983 QbeGen.NewLabel(lEnd);
|
|
|
- 1984 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1985 [ StatSeq ] (. astBody := astStmt; .)
|
|
|
- 1986 "UNTIL" Expr<t, q> (. astCond := astCur;
|
|
|
- 1987 astNode := AST.MakeNode(AST.NkRepeat);
|
|
|
- 1988 AST.SetChild(astNode, 0, astBody);
|
|
|
- 1989 AST.SetChild(astNode, 1, astCond);
|
|
|
- 1990 astStmt := astNode;
|
|
|
- 1991 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1992 SemError(214) END;
|
|
|
- 1993 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
- 1994 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1995 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; astNode: AST.Node; .)
|
|
|
- 1996 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
- 1997 astStmt := AST.NoNode;
|
|
|
+ 1332 | "EXIT" (. IF NOT QbeGen.TopLoop(lx) THEN
|
|
|
+ 1333 SemError(230) END;
|
|
|
+ 1334 astStmt := AST.MakeNode(AST.NkExit); .) ) .
|
|
|
+ 1335 (* INCL(set, elem) / EXCL(set, elem): PIM set-element builtins. *)
|
|
|
+ 1336 InclExclStat (. VAR at, et2: SymTab.TypeIndex;
|
|
|
+ 1337 dk: INTEGER;
|
|
|
+ 1338 qd, qe: QbeGen.QVal;
|
|
|
+ 1339 qn: SymTab.Name;
|
|
|
+ 1340 sfx, isInc: BOOLEAN;
|
|
|
+ 1341 astNode, astD: AST.Node; .)
|
|
|
+ 1342 = ( "INCL" (. isInc := TRUE; .)
|
|
|
+ 1343 | "EXCL" (. isInc := FALSE; .) )
|
|
|
+ 1344 "(" Design<at, dk, qd, qn, sfx> (. astD := astCur; .) ","
|
|
|
+ 1345 Expr<et2, qe> ")"
|
|
|
+ 1346 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1347 IF isInc THEN
|
|
|
+ 1348 AST.SetChild(astNode, 0,
|
|
|
+ 1349 AST.MakeLeaf(AST.NkIdent, "INCL"))
|
|
|
+ 1350 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 1351 AST.MakeLeaf(AST.NkIdent, "EXCL"))
|
|
|
+ 1352 END;
|
|
|
+ 1353 IF astD # AST.NoNode THEN
|
|
|
+ 1354 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1355 IF astCur # AST.NoNode THEN
|
|
|
+ 1356 AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 1357 astStmt := astNode; .)
|
|
|
+ 1358 (. IF (at # SymTab.InvalidType)
|
|
|
+ 1359 AND (SymTab.ClassOf(at) # SymTab.ClSet) THEN
|
|
|
+ 1360 SemError(222)
|
|
|
+ 1361 END; .) .
|
|
|
+ 1362 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
+ 1363 integer designator. *)
|
|
|
+ 1364 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
+ 1365 dk: INTEGER;
|
|
|
+ 1366 qd, qv, qn2, qstep:
|
|
|
+ 1367 QbeGen.QVal;
|
|
|
+ 1368 qn: SymTab.Name;
|
|
|
+ 1369 sfx, isInc: BOOLEAN;
|
|
|
+ 1370 astNode, astD, astStep:
|
|
|
+ 1371 AST.Node; .)
|
|
|
+ 1372 = (. isInc := TRUE; .)
|
|
|
+ 1373 ( "INC" (. isInc := TRUE; .)
|
|
|
+ 1374 | "DEC" (. isInc := FALSE; .) )
|
|
|
+ 1375 "(" (. astStep := AST.NoNode; .)
|
|
|
+ 1376 Design<dt, dk, qd, qn, sfx> (. astD := astCur; .)
|
|
|
+ 1377 [ "," Expr<et2, qstep> (. astStep := astCur; .) ]
|
|
|
+ 1378 ")" (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1379 IF isInc THEN
|
|
|
+ 1380 AST.SetChild(astNode, 0,
|
|
|
+ 1381 AST.MakeLeaf(AST.NkIdent, "INC"))
|
|
|
+ 1382 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 1383 AST.MakeLeaf(AST.NkIdent, "DEC"))
|
|
|
+ 1384 END;
|
|
|
+ 1385 IF astD # AST.NoNode THEN
|
|
|
+ 1386 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1387 IF astStep # AST.NoNode THEN
|
|
|
+ 1388 AST.SetChild(astNode, 2, astStep) END;
|
|
|
+ 1389 astStmt := astNode; .) (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1390 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 1391 AND (dk # SymTab.KindParam)
|
|
|
+ 1392 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1393 SemError(210)
|
|
|
+ 1394 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
+ 1395 SemError(211)
|
|
|
+ 1396 END; .) .
|
|
|
+ 1397 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
+ 1398 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
+ 1399 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
+ 1400 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 1401 dk: INTEGER;
|
|
|
+ 1402 qd, qm: QbeGen.QVal;
|
|
|
+ 1403 qn: SymTab.Name;
|
|
|
+ 1404 sfx: BOOLEAN;
|
|
|
+ 1405 bt: SymTab.TypeIndex;
|
|
|
+ 1406 astNode, astD: AST.Node; .)
|
|
|
+ 1407 = "NEW" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
+ 1408 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1409 AST.SetChild(astNode, 0,
|
|
|
+ 1410 AST.MakeLeaf(AST.NkIdent, "NEW"));
|
|
|
+ 1411 IF astD # AST.NoNode THEN
|
|
|
+ 1412 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1413 astStmt := astNode; .)
|
|
|
+ 1414 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1415 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 1416 AND (dk # SymTab.KindParam)
|
|
|
+ 1417 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1418 SemError(210)
|
|
|
+ 1419 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 1420 SymTab.ClPtr THEN
|
|
|
+ 1421 SemError(219)
|
|
|
+ 1422 END; .) .
|
|
|
+ 1423 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 1424 dk: INTEGER;
|
|
|
+ 1425 qd, qv: QbeGen.QVal;
|
|
|
+ 1426 qn: SymTab.Name;
|
|
|
+ 1427 sfx: BOOLEAN;
|
|
|
+ 1428 astNode, astD: AST.Node; .)
|
|
|
+ 1429 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
+ 1430 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1431 AST.SetChild(astNode, 0,
|
|
|
+ 1432 AST.MakeLeaf(AST.NkIdent, "DISPOSE"));
|
|
|
+ 1433 IF astD # AST.NoNode THEN
|
|
|
+ 1434 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1435 astStmt := astNode; .)
|
|
|
+ 1436 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1437 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 1438 AND (dk # SymTab.KindParam)
|
|
|
+ 1439 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1440 SemError(210)
|
|
|
+ 1441 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 1442 SymTab.ClPtr THEN
|
|
|
+ 1443 SemError(219)
|
|
|
+ 1444 END; .) .
|
|
|
+ 1445 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
+ 1446 address; field designators resolve through both stacks. *)
|
|
|
+ 1447 WithStat (. VAR nW: CARDINAL;
|
|
|
+ 1448 astNode: AST.Node; .)
|
|
|
+ 1449 = "WITH" (. nW := 0;
|
|
|
+ 1450 astNode := AST.MakeNode(AST.NkWith); .)
|
|
|
+ 1451 WithItem<nW, astNode> { "," WithItem<nW, astNode> }
|
|
|
+ 1452 "DO" (. astStmt := AST.NoNode; .)
|
|
|
+ 1453 [ StatSeq ] "END" (. AST.SetChild(astNode,
|
|
|
+ 1454 AST.NChild(astNode), astStmt);
|
|
|
+ 1455 astStmt := astNode;
|
|
|
+ 1456 WHILE nW > 0 DO
|
|
|
+ 1457 SymTab.PopScope;
|
|
|
+ 1458 QbeGen.PopWith;
|
|
|
+ 1459 DEC(nW)
|
|
|
+ 1460 END; .) .
|
|
|
+ 1461 WithItem<VAR nW: CARDINAL; wnode: AST.Node>
|
|
|
+ 1462 (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 1463 dk: INTEGER;
|
|
|
+ 1464 qd, qe: QbeGen.QVal;
|
|
|
+ 1465 qn: SymTab.Name;
|
|
|
+ 1466 sfx: BOOLEAN; .)
|
|
|
+ 1467 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 1468 (. IF astCur # AST.NoNode THEN
|
|
|
+ 1469 AST.SetChild(wnode,
|
|
|
+ 1470 AST.NChild(wnode), astCur) END;
|
|
|
+ 1471 IF dt = SymTab.InvalidType THEN
|
|
|
+ 1472 ELSIF (SymTab.ClassOf(dt) #
|
|
|
+ 1473 SymTab.ClRecord)
|
|
|
+ 1474 AND (SymTab.ClassOf(dt) #
|
|
|
+ 1475 SymTab.ClClass) THEN
|
|
|
+ 1476 SemError(215)
|
|
|
+ 1477 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
+ 1478 QbeGen.PushWith(qd);
|
|
|
+ 1479 INC(nW)
|
|
|
+ 1480 END; .) .
|
|
|
+ 1481 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
+ 1482 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
+ 1483 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
+ 1484 dk: INTEGER;
|
|
|
+ 1485 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
+ 1486 qn: SymTab.Name;
|
|
|
+ 1487 ct2, res0: SymTab.TypeIndex;
|
|
|
+ 1488 q2, mg0: QbeGen.QVal;
|
|
|
+ 1489 isR, conv, wconv: BOOLEAN;
|
|
|
+ 1490 called, sfx: BOOLEAN;
|
|
|
+ 1491 astLhs: AST.Node; .)
|
|
|
+ 1492 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 1493 (. astLhs := astCur; astNArgs := 0; .)
|
|
|
+ 1494 ( ":="
|
|
|
+ 1495 Expr<et, qe> (. astStmt := AST.MakeBin(
|
|
|
+ 1496 AST.NkAssign, 0, astLhs, astCur);
|
|
|
+ 1497 IF (dt # SymTab.InvalidType)
|
|
|
+ 1498 AND (dk # SymTab.KindVar)
|
|
|
+ 1499 AND (dk # SymTab.KindParam)
|
|
|
+ 1500 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1501 SemError(210)
|
|
|
+ 1502 ELSIF NOT SymTab.Assignable(et,
|
|
|
+ 1503 dt) THEN
|
|
|
+ 1504 SemError(210)
|
|
|
+ 1505 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 1506 AND (SymTab.ClassOf(dt) =
|
|
|
+ 1507 SymTab.ClClass) THEN
|
|
|
+ 1508 SemError(230) END;
|
|
|
+ 1509 isR := (dt #
|
|
|
+ 1510 SymTab.InvalidType)
|
|
|
+ 1511 AND (SymTab.ClassOf(dt)
|
|
|
+ 1512 = SymTab.ClReal);
|
|
|
+ 1513 conv := isR
|
|
|
+ 1514 AND SymTab.IsIntFamily(et);
|
|
|
+ 1515 wconv := (dt #
|
|
|
+ 1516 SymTab.InvalidType)
|
|
|
+ 1517 AND SymTab.IsLongFamily(dt)
|
|
|
+ 1518 AND SymTab.IsIntFamily(et);
|
|
|
+ 1519 IF ((dk = SymTab.KindVar)
|
|
|
+ 1520 OR (dk = SymTab.KindParam)
|
|
|
+ 1521 OR (dk = SymTab.KindField))
|
|
|
+ 1522 AND (dt # SymTab.InvalidType)
|
|
|
+ 1523 AND (et # SymTab.InvalidType)
|
|
|
+ 1524 AND (SymTab.ClassOf(dt) #
|
|
|
+ 1525 SymTab.ClClass) THEN
|
|
|
+ 1526 IF sfx
|
|
|
+ 1527 OR (dk = SymTab.KindField) THEN
|
|
|
+ 1528 IF SymTab.ClassOf(dt) =
|
|
|
+ 1529 SymTab.ClArray THEN
|
|
|
+ 1530 IF (et # SymTab.InvalidType)
|
|
|
+ 1531 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 1532 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 1533 QbeGen.UAssign(qd, qe)
|
|
|
+ 1534 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 1535 et) THEN
|
|
|
+ 1536 QbeGen.StrAssign(qd,
|
|
|
+ 1537 qe)
|
|
|
+ 1538 ELSE
|
|
|
+ 1539 QbeGen.CopyArray(qd,
|
|
|
+ 1540 qe, dt)
|
|
|
+ 1541 END
|
|
|
+ 1542 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1543 SymTab.ClSet THEN
|
|
|
+ 1544 QbeGen.CopySet(qd, qe,
|
|
|
+ 1545 SymTab.SetWords(dt),
|
|
|
+ 1546 SymTab.SetWords(et))
|
|
|
+ 1547 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1548 SymTab.ClRecord THEN
|
|
|
+ 1549 QbeGen.CopyRecord(qd, qe,
|
|
|
+ 1550 dt)
|
|
|
+ 1551 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 1552 IF wconv THEN
|
|
|
+ 1553 QbeGen.WidenLong(qe, ql);
|
|
|
+ 1554 QbeGen.ElemStore(qd, ql,
|
|
|
+ 1555 dt)
|
|
|
+ 1556 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 1557 dt)
|
|
|
+ 1558 END
|
|
|
+ 1559 ELSIF conv THEN
|
|
|
+ 1560 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1561 QbeGen.ElemStore(qd, qt,
|
|
|
+ 1562 dt)
|
|
|
+ 1563 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 1564 dt)
|
|
|
+ 1565 END
|
|
|
+ 1566 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1567 SymTab.ClArray THEN
|
|
|
+ 1568 IF (et # SymTab.InvalidType)
|
|
|
+ 1569 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 1570 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 1571 QbeGen.UAssign(qd, qe)
|
|
|
+ 1572 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 1573 et) THEN
|
|
|
+ 1574 QbeGen.StrAssign(qd, qe)
|
|
|
+ 1575 ELSE
|
|
|
+ 1576 QbeGen.CopyArray(qd, qe,
|
|
|
+ 1577 dt)
|
|
|
+ 1578 END
|
|
|
+ 1579 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1580 SymTab.ClSet THEN
|
|
|
+ 1581 QbeGen.CopySet(qd, qe,
|
|
|
+ 1582 SymTab.SetWords(dt),
|
|
|
+ 1583 SymTab.SetWords(et))
|
|
|
+ 1584 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1585 SymTab.ClRecord THEN
|
|
|
+ 1586 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
+ 1587 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1588 SymTab.ClPtr)
|
|
|
+ 1589 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1590 SymTab.ClProc) THEN
|
|
|
+ 1591 QbeGen.StorePtr(qn, qe)
|
|
|
+ 1592 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 1593 IF wconv THEN
|
|
|
+ 1594 QbeGen.WidenLong(qe, ql);
|
|
|
+ 1595 QbeGen.StoreLong(qn, ql)
|
|
|
+ 1596 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
+ 1597 END
|
|
|
+ 1598 ELSIF conv THEN
|
|
|
+ 1599 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1600 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
+ 1601 ELSE
|
|
|
+ 1602 QbeGen.StoreVar(qn, qe, isR)
|
|
|
+ 1603 END
|
|
|
+ 1604 END; .)
|
|
|
+ 1605 | ArgList<qn, dt, qd, FALSE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 1606 (. astStmt := AstCallNode(astLhs); .)
|
|
|
+ 1607 | (* bare `P;`: proper parameterless
|
|
|
+ 1608 procedure call; anything else
|
|
|
+ 1609 here is 233 (was a bare syntax
|
|
|
+ 1610 error before 4.2) *)
|
|
|
+ 1611 (. astStmt := AstCallNode(astLhs);
|
|
|
+ 1612 IF (dk = SymTab.KindProc)
|
|
|
+ 1613 AND NOT sfx THEN
|
|
|
+ 1614 res0 := SymTab.ProcRes(qn);
|
|
|
+ 1615 IF res0 #
|
|
|
+ 1616 SymTab.InvalidType THEN
|
|
|
+ 1617 SemError(233)
|
|
|
+ 1618 ELSIF SymTab.ProcNPar(qn) #
|
|
|
+ 1619 0 THEN
|
|
|
+ 1620 SemError(233)
|
|
|
+ 1621 ELSE QbeGen.Mangled(qn,
|
|
|
+ 1622 SymTab.ProcUid(qn), mg0);
|
|
|
+ 1623 QbeGen.CallBegin(mg0,
|
|
|
+ 1624 res0,
|
|
|
+ 1625 SymTab.ProcDepthOf(qn),
|
|
|
+ 1626 SymTab.IsExternal(qn));
|
|
|
+ 1627 QbeGen.CallEnd(FALSE, q2)
|
|
|
+ 1628 END
|
|
|
+ 1629 ELSE SemError(233)
|
|
|
+ 1630 END; .) ) .
|
|
|
+ 1631 (* Actual-parameter list shared by statement and expression calls.
|
|
|
+ 1632 want selects CallEnd's result handling; t/q carry the call
|
|
|
+ 1633 value (statement calls discard). Arity/type failures are 233;
|
|
|
+ 1634 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
+ 1635 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
+ 1636 want: BOOLEAN; soft: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
+ 1637 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 1638 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
+ 1639 vs: INTEGER;
|
|
|
+ 1640 res: SymTab.TypeIndex;
|
|
|
+ 1641 mg: QbeGen.QVal;
|
|
|
+ 1642 ok, ind, isMeth, va: BOOLEAN; .)
|
|
|
+ 1643 = "(" (. called := TRUE;
|
|
|
+ 1644 ok := TRUE;
|
|
|
+ 1645 ind := FALSE;
|
|
|
+ 1646 isMeth := methCls #
|
|
|
+ 1647 SymTab.InvalidType;
|
|
|
+ 1648 IF isMeth THEN
|
|
|
+ 1649 (* class method: the
|
|
|
+ 1650 receiver is armed.
|
|
|
+ 1651 Virtual -> dispatch
|
|
|
+ 1652 through the vtable;
|
|
|
+ 1653 otherwise a static
|
|
|
+ 1654 call. *)
|
|
|
+ 1655 res := SymTab.ClassMethodRes(
|
|
|
+ 1656 methCls, pn);
|
|
|
+ 1657 vs := SymTab.VirtSlot(
|
|
|
+ 1658 methCls, pn);
|
|
|
+ 1659 IF vs >= 0 THEN
|
|
|
+ 1660 QbeGen.VirtCallBegin(
|
|
|
+ 1661 callee, vs, res)
|
|
|
+ 1662 ELSE
|
|
|
+ 1663 QbeGen.Mangled(pn,
|
|
|
+ 1664 SymTab.ClassMethodUid(
|
|
|
+ 1665 methCls, pn), mg);
|
|
|
+ 1666 QbeGen.CallBegin(mg, res, 0,
|
|
|
+ 1667 FALSE)
|
|
|
+ 1668 END
|
|
|
+ 1669 ELSIF SymTab.SymKind(pn) =
|
|
|
+ 1670 SymTab.KindProc THEN
|
|
|
+ 1671 res := SymTab.ProcRes(pn);
|
|
|
+ 1672 QbeGen.Mangled(pn,
|
|
|
+ 1673 SymTab.ProcUid(pn), mg);
|
|
|
+ 1674 QbeGen.CallBegin(mg, res,
|
|
|
+ 1675 SymTab.ProcDepthOf(pn),
|
|
|
+ 1676 SymTab.IsExternal(pn))
|
|
|
+ 1677 ELSIF (pt # SymTab.InvalidType)
|
|
|
+ 1678 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
+ 1679 ind := TRUE;
|
|
|
+ 1680 res :=
|
|
|
+ 1681 SymTab.ProcTypeRes(pt);
|
|
|
+ 1682 QbeGen.CallBeginInd(callee,
|
|
|
+ 1683 res, FALSE)
|
|
|
+ 1684 ELSE SemError(233);
|
|
|
+ 1685 ok := FALSE;
|
|
|
+ 1686 res := SymTab.InvalidType
|
|
|
+ 1687 END;
|
|
|
+ 1688 i := 0; .)
|
|
|
+ 1689 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
+ 1690 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
+ 1691 ")" (. IF ok THEN
|
|
|
+ 1692 IF isMeth THEN
|
|
|
+ 1693 np := SymTab.ClassMethodNPar(
|
|
|
+ 1694 methCls, pn)
|
|
|
+ 1695 ELSIF ind THEN
|
|
|
+ 1696 np := SymTab.ProcTypeNPar(pt)
|
|
|
+ 1697 ELSE np := SymTab.ProcNPar(pn)
|
|
|
+ 1698 END;
|
|
|
+ 1699 va := (NOT isMeth) AND (NOT ind)
|
|
|
+ 1700 AND (SymTab.SymKind(pn) =
|
|
|
+ 1701 SymTab.KindProc)
|
|
|
+ 1702 AND SymTab.Varargs(pn);
|
|
|
+ 1703 IF (i # np) AND NOT va THEN
|
|
|
+ 1704 SemError(233); ok := FALSE
|
|
|
+ 1705 END
|
|
|
+ 1706 END;
|
|
|
+ 1707 IF NOT ok THEN
|
|
|
+ 1708 t := SymTab.InvalidType;
|
|
|
+ 1709 QbeGen.CopyOp("0", q)
|
|
|
+ 1710 ELSIF want THEN
|
|
|
+ 1711 IF res =
|
|
|
+ 1712 SymTab.InvalidType THEN
|
|
|
+ 1713 SemError(233);
|
|
|
+ 1714 t := SymTab.InvalidType;
|
|
|
+ 1715 QbeGen.CopyOp("0", q)
|
|
|
+ 1716 ELSE t := res;
|
|
|
+ 1717 QbeGen.CallEnd(TRUE, q)
|
|
|
+ 1718 END
|
|
|
+ 1719 ELSE
|
|
|
+ 1720 IF res #
|
|
|
+ 1721 SymTab.InvalidType THEN
|
|
|
+ 1722 SemError(233)
|
|
|
+ 1723 END;
|
|
|
+ 1724 t := SymTab.InvalidType;
|
|
|
+ 1725 QbeGen.CopyOp("0", q);
|
|
|
+ 1726 QbeGen.CallEnd(FALSE, q)
|
|
|
+ 1727 END; .) .
|
|
|
+ 1728 (* One actual: VAR formals take recorded designator addresses
|
|
|
+ 1729 (233 otherwise); value formals take converted expressions. *)
|
|
|
+ 1730 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
+ 1731 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
+ 1732 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ 1733 qe, qa, qt: QbeGen.QVal;
|
|
|
+ 1734 isV, conv, va: BOOLEAN;
|
|
|
+ 1735 cl: CHAR;
|
|
|
+ 1736 savedN, aj: CARDINAL;
|
|
|
+ 1737 savedArgs: ARRAY [0 .. 31]
|
|
|
+ 1738 OF AST.Node; .)
|
|
|
+ 1739 = (. (* Parsing the actual can clobber
|
|
|
+ 1740 the enclosing call's argument
|
|
|
+ 1741 list (Factor resets astNArgs),
|
|
|
+ 1742 so save/restore it. *)
|
|
|
+ 1743 savedN := astNArgs; aj := 0;
|
|
|
+ 1744 WHILE aj <= HIGH(astArgs) DO
|
|
|
+ 1745 savedArgs[aj] := astArgs[aj];
|
|
|
+ 1746 INC(aj)
|
|
|
+ 1747 END; .)
|
|
|
+ 1748 Expr<at, qe> (. astNArgs := savedN; aj := 0;
|
|
|
+ 1749 WHILE aj <= HIGH(astArgs) DO
|
|
|
+ 1750 astArgs[aj] := savedArgs[aj];
|
|
|
+ 1751 INC(aj)
|
|
|
+ 1752 END;
|
|
|
+ 1753 IF astNArgs <= HIGH(astArgs) THEN
|
|
|
+ 1754 astArgs[astNArgs] := astCur;
|
|
|
+ 1755 INC(astNArgs)
|
|
|
+ 1756 END;
|
|
|
+ 1757 va := (NOT ind)
|
|
|
+ 1758 AND (methCls =
|
|
|
+ 1759 SymTab.InvalidType)
|
|
|
+ 1760 AND (SymTab.SymKind(pn) =
|
|
|
+ 1761 SymTab.KindProc)
|
|
|
+ 1762 AND SymTab.Varargs(pn);
|
|
|
+ 1763 IF ind THEN
|
|
|
+ 1764 ft :=
|
|
|
+ 1765 SymTab.ProcTypeParamType(pt,
|
|
|
+ 1766 i);
|
|
|
+ 1767 isV :=
|
|
|
+ 1768 SymTab.ProcTypeParamIsVar(pt,
|
|
|
+ 1769 i)
|
|
|
+ 1770 ELSIF methCls #
|
|
|
+ 1771 SymTab.InvalidType THEN
|
|
|
+ 1772 ft :=
|
|
|
+ 1773 SymTab.ClassMethodParamType(
|
|
|
+ 1774 methCls, pn, i);
|
|
|
+ 1775 isV :=
|
|
|
+ 1776 SymTab.ClassMethodParamIsVar(
|
|
|
+ 1777 methCls, pn, i)
|
|
|
+ 1778 ELSE
|
|
|
+ 1779 ft := SymTab.ParamType(pn, i);
|
|
|
+ 1780 isV := SymTab.ParamIsVar(pn, i)
|
|
|
+ 1781 END;
|
|
|
+ 1782 IF (at = SymTab.InvalidType) THEN
|
|
|
+ 1783 ELSIF ft = SymTab.InvalidType THEN
|
|
|
+ 1784 IF va THEN
|
|
|
+ 1785 QbeGen.CArgAdd(qe, at, qa, cl)
|
|
|
+ 1786 END
|
|
|
+ 1787 ELSIF isV THEN
|
|
|
+ 1788 IF (SymTab.ClassOf(at)
|
|
|
+ 1789 = SymTab.ClChar)
|
|
|
+ 1790 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1791 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1792 = SymTab.ClChar)
|
|
|
+ 1793 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1794 (* 1-char string
|
|
|
+ 1795 literal passed to
|
|
|
+ 1796 a VAR ARRAY OF CHAR *)
|
|
|
+ 1797 QbeGen.DeclCharStr(qe,
|
|
|
+ 1798 qa);
|
|
|
+ 1799 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1800 "l") THEN
|
|
|
+ 1801 SemError(233)
|
|
|
+ 1802 END
|
|
|
+ 1803 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
+ 1804 qa) THEN
|
|
|
+ 1805 SemError(233)
|
|
|
+ 1806 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
+ 1807 ft) THEN
|
|
|
+ 1808 SemError(233)
|
|
|
+ 1809 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
+ 1810 "l") THEN
|
|
|
+ 1811 SemError(233)
|
|
|
+ 1812 END
|
|
|
+ 1813 ELSE
|
|
|
+ 1814 IF (SymTab.ClassOf(at)
|
|
|
+ 1815 = SymTab.ClChar)
|
|
|
+ 1816 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1817 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1818 = SymTab.ClChar)
|
|
|
+ 1819 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1820 (* 1-char string
|
|
|
+ 1821 literal passed to
|
|
|
+ 1822 ARRAY OF CHAR *)
|
|
|
+ 1823 QbeGen.DeclCharStr(qe,
|
|
|
+ 1824 qa);
|
|
|
+ 1825 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1826 "l") THEN
|
|
|
+ 1827 SemError(233)
|
|
|
+ 1828 END
|
|
|
+ 1829 ELSIF NOT SymTab.Assignable(at,
|
|
|
+ 1830 ft) THEN
|
|
|
+ 1831 SemError(233)
|
|
|
+ 1832 ELSE
|
|
|
+ 1833 conv := (SymTab.ClassOf(
|
|
|
+ 1834 ft) = SymTab.ClReal)
|
|
|
+ 1835 AND SymTab.IsIntFamily(at);
|
|
|
+ 1836 IF conv THEN
|
|
|
+ 1837 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1838 IF NOT QbeGen.CallArg(qt,
|
|
|
+ 1839 "d") THEN
|
|
|
+ 1840 SemError(233)
|
|
|
+ 1841 END
|
|
|
+ 1842 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
+ 1843 QbeGen.ArgClass(ft)) THEN
|
|
|
+ 1844 SemError(233)
|
|
|
+ 1845 END
|
|
|
+ 1846 END
|
|
|
+ 1847 END; .) .
|
|
|
+ 1848 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1849 q, lThen, lElse, lEnd:
|
|
|
+ 1850 QbeGen.QVal;
|
|
|
+ 1851 hasElse: BOOLEAN;
|
|
|
+ 1852 astCond, astIf, astLast,
|
|
|
+ 1853 astNode: AST.Node; .)
|
|
|
+ 1854 = "IF" (. hasElse := FALSE; .)
|
|
|
+ 1855 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
+ 1856 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1857 SemError(214) END;
|
|
|
+ 1858 QbeGen.NewLabel(lThen);
|
|
|
+ 1859 QbeGen.NewLabel(lElse);
|
|
|
+ 1860 QbeGen.NewLabel(lEnd);
|
|
|
+ 1861 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 1862 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 1863 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
+ 1864 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1865 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1866 astIf := astNode;
|
|
|
+ 1867 astLast := astNode;
|
|
|
+ 1868 QbeGen.Jmp(lEnd); .)
|
|
|
+ 1869 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1870 QbeGen.NewLabel(lElse); .)
|
|
|
+ 1871 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
+ 1872 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1873 SemError(214) END;
|
|
|
+ 1874 QbeGen.NewLabel(lThen);
|
|
|
+ 1875 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 1876 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 1877 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
+ 1878 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1879 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1880 AST.SetChild(astLast, 2, astNode);
|
|
|
+ 1881 astLast := astNode;
|
|
|
+ 1882 QbeGen.Jmp(lEnd); .) }
|
|
|
+ 1883 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1884 hasElse := TRUE;
|
|
|
+ 1885 astStmt := AST.NoNode; .)
|
|
|
+ 1886 [ StatSeq ] (. AST.SetChild(astLast, 2, astStmt); .) ]
|
|
|
+ 1887 "END" (. astStmt := astIf;
|
|
|
+ 1888 IF hasElse THEN
|
|
|
+ 1889 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1890 ELSE QbeGen.EmitLabel(lElse);
|
|
|
+ 1891 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1892 END; .) .
|
|
|
+ 1893 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1894 q, lTop, lBody, lEnd:
|
|
|
+ 1895 QbeGen.QVal;
|
|
|
+ 1896 astCond, astNode: AST.Node; .)
|
|
|
+ 1897 = "WHILE" (. astStmt := AST.NoNode;
|
|
|
+ 1898 QbeGen.NewLabel(lTop);
|
|
|
+ 1899 QbeGen.NewLabel(lBody);
|
|
|
+ 1900 QbeGen.NewLabel(lEnd);
|
|
|
+ 1901 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1902 Expr<t, q> (. astCond := astCur;
|
|
|
+ 1903 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1904 SemError(214) END;
|
|
|
+ 1905 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
+ 1906 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1907 "DO" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkWhile);
|
|
|
+ 1908 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1909 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1910 astStmt := astNode;
|
|
|
+ 1911 QbeGen.Jmp(lTop); .)
|
|
|
+ 1912 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1913 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1914 q, lTop, lEnd: QbeGen.QVal;
|
|
|
+ 1915 astCond, astBody, astNode:
|
|
|
+ 1916 AST.Node; .)
|
|
|
+ 1917 = "REPEAT" (. astStmt := AST.NoNode;
|
|
|
+ 1918 QbeGen.NewLabel(lTop);
|
|
|
+ 1919 QbeGen.NewLabel(lEnd);
|
|
|
+ 1920 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1921 [ StatSeq ] (. astBody := astStmt; .)
|
|
|
+ 1922 "UNTIL" Expr<t, q> (. astCond := astCur;
|
|
|
+ 1923 astNode := AST.MakeNode(AST.NkRepeat);
|
|
|
+ 1924 AST.SetChild(astNode, 0, astBody);
|
|
|
+ 1925 AST.SetChild(astNode, 1, astCond);
|
|
|
+ 1926 astStmt := astNode;
|
|
|
+ 1927 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1928 SemError(214) END;
|
|
|
+ 1929 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
+ 1930 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1931 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; astNode: AST.Node; .)
|
|
|
+ 1932 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1933 astStmt := AST.NoNode;
|
|
|
+ 1934 QbeGen.NewLabel(lEnd);
|
|
|
+ 1935 QbeGen.PushLoop(lEnd);
|
|
|
+ 1936 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1937 [ StatSeq ]
|
|
|
+ 1938 "END" (. astNode := AST.MakeNode(AST.NkLoop);
|
|
|
+ 1939 AST.SetChild(astNode, 0, astStmt);
|
|
|
+ 1940 astStmt := astNode;
|
|
|
+ 1941 QbeGen.Jmp(lTop);
|
|
|
+ 1942 QbeGen.PopLoop;
|
|
|
+ 1943 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1944 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
+ 1945 Runtime direction would need a compare-select; the literal
|
|
|
+ 1946 sign picks cslew/csegew at "DO" time. *)
|
|
|
+ 1947 ForStat (. VAR lv: SymTab.Name;
|
|
|
+ 1948 tlo, thi, tby:
|
|
|
+ 1949 SymTab.TypeIndex;
|
|
|
+ 1950 qlo, qhi, qby, qt, qk, qb:
|
|
|
+ 1951 QbeGen.QVal;
|
|
|
+ 1952 lTop, lBody, lEnd:
|
|
|
+ 1953 QbeGen.QVal;
|
|
|
+ 1954 by: INTEGER;
|
|
|
+ 1955 ok: BOOLEAN;
|
|
|
+ 1956 astVar, astLo, astHi, astBy,
|
|
|
+ 1957 astNode: AST.Node; .)
|
|
|
+ 1958 = "FOR" (. by := 1; .)
|
|
|
+ 1959 GetIdent<lv> (. astVar := AST.MakeLeaf(AST.NkIdent, lv);
|
|
|
+ 1960 astStmt := AST.NoNode;
|
|
|
+ 1961 astBy := AST.NoNode;
|
|
|
+ 1962 ok := SymTab.Lookup(lv);
|
|
|
+ 1963 IF NOT ok THEN
|
|
|
+ 1964 SemError(201)
|
|
|
+ 1965 ELSIF (SymTab.SymKind(lv) #
|
|
|
+ 1966 SymTab.KindVar)
|
|
|
+ 1967 AND (SymTab.SymKind(lv) #
|
|
|
+ 1968 SymTab.KindParam) THEN
|
|
|
+ 1969 SemError(220); ok := FALSE
|
|
|
+ 1970 ELSIF NOT SymTab.IsIntFamily(
|
|
|
+ 1971 SymTab.SymType(lv)) THEN
|
|
|
+ 1972 SemError(220); ok := FALSE
|
|
|
+ 1973 END; .)
|
|
|
+ 1974 ":=" Expr<tlo, qlo> (. astLo := astCur;
|
|
|
+ 1975 IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
+ 1976 SemError(220); ok := FALSE
|
|
|
+ 1977 END; .)
|
|
|
+ 1978 "TO" Expr<thi, qhi> (. astHi := astCur;
|
|
|
+ 1979 IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
+ 1980 SemError(220); ok := FALSE
|
|
|
+ 1981 END; .)
|
|
|
+ 1982 [ "BY" Expr<tby, qby> (. astBy := astCur;
|
|
|
+ 1983 IF (tby #
|
|
|
+ 1984 SymTab.InvalidType)
|
|
|
+ 1985 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
+ 1986 SemError(220); ok := FALSE
|
|
|
+ 1987 END;
|
|
|
+ 1988 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
+ 1989 SemError(230); by := 1
|
|
|
+ 1990 ELSIF by = 0 THEN
|
|
|
+ 1991 SemError(220); by := 1
|
|
|
+ 1992 END; .) ]
|
|
|
+ 1993 "DO" (. IF ok THEN
|
|
|
+ 1994 QbeGen.StoreVar(lv, qlo,
|
|
|
+ 1995 FALSE) END;
|
|
|
+ 1996 QbeGen.NewLabel(lTop);
|
|
|
+ 1997 QbeGen.NewLabel(lBody);
|
|
|
1998 QbeGen.NewLabel(lEnd);
|
|
|
- 1999 QbeGen.PushLoop(lEnd);
|
|
|
- 2000 QbeGen.EmitLabel(lTop); .)
|
|
|
- 2001 [ StatSeq ]
|
|
|
- 2002 "END" (. astNode := AST.MakeNode(AST.NkLoop);
|
|
|
- 2003 AST.SetChild(astNode, 0, astStmt);
|
|
|
- 2004 astStmt := astNode;
|
|
|
- 2005 QbeGen.Jmp(lTop);
|
|
|
- 2006 QbeGen.PopLoop;
|
|
|
- 2007 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 2008 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
- 2009 Runtime direction would need a compare-select; the literal
|
|
|
- 2010 sign picks cslew/csegew at "DO" time. *)
|
|
|
- 2011 ForStat (. VAR lv: SymTab.Name;
|
|
|
- 2012 tlo, thi, tby:
|
|
|
- 2013 SymTab.TypeIndex;
|
|
|
- 2014 qlo, qhi, qby, qt, qk, qb:
|
|
|
- 2015 QbeGen.QVal;
|
|
|
- 2016 lTop, lBody, lEnd:
|
|
|
- 2017 QbeGen.QVal;
|
|
|
- 2018 by: INTEGER;
|
|
|
- 2019 ok: BOOLEAN;
|
|
|
- 2020 astVar, astLo, astHi, astBy,
|
|
|
- 2021 astNode: AST.Node; .)
|
|
|
- 2022 = "FOR" (. by := 1; .)
|
|
|
- 2023 GetIdent<lv> (. astVar := AST.MakeLeaf(AST.NkIdent, lv);
|
|
|
- 2024 astStmt := AST.NoNode;
|
|
|
- 2025 astBy := AST.NoNode;
|
|
|
- 2026 ok := SymTab.Lookup(lv);
|
|
|
- 2027 IF NOT ok THEN
|
|
|
- 2028 SemError(201)
|
|
|
- 2029 ELSIF (SymTab.SymKind(lv) #
|
|
|
- 2030 SymTab.KindVar)
|
|
|
- 2031 AND (SymTab.SymKind(lv) #
|
|
|
- 2032 SymTab.KindParam) THEN
|
|
|
- 2033 SemError(220); ok := FALSE
|
|
|
- 2034 ELSIF NOT SymTab.IsIntFamily(
|
|
|
- 2035 SymTab.SymType(lv)) THEN
|
|
|
- 2036 SemError(220); ok := FALSE
|
|
|
- 2037 END; .)
|
|
|
- 2038 ":=" Expr<tlo, qlo> (. astLo := astCur;
|
|
|
- 2039 IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
- 2040 SemError(220); ok := FALSE
|
|
|
- 2041 END; .)
|
|
|
- 2042 "TO" Expr<thi, qhi> (. astHi := astCur;
|
|
|
- 2043 IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
- 2044 SemError(220); ok := FALSE
|
|
|
- 2045 END; .)
|
|
|
- 2046 [ "BY" Expr<tby, qby> (. astBy := astCur;
|
|
|
- 2047 IF (tby #
|
|
|
- 2048 SymTab.InvalidType)
|
|
|
- 2049 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
- 2050 SemError(220); ok := FALSE
|
|
|
- 2051 END;
|
|
|
- 2052 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
- 2053 SemError(230); by := 1
|
|
|
- 2054 ELSIF by = 0 THEN
|
|
|
- 2055 SemError(220); by := 1
|
|
|
- 2056 END; .) ]
|
|
|
- 2057 "DO" (. IF ok THEN
|
|
|
- 2058 QbeGen.StoreVar(lv, qlo,
|
|
|
- 2059 FALSE) END;
|
|
|
- 2060 QbeGen.NewLabel(lTop);
|
|
|
- 2061 QbeGen.NewLabel(lBody);
|
|
|
- 2062 QbeGen.NewLabel(lEnd);
|
|
|
- 2063 QbeGen.EmitLabel(lTop);
|
|
|
- 2064 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
- 2065 QbeGen.NewTemp(qk);
|
|
|
- 2066 IF by > 0 THEN
|
|
|
- 2067 QbeGen.Op3("cslew", qk,
|
|
|
- 2068 qt, qhi, FALSE)
|
|
|
- 2069 ELSE QbeGen.Op3("csgew", qk,
|
|
|
- 2070 qt, qhi, FALSE)
|
|
|
- 2071 END;
|
|
|
- 2072 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
- 2073 QbeGen.EmitLabel(lBody); .)
|
|
|
- 2074 [ StatSeq ]
|
|
|
- 2075 "END" (. astNode := AST.MakeNode(AST.NkFor);
|
|
|
- 2076 AST.SetChild(astNode, 0, astVar);
|
|
|
- 2077 AST.SetChild(astNode, 1, astLo);
|
|
|
- 2078 AST.SetChild(astNode, 2, astHi);
|
|
|
- 2079 AST.SetChild(astNode, 3, astBy);
|
|
|
- 2080 AST.SetChild(astNode, 4, astStmt);
|
|
|
- 2081 astStmt := astNode;
|
|
|
- 2082 IF ok THEN
|
|
|
- 2083 QbeGen.LoadVar(lv, FALSE,
|
|
|
- 2084 qt);
|
|
|
- 2085 QbeGen.IntStr(by, qb);
|
|
|
- 2086 QbeGen.NewTemp(qk);
|
|
|
- 2087 QbeGen.Op3("add", qk,
|
|
|
- 2088 qt, qb, FALSE);
|
|
|
- 2089 QbeGen.StoreVar(lv, qk,
|
|
|
- 2090 FALSE) END;
|
|
|
- 2091 QbeGen.Jmp(lTop);
|
|
|
- 2092 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 2093 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
- 2094 qsel, lEnd: QbeGen.QVal;
|
|
|
- 2095 arm, astNode, astArms,
|
|
|
- 2096 astArmsTail: AST.Node; .)
|
|
|
- 2097 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
- 2098 AST.SetChild(astNode, 0, astCur);
|
|
|
- 2099 astArms := AST.NoNode;
|
|
|
- 2100 astArmsTail := AST.NoNode;
|
|
|
- 2101 QbeGen.NewLabel(lEnd); .)
|
|
|
- 2102 "OF" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail>
|
|
|
- 2103 { "|" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail> }
|
|
|
- 2104 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
- 2105 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
- 2106 AST.SetOp(arm, 1);
|
|
|
- 2107 AST.SetChild(arm, 0, astStmt);
|
|
|
- 2108 AstAppend(AST.NkBlock,
|
|
|
- 2109 astArms, astArmsTail, arm); .) ]
|
|
|
- 2110 "END" (. AST.SetChild(astNode, 1, astArms);
|
|
|
- 2111 astStmt := astNode;
|
|
|
- 2112 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 2113 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 2114 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 2115 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 2116 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 2117 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 2118 lEnd: QbeGen.QVal; VAR arms, armsTail: AST.Node>
|
|
|
- 2119 (. VAR lBody, lAfter: QbeGen.QVal;
|
|
|
- 2120 arm: AST.Node; .)
|
|
|
- 2121 = (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
- 2122 QbeGen.NewLabel(lBody);
|
|
|
- 2123 QbeGen.NewLabel(lAfter); .)
|
|
|
- 2124 CaseLabel<tsel, qsel, lBody, arm>
|
|
|
- 2125 { "," CaseLabel<tsel, qsel, lBody, arm> }
|
|
|
- 2126 ":" (. astStmt := AST.NoNode;
|
|
|
- 2127 QbeGen.Jmp(lAfter);
|
|
|
- 2128 QbeGen.EmitLabel(lBody); .)
|
|
|
- 2129 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
- 2130 astStmt);
|
|
|
- 2131 AstAppend(AST.NkBlock,
|
|
|
- 2132 arms, armsTail, arm);
|
|
|
- 2133 QbeGen.Jmp(lEnd);
|
|
|
- 2134 QbeGen.EmitLabel(lAfter); .) .
|
|
|
- 2135 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 2136 lBody: QbeGen.QVal; arm: AST.Node>
|
|
|
- 2137 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 2138 q2, q3, qc, qd, qe:
|
|
|
- 2139 QbeGen.QVal;
|
|
|
- 2140 astLab: AST.Node;
|
|
|
- 2141 lNext: QbeGen.QVal; .)
|
|
|
- 2142 = Expr<t2, q2> (. astLab := astCur;
|
|
|
- 2143 IF (t2 #
|
|
|
- 2144 SymTab.InvalidType)
|
|
|
- 2145 AND (tsel #
|
|
|
- 2146 SymTab.InvalidType)
|
|
|
- 2147 AND ((SymTab.ClassOf(t2) =
|
|
|
- 2148 SymTab.ClSet)
|
|
|
- 2149 OR (SymTab.ClassOf(tsel) =
|
|
|
- 2150 SymTab.ClSet)) THEN
|
|
|
- 2151 SemError(230)
|
|
|
- 2152 ELSIF (t2 #
|
|
|
- 2153 SymTab.InvalidType)
|
|
|
- 2154 AND (tsel #
|
|
|
- 2155 SymTab.InvalidType)
|
|
|
- 2156 AND NOT SymTab.EqCheck(t2,
|
|
|
- 2157 tsel) THEN
|
|
|
- 2158 SemError(213) END;
|
|
|
- 2159 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
- 2160 SemError(230);
|
|
|
- 2161 QbeGen.CopyOp("0", q2)
|
|
|
- 2162 END;
|
|
|
- 2163 QbeGen.NewLabel(lNext);
|
|
|
- 2164 QbeGen.Cmp(SymTab.OpEq,
|
|
|
- 2165 qsel, q2, qc, FALSE);
|
|
|
- 2166 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
- 2167 QbeGen.EmitLabel(lNext); .)
|
|
|
- 2168 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
- 2169 AST.NkSubrange, 0, astLab, astCur);
|
|
|
- 2170 IF (t3 #
|
|
|
- 2171 SymTab.InvalidType)
|
|
|
- 2172 AND (tsel #
|
|
|
- 2173 SymTab.InvalidType)
|
|
|
- 2174 AND NOT SymTab.EqCheck(t3,
|
|
|
- 2175 tsel) THEN
|
|
|
- 2176 SemError(213) END;
|
|
|
- 2177 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
- 2178 SemError(230);
|
|
|
- 2179 QbeGen.CopyOp("0", q3)
|
|
|
- 2180 END;
|
|
|
- 2181 QbeGen.Cmp(SymTab.OpGe,
|
|
|
- 2182 qsel, q2, qc, FALSE);
|
|
|
- 2183 QbeGen.Cmp(SymTab.OpLe,
|
|
|
- 2184 qsel, q3, qd, FALSE);
|
|
|
- 2185 QbeGen.NewTemp(qe);
|
|
|
- 2186 QbeGen.Op3("and", qe, qc, qd,
|
|
|
- 2187 FALSE);
|
|
|
- 2188 QbeGen.NewLabel(lNext);
|
|
|
- 2189 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
- 2190 QbeGen.EmitLabel(lNext); .) ]
|
|
|
- 2191 (. AST.SetChild(arm,
|
|
|
- 2192 AST.NChild(arm), astLab); .) .
|
|
|
- 2193 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2194 q, qt: QbeGen.QVal;
|
|
|
- 2195 res: SymTab.TypeIndex;
|
|
|
- 2196 hadE, conv: BOOLEAN;
|
|
|
- 2197 astVal, astNode: AST.Node; .)
|
|
|
- 2198 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
- 2199 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
- 2200 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
- 2201 IF hadE THEN
|
|
|
- 2202 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2203 END;
|
|
|
- 2204 astStmt := astNode;
|
|
|
- 2205 conv := FALSE;
|
|
|
- 2206 IF NOT SymTab.InProc() THEN
|
|
|
- 2207 SemError(232)
|
|
|
- 2208 ELSE res := SymTab.CurRes();
|
|
|
- 2209 IF NOT hadE THEN
|
|
|
- 2210 IF res #
|
|
|
- 2211 SymTab.InvalidType THEN
|
|
|
- 2212 SemError(232)
|
|
|
- 2213 ELSE QbeGen.EmitRet(q,
|
|
|
- 2214 FALSE)
|
|
|
- 2215 END
|
|
|
- 2216 ELSIF (res =
|
|
|
- 2217 SymTab.InvalidType)
|
|
|
- 2218 OR (t #
|
|
|
- 2219 SymTab.InvalidType)
|
|
|
- 2220 AND NOT SymTab.Assignable(t,
|
|
|
- 2221 res) THEN
|
|
|
- 2222 SemError(232)
|
|
|
- 2223 ELSE
|
|
|
- 2224 conv := (SymTab.ClassOf(
|
|
|
- 2225 res) = SymTab.ClReal)
|
|
|
- 2226 AND SymTab.IsIntFamily(t);
|
|
|
- 2227 IF conv THEN
|
|
|
- 2228 QbeGen.ConvIR(q, qt);
|
|
|
- 2229 QbeGen.EmitRet(qt, TRUE)
|
|
|
- 2230 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
- 2231 END
|
|
|
- 2232 END
|
|
|
- 2233 END; .) .
|
|
|
- 2234 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2235 q: QbeGen.QVal;
|
|
|
- 2236 astVal, astNode: AST.Node; .)
|
|
|
- 2237 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
- 2238 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
- 2239 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
- 2240 IF astVal # AST.NoNode THEN
|
|
|
- 2241 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2242 END;
|
|
|
- 2243 astStmt := astNode;
|
|
|
- 2244 QbeGen.HaltQ; .) .
|
|
|
- 2245 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 2246 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 2247 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 2248 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 2249 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 2250 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 2251 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 2252 (. VAR n, fn, mal: SymTab.Name;
|
|
|
- 2253 cls: INTEGER;
|
|
|
- 2254 ic: SymTab.TypeIndex;
|
|
|
- 2255 curT, it, eT, bt:
|
|
|
- 2256 SymTab.TypeIndex;
|
|
|
- 2257 iq, ql, qlo, qhi, qe:
|
|
|
- 2258 QbeGen.QVal;
|
|
|
- 2259 lo, hi: INTEGER;
|
|
|
- 2260 fo: INTEGER;
|
|
|
- 2261 isOpen: BOOLEAN;
|
|
|
- 2262 qb, cv: QbeGen.QVal;
|
|
|
- 2263 fid, fref, slot: INTEGER;
|
|
|
- 2264 r: BOOLEAN;
|
|
|
- 2265 astDes, astSel: AST.Node;
|
|
|
- 2266 fwd: BOOLEAN; .)
|
|
|
- 2267 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
- 2268 QbeGen.CopyOp(n, qn);
|
|
|
- 2269 sfx := FALSE; fwd := FALSE;
|
|
|
- 2270 fid := 0; fref := 0; slot := 0;
|
|
|
- 2271 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 2272 (* a bare method name inside
|
|
|
- 2273 a CLASS IMPLEMENTATION
|
|
|
- 2274 is a sibling call on
|
|
|
- 2275 THIS *)
|
|
|
- 2276 ic := SymTab.CurImplClass();
|
|
|
- 2277 IF (ic #
|
|
|
- 2278 SymTab.InvalidType)
|
|
|
- 2279 AND SymTab.MethodExists(ic, n) THEN
|
|
|
- 2280 sfx := FALSE;
|
|
|
- 2281 QbeGen.ThisBase(q);
|
|
|
- 2282 QbeGen.ArmRecv(q);
|
|
|
- 2283 methCls := ic;
|
|
|
- 2284 k := SymTab.KindProc;
|
|
|
- 2285 t := SymTab.InvalidType
|
|
|
- 2286 ELSIF SymTab.InProc() THEN
|
|
|
- 2287 (* not declared yet: a
|
|
|
- 2288 forward reference to a
|
|
|
- 2289 module-level variable
|
|
|
- 2290 declared further down. *)
|
|
|
- 2291 k := SymTab.KindVar;
|
|
|
- 2292 r := SymTab.FwdVarRef(n, k,
|
|
|
- 2293 fref, t);
|
|
|
- 2294 slot := QbeGen.FwdDesignator();
|
|
|
- 2295 FwdVarNote(fref, slot);
|
|
|
- 2296 fid := slot;
|
|
|
- 2297 QbeGen.FwdAddrOper(fid, q);
|
|
|
- 2298 sfx := TRUE; fwd := TRUE
|
|
|
- 2299 ELSE
|
|
|
- 2300 SemError(201);
|
|
|
- 2301 t :=
|
|
|
- 2302 SymTab.InvalidType;
|
|
|
- 2303 k := -1;
|
|
|
- 2304 QbeGen.CopyOp("0", q)
|
|
|
- 2305 END
|
|
|
- 2306 ELSE
|
|
|
- 2307 t := SymTab.SymType(n);
|
|
|
- 2308 k := SymTab.SymKind(n);
|
|
|
- 2309 IF k = SymTab.KindConst THEN
|
|
|
- 2310 IF SymTab.Equal(n,
|
|
|
- 2311 "TRUE") THEN
|
|
|
- 2312 t := SymTab.BoolType();
|
|
|
- 2313 QbeGen.CopyOp("1", q)
|
|
|
- 2314 ELSIF SymTab.Equal(n,
|
|
|
- 2315 "FALSE") THEN
|
|
|
- 2316 t := SymTab.BoolType();
|
|
|
- 2317 QbeGen.CopyOp("0", q)
|
|
|
- 2318 ELSIF SymTab.Equal(n,
|
|
|
- 2319 "NIL") THEN
|
|
|
- 2320 QbeGen.CopyOp("0", q)
|
|
|
- 2321 ELSE
|
|
|
- 2322 cls :=
|
|
|
- 2323 SymTab.ClassOf(t);
|
|
|
- 2324 IF (t #
|
|
|
- 2325 SymTab.InvalidType)
|
|
|
- 2326 AND ((cls = SymTab.ClInt)
|
|
|
- 2327 OR (cls
|
|
|
- 2328 = SymTab.ClChar)
|
|
|
- 2329 OR (cls
|
|
|
- 2330 = SymTab.ClEnum)
|
|
|
- 2331 OR (cls
|
|
|
- 2332 = SymTab.ClReal)
|
|
|
- 2333 OR (cls
|
|
|
- 2334 = SymTab.ClLong)
|
|
|
- 2335 OR (cls
|
|
|
- 2336 = SymTab.ClNil)) THEN
|
|
|
- 2337 IF cls = SymTab.ClNil THEN
|
|
|
- 2338 QbeGen.CopyOp("0", q)
|
|
|
- 2339 ELSIF ((cls
|
|
|
- 2340 = SymTab.ClInt)
|
|
|
- 2341 OR (cls
|
|
|
- 2342 = SymTab.ClChar)
|
|
|
- 2343 OR (cls
|
|
|
- 2344 = SymTab.ClEnum)
|
|
|
- 2345 OR (cls
|
|
|
- 2346 = SymTab.ClLong))
|
|
|
- 2347 AND SymTab.GetSymVal(n, cv)
|
|
|
- 2348 AND QbeGen.IsImm(cv) THEN
|
|
|
- 2349 QbeGen.CopyOp(cv, q)
|
|
|
- 2350 ELSE
|
|
|
- 2351 QbeGen.LoadVar(n,
|
|
|
- 2352 cls = SymTab.ClReal,
|
|
|
- 2353 q)
|
|
|
- 2354 END
|
|
|
- 2355 ELSIF (cls = SymTab.ClArray)
|
|
|
- 2356 OR (cls = SymTab.ClRecord)
|
|
|
- 2357 OR (cls = SymTab.ClClass)
|
|
|
- 2358 OR (cls = SymTab.ClStr)
|
|
|
- 2359 OR (cls = SymTab.ClUStr) THEN
|
|
|
- 2360 (* aggregate constant:
|
|
|
- 2361 its value IS the
|
|
|
- 2362 descriptor address *)
|
|
|
- 2363 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
- 2364 QbeGen.CopyOp(cv, q)
|
|
|
- 2365 ELSE
|
|
|
- 2366 QbeGen.CopyOp("0", q)
|
|
|
- 2367 END
|
|
|
- 2368 ELSE
|
|
|
- 2369 IF t #
|
|
|
- 2370 SymTab.InvalidType THEN
|
|
|
- 2371 SemError(230)
|
|
|
- 2372 END;
|
|
|
- 2373 QbeGen.CopyOp("0", q)
|
|
|
- 2374 END
|
|
|
- 2375 END
|
|
|
- 2376 ELSIF (k = SymTab.KindVar)
|
|
|
- 2377 OR (k = SymTab.KindParam) THEN
|
|
|
- 2378 cls :=
|
|
|
- 2379 SymTab.ClassOf(t);
|
|
|
- 2380 IF (cls = SymTab.ClInt)
|
|
|
- 2381 OR (cls = SymTab.ClBool)
|
|
|
- 2382 OR (cls = SymTab.ClChar)
|
|
|
- 2383 OR (cls = SymTab.ClUChar)
|
|
|
- 2384 OR (cls = SymTab.ClEnum)
|
|
|
- 2385 OR (cls
|
|
|
- 2386 = SymTab.ClReal) THEN
|
|
|
- 2387 QbeGen.LoadVar(n,
|
|
|
- 2388 cls = SymTab.ClReal, q)
|
|
|
- 2389 ELSIF (cls = SymTab.ClPtr)
|
|
|
- 2390 OR (cls = SymTab.ClProc) THEN
|
|
|
- 2391 QbeGen.LoadPtr(n, q)
|
|
|
- 2392 ELSIF cls = SymTab.ClLong THEN
|
|
|
- 2393 QbeGen.LoadLong(n, q)
|
|
|
- 2394 ELSIF (cls
|
|
|
- 2395 = SymTab.ClArray)
|
|
|
- 2396 OR (cls
|
|
|
- 2397 = SymTab.ClSet)
|
|
|
- 2398 OR (cls
|
|
|
- 2399 = SymTab.ClRecord)
|
|
|
- 2400 OR (cls
|
|
|
- 2401 = SymTab.ClUStr)
|
|
|
- 2402 OR (cls
|
|
|
- 2403 = SymTab.ClClass) THEN
|
|
|
- 2404 QbeGen.AddrOf(n, q)
|
|
|
- 2405 ELSE SemError(230);
|
|
|
- 2406 QbeGen.CopyOp("0", q)
|
|
|
- 2407 END
|
|
|
- 2408 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 2409 IF k = SymTab.KindImport THEN
|
|
|
- 2410 SemError(230)
|
|
|
- 2411 ELSIF k =
|
|
|
- 2412 SymTab.KindProc THEN
|
|
|
- 2413 (* bare procedure name:
|
|
|
- 2414 a following ArgList
|
|
|
- 2415 makes it a call;
|
|
|
- 2416 otherwise Fact
|
|
|
- 2417 reports 230 *)
|
|
|
- 2418 ELSE
|
|
|
- 2419 IF k = SymTab.KindField THEN
|
|
|
- 2420 IF QbeGen.TopWith(qb) THEN
|
|
|
- 2421 fo :=
|
|
|
- 2422 SymTab.FieldOffset(
|
|
|
- 2423 SymTab.FieldOwner(n),
|
|
|
- 2424 n);
|
|
|
- 2425 QbeGen.FieldAddr(qb,
|
|
|
- 2426 fo, q);
|
|
|
- 2427 sfx := TRUE
|
|
|
- 2428 ELSE SemError(230);
|
|
|
- 2429 QbeGen.CopyOp("0", q)
|
|
|
- 2430 END
|
|
|
- 2431 END
|
|
|
- 2432 END
|
|
|
- 2433 END
|
|
|
- 2434 END; .)
|
|
|
- 2435 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
- 2436 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n));
|
|
|
- 2437 IF fwd THEN AST.SetOp(astDes, 1) END; .)
|
|
|
- 2438 { "[" Expr<it, iq>
|
|
|
- 2439 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2440 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2441 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2442 SymTab.ClArray THEN
|
|
|
- 2443 SemError(217);
|
|
|
- 2444 t := SymTab.InvalidType
|
|
|
- 2445 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2446 AND (SymTab.ClassOf(it) #
|
|
|
- 2447 SymTab.ClChar)
|
|
|
- 2448 AND (SymTab.ClassOf(it) #
|
|
|
- 2449 SymTab.ClEnum) THEN
|
|
|
- 2450 SemError(218);
|
|
|
- 2451 t := SymTab.InvalidType
|
|
|
- 2452 ELSE
|
|
|
- 2453 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2454 isOpen :=
|
|
|
- 2455 SymTab.IsOpenArray(t);
|
|
|
- 2456 IF isOpen THEN
|
|
|
- 2457 QbeGen.CopyOp("0", qlo);
|
|
|
- 2458 IF SymTab.IsCharArray(t)
|
|
|
- 2459 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2460 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2461 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2462 END
|
|
|
- 2463 ELSE
|
|
|
- 2464 lo := SymTab.ArrayLo(t);
|
|
|
- 2465 hi := SymTab.ArrayHi(t);
|
|
|
- 2466 IF SymTab.IsCharArray(t)
|
|
|
- 2467 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2468 hi := hi + 1
|
|
|
- 2469 END;
|
|
|
- 2470 QbeGen.IntStr(lo, qlo);
|
|
|
- 2471 QbeGen.IntStr(hi, qhi)
|
|
|
- 2472 END;
|
|
|
- 2473 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2474 qhi);
|
|
|
- 2475 eT := SymTab.ArrayElem(t);
|
|
|
- 2476 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2477 t, qe);
|
|
|
- 2478 IF SymTab.ClassOf(eT) =
|
|
|
- 2479 SymTab.ClArray THEN
|
|
|
- 2480 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2481 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2482 END;
|
|
|
- 2483 t := eT; sfx := TRUE
|
|
|
- 2484 END; .)
|
|
|
- 2485 { "," Expr<it, iq>
|
|
|
- 2486 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2487 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2488 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2489 SymTab.ClArray THEN
|
|
|
- 2490 SemError(217);
|
|
|
- 2491 t := SymTab.InvalidType
|
|
|
- 2492 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2493 AND (SymTab.ClassOf(it) #
|
|
|
- 2494 SymTab.ClChar)
|
|
|
- 2495 AND (SymTab.ClassOf(it) #
|
|
|
- 2496 SymTab.ClEnum) THEN
|
|
|
- 2497 SemError(218);
|
|
|
- 2498 t := SymTab.InvalidType
|
|
|
- 2499 ELSE
|
|
|
- 2500 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2501 isOpen :=
|
|
|
- 2502 SymTab.IsOpenArray(t);
|
|
|
- 2503 IF isOpen THEN
|
|
|
- 2504 QbeGen.CopyOp("0", qlo);
|
|
|
- 2505 IF SymTab.IsCharArray(t)
|
|
|
- 2506 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2507 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2508 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2509 END
|
|
|
- 2510 ELSE
|
|
|
- 2511 lo := SymTab.ArrayLo(t);
|
|
|
- 2512 hi := SymTab.ArrayHi(t);
|
|
|
- 2513 IF SymTab.IsCharArray(t)
|
|
|
- 2514 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2515 hi := hi + 1
|
|
|
- 2516 END;
|
|
|
- 2517 QbeGen.IntStr(lo, qlo);
|
|
|
- 2518 QbeGen.IntStr(hi, qhi)
|
|
|
- 2519 END;
|
|
|
- 2520 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2521 qhi);
|
|
|
- 2522 eT := SymTab.ArrayElem(t);
|
|
|
- 2523 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2524 t, qe);
|
|
|
- 2525 IF SymTab.ClassOf(eT) =
|
|
|
- 2526 SymTab.ClArray THEN
|
|
|
- 2527 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2528 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2529 END;
|
|
|
- 2530 t := eT; sfx := TRUE
|
|
|
- 2531 END; .) }
|
|
|
- 2532 "]"
|
|
|
- 2533 | "." GetIdent<fn>
|
|
|
- 2534 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2535 AST.SetOp(astSel, AST.SelField);
|
|
|
- 2536 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
- 2537 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
- 2538 (* qualified L.x: materialize
|
|
|
- 2539 the export, then load it *)
|
|
|
- 2540 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 2541 fn, mal) THEN
|
|
|
- 2542 SemError(201);
|
|
|
- 2543 t := SymTab.InvalidType;
|
|
|
- 2544 QbeGen.CopyOp("0", q)
|
|
|
- 2545 ELSE
|
|
|
- 2546 QbeGen.CopyOp(mal, qn);
|
|
|
- 2547 t := SymTab.SymType(mal);
|
|
|
- 2548 k := SymTab.SymKind(mal);
|
|
|
- 2549 sfx := FALSE;
|
|
|
- 2550 IF k = SymTab.KindProc THEN
|
|
|
- 2551 (* call: ArgList supplies
|
|
|
- 2552 the value *)
|
|
|
- 2553 QbeGen.CopyOp("0", q)
|
|
|
- 2554 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
- 2555 mal, t, k, q) THEN
|
|
|
- 2556 SemError(230);
|
|
|
- 2557 QbeGen.CopyOp("0", q)
|
|
|
- 2558 END
|
|
|
- 2559 END
|
|
|
- 2560 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 2561 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2562 SymTab.ClRecord)
|
|
|
- 2563 AND (SymTab.ClassOf(t) #
|
|
|
- 2564 SymTab.ClClass) THEN
|
|
|
- 2565 SemError(215);
|
|
|
- 2566 t := SymTab.InvalidType
|
|
|
- 2567 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 2568 SymTab.ClClass)
|
|
|
- 2569 AND SymTab.MethodExists(t, fn) THEN
|
|
|
- 2570 (* obj.Method: bind the
|
|
|
- 2571 method and pass obj as
|
|
|
- 2572 the hidden receiver; q
|
|
|
- 2573 already holds the
|
|
|
- 2574 object's address *)
|
|
|
- 2575 QbeGen.ArmRecv(q);
|
|
|
- 2576 QbeGen.CopyOp(fn, n);
|
|
|
- 2577 QbeGen.CopyOp(fn, qn);
|
|
|
- 2578 methCls := t;
|
|
|
- 2579 k := SymTab.KindProc;
|
|
|
- 2580 t := SymTab.InvalidType
|
|
|
- 2581 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2582 fn) THEN
|
|
|
- 2583 SemError(216);
|
|
|
+ 1999 QbeGen.EmitLabel(lTop);
|
|
|
+ 2000 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
+ 2001 QbeGen.NewTemp(qk);
|
|
|
+ 2002 IF by > 0 THEN
|
|
|
+ 2003 QbeGen.Op3("cslew", qk,
|
|
|
+ 2004 qt, qhi, FALSE)
|
|
|
+ 2005 ELSE QbeGen.Op3("csgew", qk,
|
|
|
+ 2006 qt, qhi, FALSE)
|
|
|
+ 2007 END;
|
|
|
+ 2008 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
+ 2009 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 2010 [ StatSeq ]
|
|
|
+ 2011 "END" (. astNode := AST.MakeNode(AST.NkFor);
|
|
|
+ 2012 AST.SetChild(astNode, 0, astVar);
|
|
|
+ 2013 AST.SetChild(astNode, 1, astLo);
|
|
|
+ 2014 AST.SetChild(astNode, 2, astHi);
|
|
|
+ 2015 AST.SetChild(astNode, 3, astBy);
|
|
|
+ 2016 AST.SetChild(astNode, 4, astStmt);
|
|
|
+ 2017 astStmt := astNode;
|
|
|
+ 2018 IF ok THEN
|
|
|
+ 2019 QbeGen.LoadVar(lv, FALSE,
|
|
|
+ 2020 qt);
|
|
|
+ 2021 QbeGen.IntStr(by, qb);
|
|
|
+ 2022 QbeGen.NewTemp(qk);
|
|
|
+ 2023 QbeGen.Op3("add", qk,
|
|
|
+ 2024 qt, qb, FALSE);
|
|
|
+ 2025 QbeGen.StoreVar(lv, qk,
|
|
|
+ 2026 FALSE) END;
|
|
|
+ 2027 QbeGen.Jmp(lTop);
|
|
|
+ 2028 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 2029 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
+ 2030 qsel, lEnd: QbeGen.QVal;
|
|
|
+ 2031 arm, astNode, astArms,
|
|
|
+ 2032 astArmsTail: AST.Node; .)
|
|
|
+ 2033 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
+ 2034 AST.SetChild(astNode, 0, astCur);
|
|
|
+ 2035 astArms := AST.NoNode;
|
|
|
+ 2036 astArmsTail := AST.NoNode;
|
|
|
+ 2037 QbeGen.NewLabel(lEnd); .)
|
|
|
+ 2038 "OF" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail>
|
|
|
+ 2039 { "|" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail> }
|
|
|
+ 2040 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
+ 2041 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
+ 2042 AST.SetOp(arm, 1);
|
|
|
+ 2043 AST.SetChild(arm, 0, astStmt);
|
|
|
+ 2044 AstAppend(AST.NkBlock,
|
|
|
+ 2045 astArms, astArmsTail, arm); .) ]
|
|
|
+ 2046 "END" (. AST.SetChild(astNode, 1, astArms);
|
|
|
+ 2047 astStmt := astNode;
|
|
|
+ 2048 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 2049 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 2050 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 2051 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 2052 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 2053 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 2054 lEnd: QbeGen.QVal; VAR arms, armsTail: AST.Node>
|
|
|
+ 2055 (. VAR lBody, lAfter: QbeGen.QVal;
|
|
|
+ 2056 arm: AST.Node; .)
|
|
|
+ 2057 = (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
+ 2058 QbeGen.NewLabel(lBody);
|
|
|
+ 2059 QbeGen.NewLabel(lAfter); .)
|
|
|
+ 2060 CaseLabel<tsel, qsel, lBody, arm>
|
|
|
+ 2061 { "," CaseLabel<tsel, qsel, lBody, arm> }
|
|
|
+ 2062 ":" (. astStmt := AST.NoNode;
|
|
|
+ 2063 QbeGen.Jmp(lAfter);
|
|
|
+ 2064 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 2065 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
+ 2066 astStmt);
|
|
|
+ 2067 AstAppend(AST.NkBlock,
|
|
|
+ 2068 arms, armsTail, arm);
|
|
|
+ 2069 QbeGen.Jmp(lEnd);
|
|
|
+ 2070 QbeGen.EmitLabel(lAfter); .) .
|
|
|
+ 2071 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 2072 lBody: QbeGen.QVal; arm: AST.Node>
|
|
|
+ 2073 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 2074 q2, q3, qc, qd, qe:
|
|
|
+ 2075 QbeGen.QVal;
|
|
|
+ 2076 astLab: AST.Node;
|
|
|
+ 2077 lNext: QbeGen.QVal; .)
|
|
|
+ 2078 = Expr<t2, q2> (. astLab := astCur;
|
|
|
+ 2079 IF (t2 #
|
|
|
+ 2080 SymTab.InvalidType)
|
|
|
+ 2081 AND (tsel #
|
|
|
+ 2082 SymTab.InvalidType)
|
|
|
+ 2083 AND ((SymTab.ClassOf(t2) =
|
|
|
+ 2084 SymTab.ClSet)
|
|
|
+ 2085 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 2086 SymTab.ClSet)) THEN
|
|
|
+ 2087 SemError(230)
|
|
|
+ 2088 ELSIF (t2 #
|
|
|
+ 2089 SymTab.InvalidType)
|
|
|
+ 2090 AND (tsel #
|
|
|
+ 2091 SymTab.InvalidType)
|
|
|
+ 2092 AND NOT SymTab.EqCheck(t2,
|
|
|
+ 2093 tsel) THEN
|
|
|
+ 2094 SemError(213) END;
|
|
|
+ 2095 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
+ 2096 SemError(230);
|
|
|
+ 2097 QbeGen.CopyOp("0", q2)
|
|
|
+ 2098 END;
|
|
|
+ 2099 QbeGen.NewLabel(lNext);
|
|
|
+ 2100 QbeGen.Cmp(SymTab.OpEq,
|
|
|
+ 2101 qsel, q2, qc, FALSE);
|
|
|
+ 2102 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
+ 2103 QbeGen.EmitLabel(lNext); .)
|
|
|
+ 2104 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
+ 2105 AST.NkSubrange, 0, astLab, astCur);
|
|
|
+ 2106 IF (t3 #
|
|
|
+ 2107 SymTab.InvalidType)
|
|
|
+ 2108 AND (tsel #
|
|
|
+ 2109 SymTab.InvalidType)
|
|
|
+ 2110 AND NOT SymTab.EqCheck(t3,
|
|
|
+ 2111 tsel) THEN
|
|
|
+ 2112 SemError(213) END;
|
|
|
+ 2113 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
+ 2114 SemError(230);
|
|
|
+ 2115 QbeGen.CopyOp("0", q3)
|
|
|
+ 2116 END;
|
|
|
+ 2117 QbeGen.Cmp(SymTab.OpGe,
|
|
|
+ 2118 qsel, q2, qc, FALSE);
|
|
|
+ 2119 QbeGen.Cmp(SymTab.OpLe,
|
|
|
+ 2120 qsel, q3, qd, FALSE);
|
|
|
+ 2121 QbeGen.NewTemp(qe);
|
|
|
+ 2122 QbeGen.Op3("and", qe, qc, qd,
|
|
|
+ 2123 FALSE);
|
|
|
+ 2124 QbeGen.NewLabel(lNext);
|
|
|
+ 2125 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
+ 2126 QbeGen.EmitLabel(lNext); .) ]
|
|
|
+ 2127 (. AST.SetChild(arm,
|
|
|
+ 2128 AST.NChild(arm), astLab); .) .
|
|
|
+ 2129 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2130 q, qt: QbeGen.QVal;
|
|
|
+ 2131 res: SymTab.TypeIndex;
|
|
|
+ 2132 hadE, conv: BOOLEAN;
|
|
|
+ 2133 astVal, astNode: AST.Node; .)
|
|
|
+ 2134 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
+ 2135 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
+ 2136 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
+ 2137 IF hadE THEN
|
|
|
+ 2138 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2139 END;
|
|
|
+ 2140 astStmt := astNode;
|
|
|
+ 2141 conv := FALSE;
|
|
|
+ 2142 IF NOT SymTab.InProc() THEN
|
|
|
+ 2143 SemError(232)
|
|
|
+ 2144 ELSE res := SymTab.CurRes();
|
|
|
+ 2145 IF NOT hadE THEN
|
|
|
+ 2146 IF res #
|
|
|
+ 2147 SymTab.InvalidType THEN
|
|
|
+ 2148 SemError(232)
|
|
|
+ 2149 ELSE QbeGen.EmitRet(q,
|
|
|
+ 2150 FALSE)
|
|
|
+ 2151 END
|
|
|
+ 2152 ELSIF (res =
|
|
|
+ 2153 SymTab.InvalidType)
|
|
|
+ 2154 OR (t #
|
|
|
+ 2155 SymTab.InvalidType)
|
|
|
+ 2156 AND NOT SymTab.Assignable(t,
|
|
|
+ 2157 res) THEN
|
|
|
+ 2158 SemError(232)
|
|
|
+ 2159 ELSE
|
|
|
+ 2160 conv := (SymTab.ClassOf(
|
|
|
+ 2161 res) = SymTab.ClReal)
|
|
|
+ 2162 AND SymTab.IsIntFamily(t);
|
|
|
+ 2163 IF conv THEN
|
|
|
+ 2164 QbeGen.ConvIR(q, qt);
|
|
|
+ 2165 QbeGen.EmitRet(qt, TRUE)
|
|
|
+ 2166 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
+ 2167 END
|
|
|
+ 2168 END
|
|
|
+ 2169 END; .) .
|
|
|
+ 2170 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2171 q: QbeGen.QVal;
|
|
|
+ 2172 astVal, astNode: AST.Node; .)
|
|
|
+ 2173 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
+ 2174 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
+ 2175 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
+ 2176 IF astVal # AST.NoNode THEN
|
|
|
+ 2177 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2178 END;
|
|
|
+ 2179 astStmt := astNode;
|
|
|
+ 2180 QbeGen.HaltQ; .) .
|
|
|
+ 2181 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 2182 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 2183 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 2184 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 2185 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 2186 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 2187 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 2188 (. VAR n, fn, mal: SymTab.Name;
|
|
|
+ 2189 cls: INTEGER;
|
|
|
+ 2190 ic: SymTab.TypeIndex;
|
|
|
+ 2191 curT, it, eT, bt:
|
|
|
+ 2192 SymTab.TypeIndex;
|
|
|
+ 2193 iq, ql, qlo, qhi, qe:
|
|
|
+ 2194 QbeGen.QVal;
|
|
|
+ 2195 lo, hi: INTEGER;
|
|
|
+ 2196 fo: INTEGER;
|
|
|
+ 2197 isOpen: BOOLEAN;
|
|
|
+ 2198 qb, cv: QbeGen.QVal;
|
|
|
+ 2199 fid, fref, slot: INTEGER;
|
|
|
+ 2200 r: BOOLEAN;
|
|
|
+ 2201 astDes, astSel: AST.Node;
|
|
|
+ 2202 fwd: BOOLEAN; .)
|
|
|
+ 2203 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
+ 2204 QbeGen.CopyOp(n, qn);
|
|
|
+ 2205 sfx := FALSE; fwd := FALSE;
|
|
|
+ 2206 fid := 0; fref := 0; slot := 0;
|
|
|
+ 2207 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 2208 (* a bare method name inside
|
|
|
+ 2209 a CLASS IMPLEMENTATION
|
|
|
+ 2210 is a sibling call on
|
|
|
+ 2211 THIS *)
|
|
|
+ 2212 ic := SymTab.CurImplClass();
|
|
|
+ 2213 IF (ic #
|
|
|
+ 2214 SymTab.InvalidType)
|
|
|
+ 2215 AND SymTab.MethodExists(ic, n) THEN
|
|
|
+ 2216 sfx := FALSE;
|
|
|
+ 2217 QbeGen.ThisBase(q);
|
|
|
+ 2218 QbeGen.ArmRecv(q);
|
|
|
+ 2219 methCls := ic;
|
|
|
+ 2220 k := SymTab.KindProc;
|
|
|
+ 2221 t := SymTab.InvalidType
|
|
|
+ 2222 ELSIF SymTab.InProc() THEN
|
|
|
+ 2223 (* not declared yet: a
|
|
|
+ 2224 forward reference to a
|
|
|
+ 2225 module-level variable
|
|
|
+ 2226 declared further down. *)
|
|
|
+ 2227 k := SymTab.KindVar;
|
|
|
+ 2228 r := SymTab.FwdVarRef(n, k,
|
|
|
+ 2229 fref, t);
|
|
|
+ 2230 slot := QbeGen.FwdDesignator();
|
|
|
+ 2231 FwdVarNote(fref, slot);
|
|
|
+ 2232 fid := slot;
|
|
|
+ 2233 QbeGen.FwdAddrOper(fid, q);
|
|
|
+ 2234 sfx := TRUE; fwd := TRUE
|
|
|
+ 2235 ELSE
|
|
|
+ 2236 SemError(201);
|
|
|
+ 2237 t :=
|
|
|
+ 2238 SymTab.InvalidType;
|
|
|
+ 2239 k := -1;
|
|
|
+ 2240 QbeGen.CopyOp("0", q)
|
|
|
+ 2241 END
|
|
|
+ 2242 ELSE
|
|
|
+ 2243 t := SymTab.SymType(n);
|
|
|
+ 2244 k := SymTab.SymKind(n);
|
|
|
+ 2245 IF k = SymTab.KindConst THEN
|
|
|
+ 2246 IF SymTab.Equal(n,
|
|
|
+ 2247 "TRUE") THEN
|
|
|
+ 2248 t := SymTab.BoolType();
|
|
|
+ 2249 QbeGen.CopyOp("1", q)
|
|
|
+ 2250 ELSIF SymTab.Equal(n,
|
|
|
+ 2251 "FALSE") THEN
|
|
|
+ 2252 t := SymTab.BoolType();
|
|
|
+ 2253 QbeGen.CopyOp("0", q)
|
|
|
+ 2254 ELSIF SymTab.Equal(n,
|
|
|
+ 2255 "NIL") THEN
|
|
|
+ 2256 QbeGen.CopyOp("0", q)
|
|
|
+ 2257 ELSE
|
|
|
+ 2258 cls :=
|
|
|
+ 2259 SymTab.ClassOf(t);
|
|
|
+ 2260 IF (t #
|
|
|
+ 2261 SymTab.InvalidType)
|
|
|
+ 2262 AND ((cls = SymTab.ClInt)
|
|
|
+ 2263 OR (cls
|
|
|
+ 2264 = SymTab.ClChar)
|
|
|
+ 2265 OR (cls
|
|
|
+ 2266 = SymTab.ClEnum)
|
|
|
+ 2267 OR (cls
|
|
|
+ 2268 = SymTab.ClReal)
|
|
|
+ 2269 OR (cls
|
|
|
+ 2270 = SymTab.ClLong)
|
|
|
+ 2271 OR (cls
|
|
|
+ 2272 = SymTab.ClNil)) THEN
|
|
|
+ 2273 IF cls = SymTab.ClNil THEN
|
|
|
+ 2274 QbeGen.CopyOp("0", q)
|
|
|
+ 2275 ELSIF ((cls
|
|
|
+ 2276 = SymTab.ClInt)
|
|
|
+ 2277 OR (cls
|
|
|
+ 2278 = SymTab.ClChar)
|
|
|
+ 2279 OR (cls
|
|
|
+ 2280 = SymTab.ClEnum)
|
|
|
+ 2281 OR (cls
|
|
|
+ 2282 = SymTab.ClLong))
|
|
|
+ 2283 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 2284 AND QbeGen.IsImm(cv) THEN
|
|
|
+ 2285 QbeGen.CopyOp(cv, q)
|
|
|
+ 2286 ELSE
|
|
|
+ 2287 QbeGen.LoadVar(n,
|
|
|
+ 2288 cls = SymTab.ClReal,
|
|
|
+ 2289 q)
|
|
|
+ 2290 END
|
|
|
+ 2291 ELSIF (cls = SymTab.ClArray)
|
|
|
+ 2292 OR (cls = SymTab.ClRecord)
|
|
|
+ 2293 OR (cls = SymTab.ClClass)
|
|
|
+ 2294 OR (cls = SymTab.ClStr)
|
|
|
+ 2295 OR (cls = SymTab.ClUStr) THEN
|
|
|
+ 2296 (* aggregate constant:
|
|
|
+ 2297 its value IS the
|
|
|
+ 2298 descriptor address *)
|
|
|
+ 2299 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 2300 QbeGen.CopyOp(cv, q)
|
|
|
+ 2301 ELSE
|
|
|
+ 2302 QbeGen.CopyOp("0", q)
|
|
|
+ 2303 END
|
|
|
+ 2304 ELSE
|
|
|
+ 2305 IF t #
|
|
|
+ 2306 SymTab.InvalidType THEN
|
|
|
+ 2307 SemError(230)
|
|
|
+ 2308 END;
|
|
|
+ 2309 QbeGen.CopyOp("0", q)
|
|
|
+ 2310 END
|
|
|
+ 2311 END
|
|
|
+ 2312 ELSIF (k = SymTab.KindVar)
|
|
|
+ 2313 OR (k = SymTab.KindParam) THEN
|
|
|
+ 2314 cls :=
|
|
|
+ 2315 SymTab.ClassOf(t);
|
|
|
+ 2316 IF (cls = SymTab.ClInt)
|
|
|
+ 2317 OR (cls = SymTab.ClBool)
|
|
|
+ 2318 OR (cls = SymTab.ClChar)
|
|
|
+ 2319 OR (cls = SymTab.ClUChar)
|
|
|
+ 2320 OR (cls = SymTab.ClEnum)
|
|
|
+ 2321 OR (cls
|
|
|
+ 2322 = SymTab.ClReal) THEN
|
|
|
+ 2323 QbeGen.LoadVar(n,
|
|
|
+ 2324 cls = SymTab.ClReal, q)
|
|
|
+ 2325 ELSIF (cls = SymTab.ClPtr)
|
|
|
+ 2326 OR (cls = SymTab.ClProc) THEN
|
|
|
+ 2327 QbeGen.LoadPtr(n, q)
|
|
|
+ 2328 ELSIF cls = SymTab.ClLong THEN
|
|
|
+ 2329 QbeGen.LoadLong(n, q)
|
|
|
+ 2330 ELSIF (cls
|
|
|
+ 2331 = SymTab.ClArray)
|
|
|
+ 2332 OR (cls
|
|
|
+ 2333 = SymTab.ClSet)
|
|
|
+ 2334 OR (cls
|
|
|
+ 2335 = SymTab.ClRecord)
|
|
|
+ 2336 OR (cls
|
|
|
+ 2337 = SymTab.ClUStr)
|
|
|
+ 2338 OR (cls
|
|
|
+ 2339 = SymTab.ClClass) THEN
|
|
|
+ 2340 QbeGen.AddrOf(n, q)
|
|
|
+ 2341 ELSE SemError(230);
|
|
|
+ 2342 QbeGen.CopyOp("0", q)
|
|
|
+ 2343 END
|
|
|
+ 2344 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 2345 IF k = SymTab.KindImport THEN
|
|
|
+ 2346 SemError(230)
|
|
|
+ 2347 ELSIF k =
|
|
|
+ 2348 SymTab.KindProc THEN
|
|
|
+ 2349 (* bare procedure name:
|
|
|
+ 2350 a following ArgList
|
|
|
+ 2351 makes it a call;
|
|
|
+ 2352 otherwise Fact
|
|
|
+ 2353 reports 230 *)
|
|
|
+ 2354 ELSE
|
|
|
+ 2355 IF k = SymTab.KindField THEN
|
|
|
+ 2356 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 2357 fo :=
|
|
|
+ 2358 SymTab.FieldOffset(
|
|
|
+ 2359 SymTab.FieldOwner(n),
|
|
|
+ 2360 n);
|
|
|
+ 2361 QbeGen.FieldAddr(qb,
|
|
|
+ 2362 fo, q);
|
|
|
+ 2363 sfx := TRUE
|
|
|
+ 2364 ELSE SemError(230);
|
|
|
+ 2365 QbeGen.CopyOp("0", q)
|
|
|
+ 2366 END
|
|
|
+ 2367 END
|
|
|
+ 2368 END
|
|
|
+ 2369 END
|
|
|
+ 2370 END; .)
|
|
|
+ 2371 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
+ 2372 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n));
|
|
|
+ 2373 IF fwd THEN AST.SetOp(astDes, 1) END; .)
|
|
|
+ 2374 { "[" Expr<it, iq>
|
|
|
+ 2375 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2376 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2377 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2378 SymTab.ClArray THEN
|
|
|
+ 2379 SemError(217);
|
|
|
+ 2380 t := SymTab.InvalidType
|
|
|
+ 2381 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2382 AND (SymTab.ClassOf(it) #
|
|
|
+ 2383 SymTab.ClChar)
|
|
|
+ 2384 AND (SymTab.ClassOf(it) #
|
|
|
+ 2385 SymTab.ClEnum) THEN
|
|
|
+ 2386 SemError(218);
|
|
|
+ 2387 t := SymTab.InvalidType
|
|
|
+ 2388 ELSE
|
|
|
+ 2389 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2390 isOpen :=
|
|
|
+ 2391 SymTab.IsOpenArray(t);
|
|
|
+ 2392 IF isOpen THEN
|
|
|
+ 2393 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2394 IF SymTab.IsCharArray(t)
|
|
|
+ 2395 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2396 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2397 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2398 END
|
|
|
+ 2399 ELSE
|
|
|
+ 2400 lo := SymTab.ArrayLo(t);
|
|
|
+ 2401 hi := SymTab.ArrayHi(t);
|
|
|
+ 2402 IF SymTab.IsCharArray(t)
|
|
|
+ 2403 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2404 hi := hi + 1
|
|
|
+ 2405 END;
|
|
|
+ 2406 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2407 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2408 END;
|
|
|
+ 2409 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2410 qhi);
|
|
|
+ 2411 eT := SymTab.ArrayElem(t);
|
|
|
+ 2412 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2413 t, qe);
|
|
|
+ 2414 IF SymTab.ClassOf(eT) =
|
|
|
+ 2415 SymTab.ClArray THEN
|
|
|
+ 2416 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2417 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2418 END;
|
|
|
+ 2419 t := eT; sfx := TRUE
|
|
|
+ 2420 END; .)
|
|
|
+ 2421 { "," Expr<it, iq>
|
|
|
+ 2422 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2423 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2424 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2425 SymTab.ClArray THEN
|
|
|
+ 2426 SemError(217);
|
|
|
+ 2427 t := SymTab.InvalidType
|
|
|
+ 2428 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2429 AND (SymTab.ClassOf(it) #
|
|
|
+ 2430 SymTab.ClChar)
|
|
|
+ 2431 AND (SymTab.ClassOf(it) #
|
|
|
+ 2432 SymTab.ClEnum) THEN
|
|
|
+ 2433 SemError(218);
|
|
|
+ 2434 t := SymTab.InvalidType
|
|
|
+ 2435 ELSE
|
|
|
+ 2436 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2437 isOpen :=
|
|
|
+ 2438 SymTab.IsOpenArray(t);
|
|
|
+ 2439 IF isOpen THEN
|
|
|
+ 2440 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2441 IF SymTab.IsCharArray(t)
|
|
|
+ 2442 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2443 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2444 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2445 END
|
|
|
+ 2446 ELSE
|
|
|
+ 2447 lo := SymTab.ArrayLo(t);
|
|
|
+ 2448 hi := SymTab.ArrayHi(t);
|
|
|
+ 2449 IF SymTab.IsCharArray(t)
|
|
|
+ 2450 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2451 hi := hi + 1
|
|
|
+ 2452 END;
|
|
|
+ 2453 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2454 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2455 END;
|
|
|
+ 2456 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2457 qhi);
|
|
|
+ 2458 eT := SymTab.ArrayElem(t);
|
|
|
+ 2459 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2460 t, qe);
|
|
|
+ 2461 IF SymTab.ClassOf(eT) =
|
|
|
+ 2462 SymTab.ClArray THEN
|
|
|
+ 2463 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2464 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2465 END;
|
|
|
+ 2466 t := eT; sfx := TRUE
|
|
|
+ 2467 END; .) }
|
|
|
+ 2468 "]"
|
|
|
+ 2469 | "." GetIdent<fn>
|
|
|
+ 2470 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2471 AST.SetOp(astSel, AST.SelField);
|
|
|
+ 2472 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
+ 2473 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
+ 2474 (* qualified L.x: materialize
|
|
|
+ 2475 the export, then load it *)
|
|
|
+ 2476 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 2477 fn, mal) THEN
|
|
|
+ 2478 SemError(201);
|
|
|
+ 2479 t := SymTab.InvalidType;
|
|
|
+ 2480 QbeGen.CopyOp("0", q)
|
|
|
+ 2481 ELSE
|
|
|
+ 2482 QbeGen.CopyOp(mal, qn);
|
|
|
+ 2483 t := SymTab.SymType(mal);
|
|
|
+ 2484 k := SymTab.SymKind(mal);
|
|
|
+ 2485 sfx := FALSE;
|
|
|
+ 2486 IF k = SymTab.KindProc THEN
|
|
|
+ 2487 (* call: ArgList supplies
|
|
|
+ 2488 the value *)
|
|
|
+ 2489 QbeGen.CopyOp("0", q)
|
|
|
+ 2490 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
+ 2491 mal, t, k, q) THEN
|
|
|
+ 2492 SemError(230);
|
|
|
+ 2493 QbeGen.CopyOp("0", q)
|
|
|
+ 2494 END
|
|
|
+ 2495 END
|
|
|
+ 2496 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 2497 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2498 SymTab.ClRecord)
|
|
|
+ 2499 AND (SymTab.ClassOf(t) #
|
|
|
+ 2500 SymTab.ClClass) THEN
|
|
|
+ 2501 SemError(215);
|
|
|
+ 2502 t := SymTab.InvalidType
|
|
|
+ 2503 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 2504 SymTab.ClClass)
|
|
|
+ 2505 AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ 2506 (* obj.Method: bind the
|
|
|
+ 2507 method and pass obj as
|
|
|
+ 2508 the hidden receiver; q
|
|
|
+ 2509 already holds the
|
|
|
+ 2510 object's address *)
|
|
|
+ 2511 QbeGen.ArmRecv(q);
|
|
|
+ 2512 QbeGen.CopyOp(fn, n);
|
|
|
+ 2513 QbeGen.CopyOp(fn, qn);
|
|
|
+ 2514 methCls := t;
|
|
|
+ 2515 k := SymTab.KindProc;
|
|
|
+ 2516 t := SymTab.InvalidType
|
|
|
+ 2517 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2518 fn) THEN
|
|
|
+ 2519 SemError(216);
|
|
|
+ 2520 t := SymTab.InvalidType
|
|
|
+ 2521 ELSE
|
|
|
+ 2522 fo := SymTab.FieldOffset(t,
|
|
|
+ 2523 fn);
|
|
|
+ 2524 t := SymTab.FieldType(t, fn);
|
|
|
+ 2525 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2526 (* array fields are inline:
|
|
|
+ 2527 the field address is the
|
|
|
+ 2528 descriptor, like records *)
|
|
|
+ 2529 QbeGen.CopyOp(qe, q);
|
|
|
+ 2530 sfx := TRUE
|
|
|
+ 2531 END; .)
|
|
|
+ 2532 | "^"
|
|
|
+ 2533 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2534 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2535 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2536 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2537 SymTab.ClPtr THEN
|
|
|
+ 2538 SemError(219);
|
|
|
+ 2539 t := SymTab.InvalidType
|
|
|
+ 2540 ELSE
|
|
|
+ 2541 bt := SymTab.PtrBase(t);
|
|
|
+ 2542 IF bt = SymTab.InvalidType THEN
|
|
|
+ 2543 ELSE
|
|
|
+ 2544 IF sfx THEN
|
|
|
+ 2545 QbeGen.ElemLoad(q, t,
|
|
|
+ 2546 qb);
|
|
|
+ 2547 QbeGen.CopyOp(qb, q)
|
|
|
+ 2548 END;
|
|
|
+ 2549 t := bt;
|
|
|
+ 2550 (* q holds the pointee
|
|
|
+ 2551 address: Fact loads
|
|
|
+ 2552 scalars/pointers and uses
|
|
|
+ 2553 the address for
|
|
|
+ 2554 aggregates; the VAR-actual
|
|
|
+ 2555 note is q itself. *)
|
|
|
+ 2556 sfx := TRUE
|
|
|
+ 2557 END
|
|
|
+ 2558 END; .) } (. astCur := astDes; .) .
|
|
|
+ 2559 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
+ 2560 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
+ 2561 (a value, or a descriptor address for aggregates); each component
|
|
|
+ 2562 descends one level exactly like the Design components. *)
|
|
|
+ 2563 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 2564 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
+ 2565 iq, ql, qlo, qhi, qe, qb:
|
|
|
+ 2566 QbeGen.QVal;
|
|
|
+ 2567 lo, hi, fo: INTEGER;
|
|
|
+ 2568 isOpen: BOOLEAN;
|
|
|
+ 2569 fname: SymTab.Name;
|
|
|
+ 2570 astWrap, astSel: AST.Node; .)
|
|
|
+ 2571 = "[" Expr<it, iq>
|
|
|
+ 2572 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2573 astWrap := AST.MakeNode(
|
|
|
+ 2574 AST.NkDesignator);
|
|
|
+ 2575 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2576 node := astWrap
|
|
|
+ 2577 END;
|
|
|
+ 2578 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2579 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2580 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2581 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2582 SymTab.ClArray THEN
|
|
|
+ 2583 SemError(217);
|
|
|
2584 t := SymTab.InvalidType
|
|
|
- 2585 ELSE
|
|
|
- 2586 fo := SymTab.FieldOffset(t,
|
|
|
- 2587 fn);
|
|
|
- 2588 t := SymTab.FieldType(t, fn);
|
|
|
- 2589 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2590 (* array fields are inline:
|
|
|
- 2591 the field address is the
|
|
|
- 2592 descriptor, like records *)
|
|
|
- 2593 QbeGen.CopyOp(qe, q);
|
|
|
- 2594 sfx := TRUE
|
|
|
- 2595 END; .)
|
|
|
- 2596 | "^"
|
|
|
- 2597 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2598 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2599 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2600 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2601 SymTab.ClPtr THEN
|
|
|
- 2602 SemError(219);
|
|
|
- 2603 t := SymTab.InvalidType
|
|
|
- 2604 ELSE
|
|
|
- 2605 bt := SymTab.PtrBase(t);
|
|
|
- 2606 IF bt = SymTab.InvalidType THEN
|
|
|
- 2607 ELSE
|
|
|
- 2608 IF sfx THEN
|
|
|
- 2609 QbeGen.ElemLoad(q, t,
|
|
|
- 2610 qb);
|
|
|
- 2611 QbeGen.CopyOp(qb, q)
|
|
|
- 2612 END;
|
|
|
- 2613 t := bt;
|
|
|
- 2614 (* q holds the pointee
|
|
|
- 2615 address: Fact loads
|
|
|
- 2616 scalars/pointers and uses
|
|
|
- 2617 the address for
|
|
|
- 2618 aggregates; the VAR-actual
|
|
|
- 2619 note is q itself. *)
|
|
|
- 2620 sfx := TRUE
|
|
|
- 2621 END
|
|
|
- 2622 END; .) } (. astCur := astDes; .) .
|
|
|
- 2623 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
- 2624 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
- 2625 (a value, or a descriptor address for aggregates); each component
|
|
|
- 2626 descends one level exactly like the Design components. *)
|
|
|
- 2627 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 2628 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
- 2629 iq, ql, qlo, qhi, qe, qb:
|
|
|
- 2630 QbeGen.QVal;
|
|
|
- 2631 lo, hi, fo: INTEGER;
|
|
|
- 2632 isOpen: BOOLEAN;
|
|
|
- 2633 fname: SymTab.Name;
|
|
|
- 2634 astWrap, astSel: AST.Node; .)
|
|
|
- 2635 = "[" Expr<it, iq>
|
|
|
- 2636 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2637 astWrap := AST.MakeNode(
|
|
|
- 2638 AST.NkDesignator);
|
|
|
- 2639 AST.SetChild(astWrap, 0, node);
|
|
|
- 2640 node := astWrap
|
|
|
- 2641 END;
|
|
|
- 2642 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2643 AST.MakeUn(AST.NkSelector,
|
|
|
- 2644 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2645 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2646 SymTab.ClArray THEN
|
|
|
- 2647 SemError(217);
|
|
|
- 2648 t := SymTab.InvalidType
|
|
|
- 2649 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2650 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
- 2651 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
- 2652 SemError(218);
|
|
|
- 2653 t := SymTab.InvalidType
|
|
|
- 2654 ELSE
|
|
|
- 2655 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2656 isOpen :=
|
|
|
- 2657 SymTab.IsOpenArray(t);
|
|
|
- 2658 IF isOpen THEN
|
|
|
- 2659 QbeGen.CopyOp("0", qlo);
|
|
|
- 2660 IF SymTab.IsCharArray(t)
|
|
|
- 2661 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2662 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2663 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2664 END
|
|
|
- 2665 ELSE
|
|
|
- 2666 lo := SymTab.ArrayLo(t);
|
|
|
- 2667 hi := SymTab.ArrayHi(t);
|
|
|
- 2668 IF SymTab.IsCharArray(t)
|
|
|
- 2669 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2670 hi := hi + 1
|
|
|
- 2671 END;
|
|
|
- 2672 QbeGen.IntStr(lo, qlo);
|
|
|
- 2673 QbeGen.IntStr(hi, qhi)
|
|
|
- 2674 END;
|
|
|
- 2675 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2676 qhi);
|
|
|
- 2677 eT := SymTab.ArrayElem(t);
|
|
|
- 2678 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2679 t, qe);
|
|
|
- 2680 IF SymTab.ClassOf(eT) =
|
|
|
- 2681 SymTab.ClArray THEN
|
|
|
- 2682 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2683 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2684 END;
|
|
|
- 2685 t := eT; sfx := TRUE
|
|
|
- 2686 END; .)
|
|
|
- 2687 "]"
|
|
|
- 2688 | "." GetIdent<fname>
|
|
|
- 2689 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2690 astWrap := AST.MakeNode(
|
|
|
- 2691 AST.NkDesignator);
|
|
|
- 2692 AST.SetChild(astWrap, 0, node);
|
|
|
- 2693 node := astWrap
|
|
|
- 2694 END;
|
|
|
- 2695 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2696 AST.MakeUn(AST.NkSelector,
|
|
|
- 2697 AST.SelField,
|
|
|
- 2698 AST.MakeLeaf(AST.NkIdent,
|
|
|
- 2699 fname))); IF t = SymTab.InvalidType THEN
|
|
|
- 2700 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2701 SymTab.ClRecord)
|
|
|
- 2702 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 2703 SemError(215);
|
|
|
- 2704 t := SymTab.InvalidType
|
|
|
- 2705 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2706 fname) THEN
|
|
|
- 2707 SemError(216);
|
|
|
- 2708 t := SymTab.InvalidType
|
|
|
- 2709 ELSE
|
|
|
- 2710 fo := SymTab.FieldOffset(t,
|
|
|
- 2711 fname);
|
|
|
- 2712 t := SymTab.FieldType(t, fname);
|
|
|
- 2713 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2714 QbeGen.CopyOp(qe, q);
|
|
|
- 2715 sfx := TRUE
|
|
|
- 2716 END; .)
|
|
|
- 2717 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2718 astWrap := AST.MakeNode(
|
|
|
- 2719 AST.NkDesignator);
|
|
|
- 2720 AST.SetChild(astWrap, 0, node);
|
|
|
- 2721 node := astWrap
|
|
|
- 2722 END;
|
|
|
- 2723 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2724 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2725 AST.SetChild(node,
|
|
|
- 2726 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2727 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2728 SymTab.ClPtr THEN
|
|
|
- 2729 SemError(219);
|
|
|
- 2730 t := SymTab.InvalidType
|
|
|
- 2731 ELSE
|
|
|
- 2732 bt := SymTab.PtrBase(t);
|
|
|
- 2733 IF bt # SymTab.InvalidType THEN
|
|
|
- 2734 IF sfx THEN
|
|
|
- 2735 QbeGen.ElemLoad(q, t, qb);
|
|
|
- 2736 QbeGen.CopyOp(qb, q)
|
|
|
- 2737 END;
|
|
|
- 2738 t := bt; sfx := TRUE
|
|
|
- 2739 END
|
|
|
- 2740 END; .) .
|
|
|
- 2741 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2742 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 2743 op: INTEGER;
|
|
|
- 2744 q2, qt, wl: QbeGen.QVal;
|
|
|
- 2745 astA, astB: AST.Node;
|
|
|
- 2746 astOp: INTEGER;
|
|
|
- 2747 astMade: BOOLEAN;
|
|
|
- 2748 isR: BOOLEAN; .)
|
|
|
- 2749 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
- 2750 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 2751 (. astB := astCur; astMade := TRUE;
|
|
|
- 2752 astOp := AST.OpEq;
|
|
|
- 2753 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
- 2754 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
- 2755 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
- 2756 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
- 2757 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
- 2758 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
- 2759 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
- 2760 END;
|
|
|
- 2761 IF op = SymTab.OpIn THEN
|
|
|
- 2762 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 2763 IF (t = SymTab.InvalidType)
|
|
|
- 2764 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2765 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2766 ELSE
|
|
|
- 2767 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 2768 SymTab.SetCount(t2), qt);
|
|
|
- 2769 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2770 END
|
|
|
- 2771 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 2772 QbeGen.CopyOp("0", q)
|
|
|
- 2773 END
|
|
|
- 2774 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 2775 IF (t = SymTab.InvalidType)
|
|
|
- 2776 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2777 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2778 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 2779 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 2780 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
- 2781 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
- 2782 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2783 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 2784 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 2785 SemError(213); t := SymTab.InvalidType;
|
|
|
- 2786 QbeGen.CopyOp("0", q)
|
|
|
- 2787 ELSE
|
|
|
- 2788 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 2789 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2790 END
|
|
|
- 2791 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2792 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2793 QbeGen.CmpSet(op, q, q2,
|
|
|
- 2794 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 2795 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2796 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2797 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 2798 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2799 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 2800 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 2801 IF SymTab.IsIntFamily(t) THEN
|
|
|
- 2802 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
- 2803 END;
|
|
|
- 2804 IF SymTab.IsIntFamily(t2) THEN
|
|
|
- 2805 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
- 2806 END;
|
|
|
- 2807 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
- 2808 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2809 ELSE
|
|
|
- 2810 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2811 t := SymTab.BoolType();
|
|
|
- 2812 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 2813 QbeGen.CopyOp(qt, q)
|
|
|
- 2814 END
|
|
|
- 2815 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 2816 QbeGen.CopyOp("0", q)
|
|
|
- 2817 END;
|
|
|
- 2818 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
- 2819 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
- 2820 Rel<VAR op: INTEGER>
|
|
|
- 2821 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 2822 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 2823 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 2824 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 2825 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 2826 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 2827 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 2828 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2829 (. VAR t2, res2, lt, rt:
|
|
|
- 2830 SymTab.TypeIndex;
|
|
|
- 2831 op: INTEGER;
|
|
|
- 2832 q2, qt, wq, qf, q2a, q2b:
|
|
|
- 2833 QbeGen.QVal;
|
|
|
- 2834 neg, isR, isL, folded:
|
|
|
- 2835 BOOLEAN;
|
|
|
- 2836 fok: BOOLEAN;
|
|
|
- 2837 lw, rw, mw: CARDINAL;
|
|
|
- 2838 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2839 astA, astB: AST.Node;
|
|
|
- 2840 astSign, astOp: INTEGER; .)
|
|
|
- 2841 = (. neg := FALSE; astSign := 0; .)
|
|
|
- 2842 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
- 2843 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
- 2844 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
- 2845 IF QbeGen.IsImm(q) THEN
|
|
|
- 2846 QbeGen.NegFold(q, q)
|
|
|
- 2847 ELSE QbeGen.NewTemp(qt);
|
|
|
- 2848 QbeGen.NegQ(q, qt,
|
|
|
- 2849 SymTab.ClassOf(t)
|
|
|
- 2850 = SymTab.ClReal);
|
|
|
- 2851 QbeGen.CopyOp(qt, q)
|
|
|
- 2852 END
|
|
|
- 2853 END;
|
|
|
- 2854 IF astSign < 0 THEN
|
|
|
- 2855 astCur := AST.MakeUn(
|
|
|
- 2856 AST.NkUnary, AST.OpSub, astA);
|
|
|
- 2857 astA := astCur
|
|
|
- 2858 END; .)
|
|
|
- 2859 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
- 2860 QbeGen.DelayBegin END; .)
|
|
|
- 2861 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
- 2862 QbeGen.DelayEnd END; .)
|
|
|
- 2863 (. astOp := AST.OpAdd;
|
|
|
- 2864 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
- 2865 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
- 2866 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2867 astCur := astA;
|
|
|
- 2868 IF op = SymTab.OpOr THEN
|
|
|
- 2869 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 2870 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2871 t := SymTab.BoolType()
|
|
|
- 2872 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2873 IF t # SymTab.InvalidType THEN
|
|
|
- 2874 QbeGen.Slot4(qs);
|
|
|
- 2875 QbeGen.NewLabel(lTrue);
|
|
|
- 2876 QbeGen.NewLabel(lNext);
|
|
|
- 2877 QbeGen.NewLabel(lDone);
|
|
|
- 2878 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
- 2879 QbeGen.EmitLabel(lTrue);
|
|
|
- 2880 QbeGen.StoreW(qs, "1");
|
|
|
- 2881 QbeGen.Jmp(lDone);
|
|
|
- 2882 QbeGen.EmitLabel(lNext);
|
|
|
- 2883 QbeGen.DelayFlush;
|
|
|
- 2884 QbeGen.StoreW(qs, q2);
|
|
|
- 2885 QbeGen.Jmp(lDone);
|
|
|
- 2886 QbeGen.EmitLabel(lDone);
|
|
|
- 2887 QbeGen.LoadW(qs, qr);
|
|
|
- 2888 QbeGen.CopyOp(qr, q)
|
|
|
- 2889 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 2890 END
|
|
|
- 2891 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2892 AND (SymTab.UStrCompat(t, t2)
|
|
|
- 2893 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2894 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
- 2895 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
- 2896 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
- 2897 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2898 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
- 2899 (* UString concatenation: a UCHAR operand becomes a
|
|
|
- 2900 1-codepoint UString; the result is a descriptor in the
|
|
|
- 2901 shim's concat buffer. Work on copies so neither
|
|
|
- 2902 operand is clobbered. *)
|
|
|
- 2903 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
- 2904 QbeGen.CopyOp(q, q2a)
|
|
|
- 2905 ELSE
|
|
|
- 2906 QbeGen.UStrFrom(q, q2a)
|
|
|
- 2907 END;
|
|
|
- 2908 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
- 2909 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
- 2910 ELSE
|
|
|
- 2911 QbeGen.UStrFrom(q2, q2b);
|
|
|
- 2912 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
- 2913 END;
|
|
|
- 2914 t := SymTab.NewUStr();
|
|
|
- 2915 QbeGen.CopyOp(qt, q)
|
|
|
- 2916 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2917 AND (SymTab.StrCompat(t, t2)
|
|
|
- 2918 OR (SymTab.IsStrType(t)
|
|
|
- 2919 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 2920 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 2921 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 2922 (* string concatenation; a CHAR operand becomes a
|
|
|
- 2923 1-character string literal. When both operands are
|
|
|
- 2924 constants, fold to a single string literal so a
|
|
|
- 2925 constructor element stays compile-time. *)
|
|
|
- 2926 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
- 2927 qt, fok);
|
|
|
- 2928 IF NOT fok THEN
|
|
|
- 2929 IF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2930 QbeGen.StrCat(q, q2, qt)
|
|
|
- 2931 ELSIF SymTab.IsStrType(t) THEN
|
|
|
- 2932 QbeGen.DeclCharStr(q2, qs);
|
|
|
- 2933 QbeGen.StrCat(q, qs, qt)
|
|
|
- 2934 ELSE
|
|
|
- 2935 QbeGen.DeclCharStr(q, qs);
|
|
|
- 2936 QbeGen.StrCat(qs, q2, qt)
|
|
|
- 2937 END
|
|
|
- 2938 END;
|
|
|
- 2939 t := SymTab.NewStr();
|
|
|
- 2940 QbeGen.CopyOp(qt, q)
|
|
|
- 2941 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2942 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2943 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2944 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2945 mw := lw;
|
|
|
- 2946 IF rw > mw THEN mw := rw END;
|
|
|
- 2947 IF op = SymTab.OpAdd THEN
|
|
|
- 2948 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 2949 ELSE
|
|
|
- 2950 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 2951 END;
|
|
|
- 2952 t := SymTab.NewSet(
|
|
|
- 2953 SymTab.NewSubR(0,
|
|
|
- 2954 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2955 QbeGen.CopyOp(qt, q)
|
|
|
- 2956 ELSE
|
|
|
- 2957 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 2958 lt := t; rt := t2; t := res2
|
|
|
- 2959 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2960 IF t # SymTab.InvalidType THEN
|
|
|
- 2961 isL := SymTab.IsLongFamily(t);
|
|
|
- 2962 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2963 folded := FALSE;
|
|
|
- 2964 IF (NOT isL) AND (NOT isR)
|
|
|
- 2965 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2966 IF op = SymTab.OpAdd THEN
|
|
|
- 2967 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 2968 ELSE
|
|
|
- 2969 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 2970 END
|
|
|
- 2971 END;
|
|
|
- 2972 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2973 ELSE
|
|
|
- 2974 IF isL THEN
|
|
|
- 2975 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 2976 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 2977 END;
|
|
|
- 2978 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 2979 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 2980 END;
|
|
|
- 2981 QbeGen.NewTemp(qt);
|
|
|
- 2982 IF op = SymTab.OpAdd THEN
|
|
|
- 2983 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 2984 ELSE
|
|
|
- 2985 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 2986 END
|
|
|
- 2987 ELSE
|
|
|
- 2988 QbeGen.NewTemp(qt);
|
|
|
- 2989 IF op = SymTab.OpAdd THEN
|
|
|
- 2990 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 2991 ELSE
|
|
|
- 2992 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 2993 END
|
|
|
- 2994 END;
|
|
|
- 2995 QbeGen.CopyOp(qt, q)
|
|
|
- 2996 END
|
|
|
- 2997 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2998 END
|
|
|
- 2999 END; .) } .
|
|
|
- 3000 AddOp<VAR op: INTEGER>
|
|
|
- 3001 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 3002 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 3003 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 3004 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3005 (. VAR t2, res2, lt, rt:
|
|
|
- 3006 SymTab.TypeIndex;
|
|
|
- 3007 op: INTEGER;
|
|
|
- 3008 q2, qt, wq, qf:
|
|
|
- 3009 QbeGen.QVal;
|
|
|
- 3010 isR, isL, folded: BOOLEAN;
|
|
|
- 3011 lw, rw, mw: CARDINAL;
|
|
|
- 3012 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 3013 astA, astB: AST.Node;
|
|
|
- 3014 astOp: INTEGER; .)
|
|
|
- 3015 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
- 3016 QbeGen.DelayBegin END; .)
|
|
|
- 3017 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
- 3018 QbeGen.DelayEnd END; .)
|
|
|
- 3019 (. astOp := AST.OpMul;
|
|
|
- 3020 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
- 3021 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
- 3022 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
- 3023 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
- 3024 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 3025 astCur := astA;
|
|
|
- 3026 IF op = SymTab.OpAnd THEN
|
|
|
- 3027 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 3028 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 3029 t := SymTab.BoolType()
|
|
|
- 3030 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 3031 IF t # SymTab.InvalidType THEN
|
|
|
- 3032 QbeGen.Slot4(qs);
|
|
|
- 3033 QbeGen.NewLabel(lNext);
|
|
|
- 3034 QbeGen.NewLabel(lFalse);
|
|
|
- 3035 QbeGen.NewLabel(lDone);
|
|
|
- 3036 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
- 3037 QbeGen.EmitLabel(lNext);
|
|
|
- 3038 QbeGen.DelayFlush;
|
|
|
- 3039 QbeGen.StoreW(qs, q2);
|
|
|
- 3040 QbeGen.Jmp(lDone);
|
|
|
- 3041 QbeGen.EmitLabel(lFalse);
|
|
|
- 3042 QbeGen.StoreW(qs, "0");
|
|
|
- 3043 QbeGen.Jmp(lDone);
|
|
|
- 3044 QbeGen.EmitLabel(lDone);
|
|
|
- 3045 QbeGen.LoadW(qs, qr);
|
|
|
- 3046 QbeGen.CopyOp(qr, q)
|
|
|
- 3047 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 3048 END
|
|
|
- 3049 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 3050 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 3051 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 3052 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 3053 mw := lw;
|
|
|
- 3054 IF rw > mw THEN mw := rw END;
|
|
|
- 3055 IF op = SymTab.OpTimes THEN
|
|
|
- 3056 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 3057 ELSE
|
|
|
- 3058 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 3059 END;
|
|
|
- 3060 t := SymTab.NewSet(
|
|
|
- 3061 SymTab.NewSubR(0,
|
|
|
- 3062 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 3063 QbeGen.CopyOp(qt, q)
|
|
|
- 3064 ELSE
|
|
|
- 3065 IF SymTab.ArithCheck(t, t2,
|
|
|
- 3066 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 3067 res2) THEN
|
|
|
- 3068 lt := t; rt := t2; t := res2
|
|
|
- 3069 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 3070 IF t # SymTab.InvalidType THEN
|
|
|
- 3071 isL := SymTab.IsLongFamily(t);
|
|
|
- 3072 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 3073 folded := FALSE;
|
|
|
- 3074 IF (NOT isL) AND (NOT isR)
|
|
|
- 3075 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 3076 IF op = SymTab.OpTimes THEN
|
|
|
- 3077 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 3078 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 3079 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 3080 ELSIF op = SymTab.OpMod THEN
|
|
|
- 3081 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 3082 END
|
|
|
- 3083 END;
|
|
|
- 3084 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 3085 ELSE
|
|
|
- 3086 IF isL THEN
|
|
|
- 3087 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 3088 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 3089 END;
|
|
|
- 3090 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 3091 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 3092 END;
|
|
|
- 3093 QbeGen.NewTemp(qt);
|
|
|
- 3094 IF op = SymTab.OpTimes THEN
|
|
|
- 3095 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 3096 ELSIF (op = SymTab.OpDiv)
|
|
|
- 3097 OR (op = SymTab.OpSlash) THEN
|
|
|
- 3098 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 3099 ELSE
|
|
|
- 3100 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 3101 END
|
|
|
- 3102 ELSE
|
|
|
- 3103 QbeGen.NewTemp(qt);
|
|
|
- 3104 IF op = SymTab.OpTimes THEN
|
|
|
- 3105 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 3106 ELSIF (op = SymTab.OpDiv)
|
|
|
- 3107 OR (op = SymTab.OpSlash) THEN
|
|
|
- 3108 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 3109 ELSE
|
|
|
- 3110 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 3111 END
|
|
|
- 3112 END;
|
|
|
- 3113 QbeGen.CopyOp(qt, q)
|
|
|
- 3114 END
|
|
|
- 3115 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3116 END
|
|
|
- 3117 END; .) } .
|
|
|
- 3118 MulOp<VAR op: INTEGER>
|
|
|
- 3119 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 3120 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 3121 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 3122 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 3123 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 3124 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3125 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 3126 et, dt, t2, st, ct2, et2:
|
|
|
- 3127 SymTab.TypeIndex;
|
|
|
- 3128 dk: INTEGER;
|
|
|
- 3129 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
- 3130 QbeGen.QVal;
|
|
|
- 3131 qn, vn: SymTab.Name;
|
|
|
- 3132 vt: SymTab.TypeIndex;
|
|
|
- 3133 c1, c2: INTEGER;
|
|
|
- 3134 lo, hi: INTEGER;
|
|
|
- 3135 isMax: BOOLEAN;
|
|
|
- 3136 called, isHigh, sfx, isCh,
|
|
|
- 3137 isU, uok, isStr: BOOLEAN;
|
|
|
- 3138 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
- 3139 astD: AST.Node;
|
|
|
- 3140 astCall: BOOLEAN;
|
|
|
- 3141 astNode, astNot: AST.Node;
|
|
|
- 3142 j: CARDINAL;
|
|
|
- 3143 astArg2: AST.Node;
|
|
|
- 3144 astBrace: AST.Node;
|
|
|
- 3145 astRes: AST.Node; .)
|
|
|
- 3146 = (. astIsLit := FALSE; .)
|
|
|
- 3147 ( integer (. LexString(s);
|
|
|
- 3148 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
- 3149 t := SymTab.IntType(); .)
|
|
|
- 3150 | charConst (. LexString(s);
|
|
|
- 3151 QbeGen.NormLit(s, q, isCh);
|
|
|
- 3152 IF twoPhase THEN
|
|
|
- 3153 astIsLit := TRUE;
|
|
|
- 3154 astCur := AST.MakeLeaf(
|
|
|
- 3155 AST.NkCharLit, s)
|
|
|
+ 2585 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2586 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
+ 2587 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
+ 2588 SemError(218);
|
|
|
+ 2589 t := SymTab.InvalidType
|
|
|
+ 2590 ELSE
|
|
|
+ 2591 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2592 isOpen :=
|
|
|
+ 2593 SymTab.IsOpenArray(t);
|
|
|
+ 2594 IF isOpen THEN
|
|
|
+ 2595 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2596 IF SymTab.IsCharArray(t)
|
|
|
+ 2597 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2598 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2599 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2600 END
|
|
|
+ 2601 ELSE
|
|
|
+ 2602 lo := SymTab.ArrayLo(t);
|
|
|
+ 2603 hi := SymTab.ArrayHi(t);
|
|
|
+ 2604 IF SymTab.IsCharArray(t)
|
|
|
+ 2605 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2606 hi := hi + 1
|
|
|
+ 2607 END;
|
|
|
+ 2608 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2609 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2610 END;
|
|
|
+ 2611 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2612 qhi);
|
|
|
+ 2613 eT := SymTab.ArrayElem(t);
|
|
|
+ 2614 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2615 t, qe);
|
|
|
+ 2616 IF SymTab.ClassOf(eT) =
|
|
|
+ 2617 SymTab.ClArray THEN
|
|
|
+ 2618 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2619 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2620 END;
|
|
|
+ 2621 t := eT; sfx := TRUE
|
|
|
+ 2622 END; .)
|
|
|
+ 2623 "]"
|
|
|
+ 2624 | "." GetIdent<fname>
|
|
|
+ 2625 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2626 astWrap := AST.MakeNode(
|
|
|
+ 2627 AST.NkDesignator);
|
|
|
+ 2628 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2629 node := astWrap
|
|
|
+ 2630 END;
|
|
|
+ 2631 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2632 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2633 AST.SelField,
|
|
|
+ 2634 AST.MakeLeaf(AST.NkIdent,
|
|
|
+ 2635 fname))); IF t = SymTab.InvalidType THEN
|
|
|
+ 2636 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2637 SymTab.ClRecord)
|
|
|
+ 2638 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 2639 SemError(215);
|
|
|
+ 2640 t := SymTab.InvalidType
|
|
|
+ 2641 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2642 fname) THEN
|
|
|
+ 2643 SemError(216);
|
|
|
+ 2644 t := SymTab.InvalidType
|
|
|
+ 2645 ELSE
|
|
|
+ 2646 fo := SymTab.FieldOffset(t,
|
|
|
+ 2647 fname);
|
|
|
+ 2648 t := SymTab.FieldType(t, fname);
|
|
|
+ 2649 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2650 QbeGen.CopyOp(qe, q);
|
|
|
+ 2651 sfx := TRUE
|
|
|
+ 2652 END; .)
|
|
|
+ 2653 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2654 astWrap := AST.MakeNode(
|
|
|
+ 2655 AST.NkDesignator);
|
|
|
+ 2656 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2657 node := astWrap
|
|
|
+ 2658 END;
|
|
|
+ 2659 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2660 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2661 AST.SetChild(node,
|
|
|
+ 2662 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2663 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2664 SymTab.ClPtr THEN
|
|
|
+ 2665 SemError(219);
|
|
|
+ 2666 t := SymTab.InvalidType
|
|
|
+ 2667 ELSE
|
|
|
+ 2668 bt := SymTab.PtrBase(t);
|
|
|
+ 2669 IF bt # SymTab.InvalidType THEN
|
|
|
+ 2670 IF sfx THEN
|
|
|
+ 2671 QbeGen.ElemLoad(q, t, qb);
|
|
|
+ 2672 QbeGen.CopyOp(qb, q)
|
|
|
+ 2673 END;
|
|
|
+ 2674 t := bt; sfx := TRUE
|
|
|
+ 2675 END
|
|
|
+ 2676 END; .) .
|
|
|
+ 2677 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2678 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 2679 op: INTEGER;
|
|
|
+ 2680 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 2681 astA, astB: AST.Node;
|
|
|
+ 2682 astOp: INTEGER;
|
|
|
+ 2683 astMade: BOOLEAN;
|
|
|
+ 2684 isR: BOOLEAN; .)
|
|
|
+ 2685 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
+ 2686 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 2687 (. astB := astCur; astMade := TRUE;
|
|
|
+ 2688 astOp := AST.OpEq;
|
|
|
+ 2689 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
+ 2690 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
+ 2691 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
+ 2692 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
+ 2693 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
+ 2694 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
+ 2695 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
+ 2696 END;
|
|
|
+ 2697 IF op = SymTab.OpIn THEN
|
|
|
+ 2698 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 2699 IF (t = SymTab.InvalidType)
|
|
|
+ 2700 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2701 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2702 ELSE
|
|
|
+ 2703 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 2704 SymTab.SetCount(t2), qt);
|
|
|
+ 2705 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2706 END
|
|
|
+ 2707 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 2708 QbeGen.CopyOp("0", q)
|
|
|
+ 2709 END
|
|
|
+ 2710 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 2711 IF (t = SymTab.InvalidType)
|
|
|
+ 2712 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2713 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2714 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 2715 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 2716 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
+ 2717 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
+ 2718 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2719 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 2720 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 2721 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2722 QbeGen.CopyOp("0", q)
|
|
|
+ 2723 ELSE
|
|
|
+ 2724 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 2725 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2726 END
|
|
|
+ 2727 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2728 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2729 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 2730 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 2731 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2732 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2733 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 2734 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2735 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 2736 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 2737 IF SymTab.IsIntFamily(t) THEN
|
|
|
+ 2738 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
+ 2739 END;
|
|
|
+ 2740 IF SymTab.IsIntFamily(t2) THEN
|
|
|
+ 2741 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
+ 2742 END;
|
|
|
+ 2743 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
+ 2744 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2745 ELSE
|
|
|
+ 2746 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2747 t := SymTab.BoolType();
|
|
|
+ 2748 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 2749 QbeGen.CopyOp(qt, q)
|
|
|
+ 2750 END
|
|
|
+ 2751 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2752 QbeGen.CopyOp("0", q)
|
|
|
+ 2753 END;
|
|
|
+ 2754 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
+ 2755 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
+ 2756 Rel<VAR op: INTEGER>
|
|
|
+ 2757 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 2758 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 2759 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 2760 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 2761 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 2762 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 2763 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 2764 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2765 (. VAR t2, res2, lt, rt:
|
|
|
+ 2766 SymTab.TypeIndex;
|
|
|
+ 2767 op: INTEGER;
|
|
|
+ 2768 q2, qt, wq, qf, q2a, q2b:
|
|
|
+ 2769 QbeGen.QVal;
|
|
|
+ 2770 neg, isR, isL, folded:
|
|
|
+ 2771 BOOLEAN;
|
|
|
+ 2772 fok: BOOLEAN;
|
|
|
+ 2773 lw, rw, mw: CARDINAL;
|
|
|
+ 2774 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2775 astA, astB: AST.Node;
|
|
|
+ 2776 astSign, astOp: INTEGER; .)
|
|
|
+ 2777 = (. neg := FALSE; astSign := 0; .)
|
|
|
+ 2778 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
+ 2779 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
+ 2780 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
+ 2781 IF QbeGen.IsImm(q) THEN
|
|
|
+ 2782 QbeGen.NegFold(q, q)
|
|
|
+ 2783 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 2784 QbeGen.NegQ(q, qt,
|
|
|
+ 2785 SymTab.ClassOf(t)
|
|
|
+ 2786 = SymTab.ClReal);
|
|
|
+ 2787 QbeGen.CopyOp(qt, q)
|
|
|
+ 2788 END
|
|
|
+ 2789 END;
|
|
|
+ 2790 IF astSign < 0 THEN
|
|
|
+ 2791 astCur := AST.MakeUn(
|
|
|
+ 2792 AST.NkUnary, AST.OpSub, astA);
|
|
|
+ 2793 astA := astCur
|
|
|
+ 2794 END; .)
|
|
|
+ 2795 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
+ 2796 QbeGen.DelayBegin END; .)
|
|
|
+ 2797 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
+ 2798 QbeGen.DelayEnd END; .)
|
|
|
+ 2799 (. astOp := AST.OpAdd;
|
|
|
+ 2800 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
+ 2801 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
+ 2802 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2803 astCur := astA;
|
|
|
+ 2804 IF op = SymTab.OpOr THEN
|
|
|
+ 2805 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 2806 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2807 t := SymTab.BoolType()
|
|
|
+ 2808 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2809 IF t # SymTab.InvalidType THEN
|
|
|
+ 2810 QbeGen.Slot4(qs);
|
|
|
+ 2811 QbeGen.NewLabel(lTrue);
|
|
|
+ 2812 QbeGen.NewLabel(lNext);
|
|
|
+ 2813 QbeGen.NewLabel(lDone);
|
|
|
+ 2814 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
+ 2815 QbeGen.EmitLabel(lTrue);
|
|
|
+ 2816 QbeGen.StoreW(qs, "1");
|
|
|
+ 2817 QbeGen.Jmp(lDone);
|
|
|
+ 2818 QbeGen.EmitLabel(lNext);
|
|
|
+ 2819 QbeGen.DelayFlush;
|
|
|
+ 2820 QbeGen.StoreW(qs, q2);
|
|
|
+ 2821 QbeGen.Jmp(lDone);
|
|
|
+ 2822 QbeGen.EmitLabel(lDone);
|
|
|
+ 2823 QbeGen.LoadW(qs, qr);
|
|
|
+ 2824 QbeGen.CopyOp(qr, q)
|
|
|
+ 2825 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 2826 END
|
|
|
+ 2827 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2828 AND (SymTab.UStrCompat(t, t2)
|
|
|
+ 2829 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2830 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
+ 2831 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
+ 2832 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
+ 2833 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2834 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
+ 2835 (* UString concatenation: a UCHAR operand becomes a
|
|
|
+ 2836 1-codepoint UString; the result is a descriptor in the
|
|
|
+ 2837 shim's concat buffer. Work on copies so neither
|
|
|
+ 2838 operand is clobbered. *)
|
|
|
+ 2839 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
+ 2840 QbeGen.CopyOp(q, q2a)
|
|
|
+ 2841 ELSE
|
|
|
+ 2842 QbeGen.UStrFrom(q, q2a)
|
|
|
+ 2843 END;
|
|
|
+ 2844 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
+ 2845 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
+ 2846 ELSE
|
|
|
+ 2847 QbeGen.UStrFrom(q2, q2b);
|
|
|
+ 2848 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
+ 2849 END;
|
|
|
+ 2850 t := SymTab.NewUStr();
|
|
|
+ 2851 QbeGen.CopyOp(qt, q)
|
|
|
+ 2852 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2853 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 2854 OR (SymTab.IsStrType(t)
|
|
|
+ 2855 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 2856 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 2857 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 2858 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 2859 1-character string literal. When both operands are
|
|
|
+ 2860 constants, fold to a single string literal so a
|
|
|
+ 2861 constructor element stays compile-time. *)
|
|
|
+ 2862 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
+ 2863 qt, fok);
|
|
|
+ 2864 IF NOT fok THEN
|
|
|
+ 2865 IF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2866 QbeGen.StrCat(q, q2, qt)
|
|
|
+ 2867 ELSIF SymTab.IsStrType(t) THEN
|
|
|
+ 2868 QbeGen.DeclCharStr(q2, qs);
|
|
|
+ 2869 QbeGen.StrCat(q, qs, qt)
|
|
|
+ 2870 ELSE
|
|
|
+ 2871 QbeGen.DeclCharStr(q, qs);
|
|
|
+ 2872 QbeGen.StrCat(qs, q2, qt)
|
|
|
+ 2873 END
|
|
|
+ 2874 END;
|
|
|
+ 2875 t := SymTab.NewStr();
|
|
|
+ 2876 QbeGen.CopyOp(qt, q)
|
|
|
+ 2877 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2878 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2879 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2880 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2881 mw := lw;
|
|
|
+ 2882 IF rw > mw THEN mw := rw END;
|
|
|
+ 2883 IF op = SymTab.OpAdd THEN
|
|
|
+ 2884 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 2885 ELSE
|
|
|
+ 2886 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 2887 END;
|
|
|
+ 2888 t := SymTab.NewSet(
|
|
|
+ 2889 SymTab.NewSubR(0,
|
|
|
+ 2890 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2891 QbeGen.CopyOp(qt, q)
|
|
|
+ 2892 ELSE
|
|
|
+ 2893 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 2894 lt := t; rt := t2; t := res2
|
|
|
+ 2895 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2896 IF t # SymTab.InvalidType THEN
|
|
|
+ 2897 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2898 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2899 folded := FALSE;
|
|
|
+ 2900 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2901 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2902 IF op = SymTab.OpAdd THEN
|
|
|
+ 2903 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 2904 ELSE
|
|
|
+ 2905 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 2906 END
|
|
|
+ 2907 END;
|
|
|
+ 2908 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2909 ELSE
|
|
|
+ 2910 IF isL THEN
|
|
|
+ 2911 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 2912 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 2913 END;
|
|
|
+ 2914 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 2915 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 2916 END;
|
|
|
+ 2917 QbeGen.NewTemp(qt);
|
|
|
+ 2918 IF op = SymTab.OpAdd THEN
|
|
|
+ 2919 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 2920 ELSE
|
|
|
+ 2921 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 2922 END
|
|
|
+ 2923 ELSE
|
|
|
+ 2924 QbeGen.NewTemp(qt);
|
|
|
+ 2925 IF op = SymTab.OpAdd THEN
|
|
|
+ 2926 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 2927 ELSE
|
|
|
+ 2928 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 2929 END
|
|
|
+ 2930 END;
|
|
|
+ 2931 QbeGen.CopyOp(qt, q)
|
|
|
+ 2932 END
|
|
|
+ 2933 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2934 END
|
|
|
+ 2935 END; .) } .
|
|
|
+ 2936 AddOp<VAR op: INTEGER>
|
|
|
+ 2937 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 2938 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 2939 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 2940 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2941 (. VAR t2, res2, lt, rt:
|
|
|
+ 2942 SymTab.TypeIndex;
|
|
|
+ 2943 op: INTEGER;
|
|
|
+ 2944 q2, qt, wq, qf:
|
|
|
+ 2945 QbeGen.QVal;
|
|
|
+ 2946 isR, isL, folded: BOOLEAN;
|
|
|
+ 2947 lw, rw, mw: CARDINAL;
|
|
|
+ 2948 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2949 astA, astB: AST.Node;
|
|
|
+ 2950 astOp: INTEGER; .)
|
|
|
+ 2951 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 2952 QbeGen.DelayBegin END; .)
|
|
|
+ 2953 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
+ 2954 QbeGen.DelayEnd END; .)
|
|
|
+ 2955 (. astOp := AST.OpMul;
|
|
|
+ 2956 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
+ 2957 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
+ 2958 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
+ 2959 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
+ 2960 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2961 astCur := astA;
|
|
|
+ 2962 IF op = SymTab.OpAnd THEN
|
|
|
+ 2963 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 2964 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2965 t := SymTab.BoolType()
|
|
|
+ 2966 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2967 IF t # SymTab.InvalidType THEN
|
|
|
+ 2968 QbeGen.Slot4(qs);
|
|
|
+ 2969 QbeGen.NewLabel(lNext);
|
|
|
+ 2970 QbeGen.NewLabel(lFalse);
|
|
|
+ 2971 QbeGen.NewLabel(lDone);
|
|
|
+ 2972 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
+ 2973 QbeGen.EmitLabel(lNext);
|
|
|
+ 2974 QbeGen.DelayFlush;
|
|
|
+ 2975 QbeGen.StoreW(qs, q2);
|
|
|
+ 2976 QbeGen.Jmp(lDone);
|
|
|
+ 2977 QbeGen.EmitLabel(lFalse);
|
|
|
+ 2978 QbeGen.StoreW(qs, "0");
|
|
|
+ 2979 QbeGen.Jmp(lDone);
|
|
|
+ 2980 QbeGen.EmitLabel(lDone);
|
|
|
+ 2981 QbeGen.LoadW(qs, qr);
|
|
|
+ 2982 QbeGen.CopyOp(qr, q)
|
|
|
+ 2983 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 2984 END
|
|
|
+ 2985 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2986 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2987 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2988 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2989 mw := lw;
|
|
|
+ 2990 IF rw > mw THEN mw := rw END;
|
|
|
+ 2991 IF op = SymTab.OpTimes THEN
|
|
|
+ 2992 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 2993 ELSE
|
|
|
+ 2994 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 2995 END;
|
|
|
+ 2996 t := SymTab.NewSet(
|
|
|
+ 2997 SymTab.NewSubR(0,
|
|
|
+ 2998 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2999 QbeGen.CopyOp(qt, q)
|
|
|
+ 3000 ELSE
|
|
|
+ 3001 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 3002 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 3003 res2) THEN
|
|
|
+ 3004 lt := t; rt := t2; t := res2
|
|
|
+ 3005 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 3006 IF t # SymTab.InvalidType THEN
|
|
|
+ 3007 isL := SymTab.IsLongFamily(t);
|
|
|
+ 3008 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 3009 folded := FALSE;
|
|
|
+ 3010 IF (NOT isL) AND (NOT isR)
|
|
|
+ 3011 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 3012 IF op = SymTab.OpTimes THEN
|
|
|
+ 3013 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 3014 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 3015 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 3016 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 3017 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 3018 END
|
|
|
+ 3019 END;
|
|
|
+ 3020 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 3021 ELSE
|
|
|
+ 3022 IF isL THEN
|
|
|
+ 3023 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 3024 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 3025 END;
|
|
|
+ 3026 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 3027 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 3028 END;
|
|
|
+ 3029 QbeGen.NewTemp(qt);
|
|
|
+ 3030 IF op = SymTab.OpTimes THEN
|
|
|
+ 3031 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 3032 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 3033 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 3034 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 3035 ELSE
|
|
|
+ 3036 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 3037 END
|
|
|
+ 3038 ELSE
|
|
|
+ 3039 QbeGen.NewTemp(qt);
|
|
|
+ 3040 IF op = SymTab.OpTimes THEN
|
|
|
+ 3041 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 3042 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 3043 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 3044 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 3045 ELSE
|
|
|
+ 3046 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 3047 END
|
|
|
+ 3048 END;
|
|
|
+ 3049 QbeGen.CopyOp(qt, q)
|
|
|
+ 3050 END
|
|
|
+ 3051 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3052 END
|
|
|
+ 3053 END; .) } .
|
|
|
+ 3054 MulOp<VAR op: INTEGER>
|
|
|
+ 3055 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 3056 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 3057 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 3058 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 3059 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 3060 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3061 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 3062 et, dt, t2, st, ct2, et2:
|
|
|
+ 3063 SymTab.TypeIndex;
|
|
|
+ 3064 dk: INTEGER;
|
|
|
+ 3065 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
+ 3066 QbeGen.QVal;
|
|
|
+ 3067 qn, vn: SymTab.Name;
|
|
|
+ 3068 vt: SymTab.TypeIndex;
|
|
|
+ 3069 c1, c2: INTEGER;
|
|
|
+ 3070 lo, hi: INTEGER;
|
|
|
+ 3071 isMax: BOOLEAN;
|
|
|
+ 3072 called, isHigh, sfx, isCh,
|
|
|
+ 3073 isU, uok, isStr: BOOLEAN;
|
|
|
+ 3074 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
+ 3075 astD: AST.Node;
|
|
|
+ 3076 astCall: BOOLEAN;
|
|
|
+ 3077 astNode, astNot: AST.Node;
|
|
|
+ 3078 j: CARDINAL;
|
|
|
+ 3079 astArg2: AST.Node;
|
|
|
+ 3080 astBrace: AST.Node;
|
|
|
+ 3081 astRes: AST.Node; .)
|
|
|
+ 3082 = (. astIsLit := FALSE; .)
|
|
|
+ 3083 ( integer (. LexString(s);
|
|
|
+ 3084 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
+ 3085 t := SymTab.IntType(); .)
|
|
|
+ 3086 | charConst (. LexString(s);
|
|
|
+ 3087 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 3088 IF twoPhase THEN
|
|
|
+ 3089 astIsLit := TRUE;
|
|
|
+ 3090 astCur := AST.MakeLeaf(
|
|
|
+ 3091 AST.NkCharLit, s)
|
|
|
+ 3092 END;
|
|
|
+ 3093 t := SymTab.CharType(); .)
|
|
|
+ 3094 | real (. LexString(s);
|
|
|
+ 3095 QbeGen.NormReal(s, q);
|
|
|
+ 3096 IF twoPhase THEN
|
|
|
+ 3097 astIsLit := TRUE;
|
|
|
+ 3098 astCur := AST.MakeLeaf(
|
|
|
+ 3099 AST.NkRealLit, s)
|
|
|
+ 3100 END;
|
|
|
+ 3101 t := SymTab.RealType(); .)
|
|
|
+ 3102 | string (. LexString(s);
|
|
|
+ 3103 IF twoPhase THEN
|
|
|
+ 3104 astIsLit := TRUE;
|
|
|
+ 3105 astCur := AST.MakeLeaf(
|
|
|
+ 3106 AST.NkStrLit, s)
|
|
|
+ 3107 END;
|
|
|
+ 3108 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3109 t := SymTab.CharType();
|
|
|
+ 3110 QbeGen.IntStr(
|
|
|
+ 3111 QbeGen.CharVal(s), q)
|
|
|
+ 3112 ELSE t := SymTab.NewStr();
|
|
|
+ 3113 QbeGen.DeclStr(s, q);
|
|
|
+ 3114 (* a literal's value IS its
|
|
|
+ 3115 static descriptor address *)
|
|
|
+ 3116 QbeGen.NoteAddr(q, q)
|
|
|
+ 3117 END; .)
|
|
|
+ 3118 | ustring (. LexString(s);
|
|
|
+ 3119 IF twoPhase THEN
|
|
|
+ 3120 astIsLit := TRUE;
|
|
|
+ 3121 astCur := AST.MakeLeaf(
|
|
|
+ 3122 AST.NkStrLit, s)
|
|
|
+ 3123 END;
|
|
|
+ 3124 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 3125 uok);
|
|
|
+ 3126 IF NOT uok THEN
|
|
|
+ 3127 SemError(234);
|
|
|
+ 3128 t := SymTab.InvalidType
|
|
|
+ 3129 ELSIF isU THEN
|
|
|
+ 3130 t := SymTab.UCharType();
|
|
|
+ 3131 QbeGen.IntStr(ucp, q)
|
|
|
+ 3132 ELSE
|
|
|
+ 3133 t := SymTab.NewUStr();
|
|
|
+ 3134 QbeGen.NoteAddr(q, q)
|
|
|
+ 3135 END; .)
|
|
|
+ 3136 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
+ 3137 astNArgs := 0; called := FALSE;
|
|
|
+ 3138 t := dt;
|
|
|
+ 3139 IF sfx THEN
|
|
|
+ 3140 IF dt =
|
|
|
+ 3141 SymTab.InvalidType THEN
|
|
|
+ 3142 QbeGen.CopyOp("0", q)
|
|
|
+ 3143 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 3144 SymTab.ClRecord)
|
|
|
+ 3145 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3146 SymTab.ClSet)
|
|
|
+ 3147 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3148 SymTab.ClArray)
|
|
|
+ 3149 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3150 SymTab.ClClass) THEN
|
|
|
+ 3151 QbeGen.CopyOp(qd, q)
|
|
|
+ 3152 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 3153 q)
|
|
|
+ 3154 END
|
|
|
+ 3155 ELSE QbeGen.CopyOp(qd, q)
|
|
|
3156 END;
|
|
|
- 3157 t := SymTab.CharType(); .)
|
|
|
- 3158 | real (. LexString(s);
|
|
|
- 3159 QbeGen.NormReal(s, q);
|
|
|
- 3160 IF twoPhase THEN
|
|
|
- 3161 astIsLit := TRUE;
|
|
|
- 3162 astCur := AST.MakeLeaf(
|
|
|
- 3163 AST.NkRealLit, s)
|
|
|
- 3164 END;
|
|
|
- 3165 t := SymTab.RealType(); .)
|
|
|
- 3166 | string (. LexString(s);
|
|
|
- 3167 IF twoPhase THEN
|
|
|
- 3168 astIsLit := TRUE;
|
|
|
- 3169 astCur := AST.MakeLeaf(
|
|
|
- 3170 AST.NkStrLit, s)
|
|
|
- 3171 END;
|
|
|
- 3172 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3173 t := SymTab.CharType();
|
|
|
- 3174 QbeGen.IntStr(
|
|
|
- 3175 QbeGen.CharVal(s), q)
|
|
|
- 3176 ELSE t := SymTab.NewStr();
|
|
|
- 3177 QbeGen.DeclStr(s, q);
|
|
|
- 3178 (* a literal's value IS its
|
|
|
- 3179 static descriptor address *)
|
|
|
- 3180 QbeGen.NoteAddr(q, q)
|
|
|
- 3181 END; .)
|
|
|
- 3182 | ustring (. LexString(s);
|
|
|
- 3183 IF twoPhase THEN
|
|
|
- 3184 astIsLit := TRUE;
|
|
|
- 3185 astCur := AST.MakeLeaf(
|
|
|
- 3186 AST.NkStrLit, s)
|
|
|
- 3187 END;
|
|
|
- 3188 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 3189 uok);
|
|
|
- 3190 IF NOT uok THEN
|
|
|
- 3191 SemError(234);
|
|
|
- 3192 t := SymTab.InvalidType
|
|
|
- 3193 ELSIF isU THEN
|
|
|
- 3194 t := SymTab.UCharType();
|
|
|
- 3195 QbeGen.IntStr(ucp, q)
|
|
|
- 3196 ELSE
|
|
|
- 3197 t := SymTab.NewUStr();
|
|
|
- 3198 QbeGen.NoteAddr(q, q)
|
|
|
- 3199 END; .)
|
|
|
- 3200 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
- 3201 astNArgs := 0; called := FALSE;
|
|
|
- 3202 t := dt;
|
|
|
- 3203 IF sfx THEN
|
|
|
- 3204 IF dt =
|
|
|
- 3205 SymTab.InvalidType THEN
|
|
|
- 3206 QbeGen.CopyOp("0", q)
|
|
|
- 3207 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 3208 SymTab.ClRecord)
|
|
|
- 3209 OR (SymTab.ClassOf(dt) =
|
|
|
- 3210 SymTab.ClSet)
|
|
|
- 3211 OR (SymTab.ClassOf(dt) =
|
|
|
- 3212 SymTab.ClArray)
|
|
|
- 3213 OR (SymTab.ClassOf(dt) =
|
|
|
- 3214 SymTab.ClClass) THEN
|
|
|
- 3215 QbeGen.CopyOp(qd, q)
|
|
|
- 3216 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 3217 q)
|
|
|
- 3218 END
|
|
|
- 3219 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 3220 END;
|
|
|
- 3221 IF (dk = SymTab.KindVar)
|
|
|
- 3222 OR (dk = SymTab.KindParam)
|
|
|
- 3223 OR (dk =
|
|
|
- 3224 SymTab.KindField) THEN
|
|
|
- 3225 IF sfx THEN
|
|
|
- 3226 QbeGen.NoteAddr(q, qd)
|
|
|
+ 3157 IF (dk = SymTab.KindVar)
|
|
|
+ 3158 OR (dk = SymTab.KindParam)
|
|
|
+ 3159 OR (dk =
|
|
|
+ 3160 SymTab.KindField) THEN
|
|
|
+ 3161 IF sfx THEN
|
|
|
+ 3162 QbeGen.NoteAddr(q, qd)
|
|
|
+ 3163 ELSE
|
|
|
+ 3164 QbeGen.AddrOf(qn, qa);
|
|
|
+ 3165 QbeGen.NoteAddr(q, qa)
|
|
|
+ 3166 END
|
|
|
+ 3167 ELSIF sfx
|
|
|
+ 3168 AND (dt #
|
|
|
+ 3169 SymTab.InvalidType)
|
|
|
+ 3170 AND ((SymTab.ClassOf(dt) =
|
|
|
+ 3171 SymTab.ClArray)
|
|
|
+ 3172 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3173 SymTab.ClSet)
|
|
|
+ 3174 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3175 SymTab.ClRecord)) THEN
|
|
|
+ 3176 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3177 END; .)
|
|
|
+ 3178 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
+ 3179 astBrace := astCur; .) ]
|
|
|
+ 3180 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 3181 (. astCall := TRUE;
|
|
|
+ 3182 astNode := AstCallNode(astD);
|
|
|
+ 3183 astRes := astNode;
|
|
|
+ 3184 t := ct2;
|
|
|
+ 3185 QbeGen.CopyOp(q2, q);
|
|
|
+ 3186 sfx := FALSE; .)
|
|
|
+ 3187 { ResultComp<t, q, sfx, astRes> }
|
|
|
+ 3188 (. IF sfx THEN
|
|
|
+ 3189 IF t = SymTab.InvalidType THEN
|
|
|
+ 3190 QbeGen.CopyOp("0", q)
|
|
|
+ 3191 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 3192 SymTab.ClRecord)
|
|
|
+ 3193 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
+ 3194 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
+ 3195 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 3196 QbeGen.ElemLoad(q, t, q2);
|
|
|
+ 3197 QbeGen.CopyOp(q2, q)
|
|
|
+ 3198 END
|
|
|
+ 3199 END; .) ]
|
|
|
+ 3200 (. IF called THEN
|
|
|
+ 3201 astCur := astRes
|
|
|
+ 3202 ELSIF astCall THEN
|
|
|
+ 3203 astCur := astBrace
|
|
|
+ 3204 ELSE astCur := astD
|
|
|
+ 3205 END;
|
|
|
+ 3206 astIsLit := TRUE;
|
|
|
+ 3207 IF NOT called
|
|
|
+ 3208 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 3209 (* bare zero-arg function
|
|
|
+ 3210 call (parentheses may be
|
|
|
+ 3211 omitted); a proper or
|
|
|
+ 3212 parameterised proc here
|
|
|
+ 3213 is 230 *)
|
|
|
+ 3214 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 3215 AND (SymTab.ProcRes(qn) #
|
|
|
+ 3216 SymTab.InvalidType) THEN
|
|
|
+ 3217 QbeGen.Mangled(qn,
|
|
|
+ 3218 SymTab.ProcUid(qn), qm0);
|
|
|
+ 3219 QbeGen.CallBegin(qm0,
|
|
|
+ 3220 SymTab.ProcRes(qn),
|
|
|
+ 3221 SymTab.ProcDepthOf(qn),
|
|
|
+ 3222 SymTab.IsExternal(qn));
|
|
|
+ 3223 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 3224 astCur := AST.MakeNode(AST.NkCall);
|
|
|
+ 3225 AST.SetChild(astCur, 0, astD);
|
|
|
+ 3226 t := SymTab.ProcRes(qn)
|
|
|
3227 ELSE
|
|
|
- 3228 QbeGen.AddrOf(qn, qa);
|
|
|
- 3229 QbeGen.NoteAddr(q, qa)
|
|
|
- 3230 END
|
|
|
- 3231 ELSIF sfx
|
|
|
- 3232 AND (dt #
|
|
|
- 3233 SymTab.InvalidType)
|
|
|
- 3234 AND ((SymTab.ClassOf(dt) =
|
|
|
- 3235 SymTab.ClArray)
|
|
|
- 3236 OR (SymTab.ClassOf(dt) =
|
|
|
- 3237 SymTab.ClSet)
|
|
|
- 3238 OR (SymTab.ClassOf(dt) =
|
|
|
- 3239 SymTab.ClRecord)) THEN
|
|
|
- 3240 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3241 END; .)
|
|
|
- 3242 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
- 3243 astBrace := astCur; .) ]
|
|
|
- 3244 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 3245 (. astCall := TRUE;
|
|
|
- 3246 astNode := AstCallNode(astD);
|
|
|
- 3247 astRes := astNode;
|
|
|
- 3248 t := ct2;
|
|
|
- 3249 QbeGen.CopyOp(q2, q);
|
|
|
- 3250 sfx := FALSE; .)
|
|
|
- 3251 { ResultComp<t, q, sfx, astRes> }
|
|
|
- 3252 (. IF sfx THEN
|
|
|
- 3253 IF t = SymTab.InvalidType THEN
|
|
|
- 3254 QbeGen.CopyOp("0", q)
|
|
|
- 3255 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 3256 SymTab.ClRecord)
|
|
|
- 3257 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
- 3258 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
- 3259 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 3260 QbeGen.ElemLoad(q, t, q2);
|
|
|
- 3261 QbeGen.CopyOp(q2, q)
|
|
|
- 3262 END
|
|
|
- 3263 END; .) ]
|
|
|
- 3264 (. IF called THEN
|
|
|
- 3265 astCur := astRes
|
|
|
- 3266 ELSIF astCall THEN
|
|
|
- 3267 astCur := astBrace
|
|
|
- 3268 ELSE astCur := astD
|
|
|
- 3269 END;
|
|
|
- 3270 astIsLit := TRUE;
|
|
|
- 3271 IF NOT called
|
|
|
- 3272 AND (dk = SymTab.KindProc) THEN
|
|
|
- 3273 (* bare zero-arg function
|
|
|
- 3274 call (parentheses may be
|
|
|
- 3275 omitted); a proper or
|
|
|
- 3276 parameterised proc here
|
|
|
- 3277 is 230 *)
|
|
|
- 3278 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 3279 AND (SymTab.ProcRes(qn) #
|
|
|
- 3280 SymTab.InvalidType) THEN
|
|
|
- 3281 QbeGen.Mangled(qn,
|
|
|
- 3282 SymTab.ProcUid(qn), qm0);
|
|
|
- 3283 QbeGen.CallBegin(qm0,
|
|
|
- 3284 SymTab.ProcRes(qn),
|
|
|
- 3285 SymTab.ProcDepthOf(qn),
|
|
|
- 3286 SymTab.IsExternal(qn));
|
|
|
- 3287 QbeGen.CallEnd(TRUE, q);
|
|
|
- 3288 astCur := AST.MakeNode(AST.NkCall);
|
|
|
- 3289 AST.SetChild(astCur, 0, astD);
|
|
|
- 3290 t := SymTab.ProcRes(qn)
|
|
|
- 3291 ELSE
|
|
|
- 3292 (* procedure used as a
|
|
|
- 3293 value (assign to a
|
|
|
- 3294 procedure variable):
|
|
|
- 3295 its code address *)
|
|
|
- 3296 t := SymTab.ProcTypeOf(qn);
|
|
|
- 3297 QbeGen.Mangled(qn,
|
|
|
- 3298 SymTab.ProcUid(qn), qm0);
|
|
|
- 3299 QbeGen.ProcAddr(qm0, q)
|
|
|
- 3300 END
|
|
|
- 3301 END; .)
|
|
|
- 3302 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 3303 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 3304 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
- 3305 isU := FALSE; .)
|
|
|
- 3306 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3307 isStr := TRUE;
|
|
|
- 3308 isU := FALSE;
|
|
|
- 3309 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3310 dt := SymTab.CharType();
|
|
|
- 3311 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 3312 qd)
|
|
|
- 3313 ELSE
|
|
|
- 3314 dt := SymTab.NewStr();
|
|
|
- 3315 QbeGen.DeclStr(s, qd);
|
|
|
- 3316 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3317 END;
|
|
|
- 3318 dk := -1;
|
|
|
- 3319 qn[0] := CHR(0); .)
|
|
|
- 3320 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3321 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
- 3322 uok);
|
|
|
- 3323 isStr := FALSE;
|
|
|
- 3324 IF NOT uok THEN
|
|
|
- 3325 SemError(234);
|
|
|
- 3326 dt := SymTab.InvalidType
|
|
|
- 3327 ELSIF isU THEN
|
|
|
- 3328 (* one codepoint: a UCHAR;
|
|
|
- 3329 LEN is 1, HIGH is 0 *)
|
|
|
- 3330 dt := SymTab.UCharType();
|
|
|
- 3331 QbeGen.IntStr(ucp, qd)
|
|
|
- 3332 ELSE
|
|
|
- 3333 dt := SymTab.NewUStr();
|
|
|
- 3334 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3335 END;
|
|
|
- 3336 dk := -1;
|
|
|
- 3337 qn[0] := CHR(0); .) )
|
|
|
- 3338 ")"
|
|
|
- 3339 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3340 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
- 3341 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
- 3342 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3343 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
- 3344 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3345 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3346 IF (dt # SymTab.InvalidType)
|
|
|
- 3347 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
- 3348 (* UString: the count is
|
|
|
- 3349 the descriptor header *)
|
|
|
- 3350 IF isHigh THEN
|
|
|
- 3351 QbeGen.UStrLen(qd, qr);
|
|
|
- 3352 QbeGen.DecQ(qr)
|
|
|
- 3353 ELSE
|
|
|
- 3354 QbeGen.UStrLen(qd, qr)
|
|
|
- 3355 END;
|
|
|
- 3356 t := SymTab.IntType();
|
|
|
- 3357 QbeGen.CopyOp(qr, q)
|
|
|
- 3358 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 3359 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
- 3360 (* single UCHAR codepoint *)
|
|
|
- 3361 IF isHigh THEN
|
|
|
- 3362 QbeGen.CopyOp("0", qr)
|
|
|
- 3363 ELSE
|
|
|
- 3364 QbeGen.CopyOp("1", qr)
|
|
|
- 3365 END;
|
|
|
- 3366 t := SymTab.IntType();
|
|
|
- 3367 QbeGen.CopyOp(qr, q)
|
|
|
- 3368 ELSIF isStr THEN
|
|
|
- 3369 (* fold: content length at
|
|
|
- 3370 compile time *)
|
|
|
- 3371 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3372 c1 := 1
|
|
|
- 3373 ELSE
|
|
|
- 3374 c1 :=
|
|
|
- 3375 SymTab.StrLen(s) - 2
|
|
|
- 3376 END;
|
|
|
- 3377 IF isHigh THEN
|
|
|
- 3378 DEC(c1)
|
|
|
- 3379 END;
|
|
|
- 3380 QbeGen.IntStr(c1, qr);
|
|
|
- 3381 t := SymTab.IntType();
|
|
|
- 3382 QbeGen.CopyOp(qr, q)
|
|
|
- 3383 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 3228 (* procedure used as a
|
|
|
+ 3229 value (assign to a
|
|
|
+ 3230 procedure variable):
|
|
|
+ 3231 its code address *)
|
|
|
+ 3232 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 3233 QbeGen.Mangled(qn,
|
|
|
+ 3234 SymTab.ProcUid(qn), qm0);
|
|
|
+ 3235 QbeGen.ProcAddr(qm0, q)
|
|
|
+ 3236 END
|
|
|
+ 3237 END; .)
|
|
|
+ 3238 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 3239 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 3240 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
+ 3241 isU := FALSE; .)
|
|
|
+ 3242 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3243 isStr := TRUE;
|
|
|
+ 3244 isU := FALSE;
|
|
|
+ 3245 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3246 dt := SymTab.CharType();
|
|
|
+ 3247 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 3248 qd)
|
|
|
+ 3249 ELSE
|
|
|
+ 3250 dt := SymTab.NewStr();
|
|
|
+ 3251 QbeGen.DeclStr(s, qd);
|
|
|
+ 3252 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3253 END;
|
|
|
+ 3254 dk := -1;
|
|
|
+ 3255 qn[0] := CHR(0); .)
|
|
|
+ 3256 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3257 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
+ 3258 uok);
|
|
|
+ 3259 isStr := FALSE;
|
|
|
+ 3260 IF NOT uok THEN
|
|
|
+ 3261 SemError(234);
|
|
|
+ 3262 dt := SymTab.InvalidType
|
|
|
+ 3263 ELSIF isU THEN
|
|
|
+ 3264 (* one codepoint: a UCHAR;
|
|
|
+ 3265 LEN is 1, HIGH is 0 *)
|
|
|
+ 3266 dt := SymTab.UCharType();
|
|
|
+ 3267 QbeGen.IntStr(ucp, qd)
|
|
|
+ 3268 ELSE
|
|
|
+ 3269 dt := SymTab.NewUStr();
|
|
|
+ 3270 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3271 END;
|
|
|
+ 3272 dk := -1;
|
|
|
+ 3273 qn[0] := CHR(0); .) )
|
|
|
+ 3274 ")"
|
|
|
+ 3275 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3276 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
+ 3277 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
+ 3278 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3279 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
+ 3280 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3281 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3282 IF (dt # SymTab.InvalidType)
|
|
|
+ 3283 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
+ 3284 (* UString: the count is
|
|
|
+ 3285 the descriptor header *)
|
|
|
+ 3286 IF isHigh THEN
|
|
|
+ 3287 QbeGen.UStrLen(qd, qr);
|
|
|
+ 3288 QbeGen.DecQ(qr)
|
|
|
+ 3289 ELSE
|
|
|
+ 3290 QbeGen.UStrLen(qd, qr)
|
|
|
+ 3291 END;
|
|
|
+ 3292 t := SymTab.IntType();
|
|
|
+ 3293 QbeGen.CopyOp(qr, q)
|
|
|
+ 3294 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 3295 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
+ 3296 (* single UCHAR codepoint *)
|
|
|
+ 3297 IF isHigh THEN
|
|
|
+ 3298 QbeGen.CopyOp("0", qr)
|
|
|
+ 3299 ELSE
|
|
|
+ 3300 QbeGen.CopyOp("1", qr)
|
|
|
+ 3301 END;
|
|
|
+ 3302 t := SymTab.IntType();
|
|
|
+ 3303 QbeGen.CopyOp(qr, q)
|
|
|
+ 3304 ELSIF isStr THEN
|
|
|
+ 3305 (* fold: content length at
|
|
|
+ 3306 compile time *)
|
|
|
+ 3307 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3308 c1 := 1
|
|
|
+ 3309 ELSE
|
|
|
+ 3310 c1 :=
|
|
|
+ 3311 SymTab.StrLen(s) - 2
|
|
|
+ 3312 END;
|
|
|
+ 3313 IF isHigh THEN
|
|
|
+ 3314 DEC(c1)
|
|
|
+ 3315 END;
|
|
|
+ 3316 QbeGen.IntStr(c1, qr);
|
|
|
+ 3317 t := SymTab.IntType();
|
|
|
+ 3318 QbeGen.CopyOp(qr, q)
|
|
|
+ 3319 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 3320 t := SymTab.InvalidType;
|
|
|
+ 3321 QbeGen.CopyOp("0", q)
|
|
|
+ 3322 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 3323 SymTab.ClArray THEN
|
|
|
+ 3324 SemError(217);
|
|
|
+ 3325 t := SymTab.InvalidType;
|
|
|
+ 3326 QbeGen.CopyOp("0", q)
|
|
|
+ 3327 ELSE
|
|
|
+ 3328 IF isHigh THEN
|
|
|
+ 3329 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3330 QbeGen.OpenHi(qd, qr)
|
|
|
+ 3331 ELSE
|
|
|
+ 3332 QbeGen.IntStr(
|
|
|
+ 3333 SymTab.ArrayHi(dt), qr)
|
|
|
+ 3334 END
|
|
|
+ 3335 ELSE
|
|
|
+ 3336 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3337 QbeGen.LoadCount(qd, qr)
|
|
|
+ 3338 ELSE
|
|
|
+ 3339 QbeGen.IntStr(VAL(
|
|
|
+ 3340 INTEGER,
|
|
|
+ 3341 SymTab.ArrayLen(dt)),
|
|
|
+ 3342 qr)
|
|
|
+ 3343 END
|
|
|
+ 3344 END;
|
|
|
+ 3345 t := SymTab.IntType();
|
|
|
+ 3346 QbeGen.CopyOp(qr, q)
|
|
|
+ 3347 END; .)
|
|
|
+ 3348 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3349 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3350 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
+ 3351 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3352 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3353 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3354 t := SymTab.InvalidType;
|
|
|
+ 3355 QbeGen.CopyOp("0", q)
|
|
|
+ 3356 ELSE
|
|
|
+ 3357 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 3358 SymTab.ObjectSize(dt)), q);
|
|
|
+ 3359 t := SymTab.IntType()
|
|
|
+ 3360 END; .)
|
|
|
+ 3361 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
+ 3362 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
+ 3363 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
+ 3364 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3365 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3366 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
+ 3367 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3368 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
+ 3369 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3370 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3371 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3372 (* set shift/rotate: isMax
|
|
|
+ 3373 doubles as "rotate" *)
|
|
|
+ 3374 IF (et # SymTab.InvalidType)
|
|
|
+ 3375 AND (SymTab.ClassOf(et) =
|
|
|
+ 3376 SymTab.ClSet) THEN
|
|
|
+ 3377 QbeGen.SetShift(q, q2,
|
|
|
+ 3378 SymTab.SetWords(et),
|
|
|
+ 3379 SymTab.SetCount(et), isMax,
|
|
|
+ 3380 qt);
|
|
|
+ 3381 t := et;
|
|
|
+ 3382 QbeGen.CopyOp(qt, q)
|
|
|
+ 3383 ELSE SemError(230);
|
|
|
3384 t := SymTab.InvalidType;
|
|
|
3385 QbeGen.CopyOp("0", q)
|
|
|
- 3386 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 3387 SymTab.ClArray THEN
|
|
|
- 3388 SemError(217);
|
|
|
- 3389 t := SymTab.InvalidType;
|
|
|
- 3390 QbeGen.CopyOp("0", q)
|
|
|
- 3391 ELSE
|
|
|
- 3392 IF isHigh THEN
|
|
|
- 3393 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3394 QbeGen.OpenHi(qd, qr)
|
|
|
- 3395 ELSE
|
|
|
- 3396 QbeGen.IntStr(
|
|
|
- 3397 SymTab.ArrayHi(dt), qr)
|
|
|
- 3398 END
|
|
|
- 3399 ELSE
|
|
|
- 3400 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3401 QbeGen.LoadCount(qd, qr)
|
|
|
- 3402 ELSE
|
|
|
- 3403 QbeGen.IntStr(VAL(
|
|
|
- 3404 INTEGER,
|
|
|
- 3405 SymTab.ArrayLen(dt)),
|
|
|
- 3406 qr)
|
|
|
- 3407 END
|
|
|
- 3408 END;
|
|
|
- 3409 t := SymTab.IntType();
|
|
|
- 3410 QbeGen.CopyOp(qr, q)
|
|
|
- 3411 END; .)
|
|
|
- 3412 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3413 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3414 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
- 3415 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3416 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3417 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3418 t := SymTab.InvalidType;
|
|
|
- 3419 QbeGen.CopyOp("0", q)
|
|
|
- 3420 ELSE
|
|
|
- 3421 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 3422 SymTab.ObjectSize(dt)), q);
|
|
|
- 3423 t := SymTab.IntType()
|
|
|
- 3424 END; .)
|
|
|
- 3425 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
- 3426 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
- 3427 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
- 3428 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3429 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3430 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
- 3431 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3432 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
- 3433 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3434 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3435 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3436 (* set shift/rotate: isMax
|
|
|
- 3437 doubles as "rotate" *)
|
|
|
- 3438 IF (et # SymTab.InvalidType)
|
|
|
- 3439 AND (SymTab.ClassOf(et) =
|
|
|
- 3440 SymTab.ClSet) THEN
|
|
|
- 3441 QbeGen.SetShift(q, q2,
|
|
|
- 3442 SymTab.SetWords(et),
|
|
|
- 3443 SymTab.SetCount(et), isMax,
|
|
|
- 3444 qt);
|
|
|
- 3445 t := et;
|
|
|
- 3446 QbeGen.CopyOp(qt, q)
|
|
|
- 3447 ELSE SemError(230);
|
|
|
- 3448 t := SymTab.InvalidType;
|
|
|
- 3449 QbeGen.CopyOp("0", q)
|
|
|
- 3450 END; .)
|
|
|
- 3451 | ( "MIN" (. isMax := FALSE; .)
|
|
|
- 3452 | "MAX" (. isMax := TRUE; .) )
|
|
|
- 3453 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3454 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3455 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3456 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
- 3457 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3458 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
- 3459 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3460 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3461 IF (dt # SymTab.InvalidType)
|
|
|
- 3462 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
- 3463 (* REAL/LONGREAL: the
|
|
|
- 3464 implementation bounds *)
|
|
|
- 3465 IF isMax THEN
|
|
|
- 3466 QbeGen.NormReal(
|
|
|
- 3467 "3.402823e38", q)
|
|
|
- 3468 ELSE QbeGen.NormReal(
|
|
|
- 3469 "-3.402823e38", q)
|
|
|
- 3470 END;
|
|
|
- 3471 t := SymTab.RealType()
|
|
|
- 3472 ELSIF (dt #
|
|
|
- 3473 SymTab.InvalidType)
|
|
|
- 3474 AND (SymTab.ClassOf(dt) =
|
|
|
- 3475 SymTab.ClLong) THEN
|
|
|
- 3476 IF isMax THEN
|
|
|
- 3477 QbeGen.CopyOp(
|
|
|
- 3478 "9223372036854775807", q)
|
|
|
- 3479 ELSE QbeGen.CopyOp(
|
|
|
- 3480 "-9223372036854775808", q)
|
|
|
- 3481 END;
|
|
|
- 3482 t := SymTab.LongType()
|
|
|
- 3483 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
- 3484 hi) THEN
|
|
|
- 3485 IF isMax THEN
|
|
|
- 3486 QbeGen.IntStr(hi, q)
|
|
|
- 3487 ELSE QbeGen.IntStr(lo, q)
|
|
|
- 3488 END;
|
|
|
- 3489 t := SymTab.IntType()
|
|
|
- 3490 ELSE SemError(230);
|
|
|
- 3491 t := SymTab.InvalidType;
|
|
|
- 3492 QbeGen.CopyOp("0", q)
|
|
|
- 3493 END; .)
|
|
|
- 3494 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3495 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3496 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
- 3497 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3498 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3499 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3500 t := SymTab.InvalidType;
|
|
|
- 3501 QbeGen.CopyOp("0", q)
|
|
|
- 3502 ELSE
|
|
|
- 3503 IF sfx THEN
|
|
|
- 3504 QbeGen.CopyOp(qd, q)
|
|
|
- 3505 ELSIF (dk = SymTab.KindVar)
|
|
|
- 3506 OR (dk = SymTab.KindParam) THEN
|
|
|
- 3507 QbeGen.AddrOf(qn, q)
|
|
|
- 3508 ELSE SemError(230);
|
|
|
- 3509 QbeGen.CopyOp("0", q)
|
|
|
- 3510 END;
|
|
|
- 3511 t := SymTab.AddrType()
|
|
|
- 3512 END; .)
|
|
|
- 3513 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 3514 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3515 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
- 3516 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3517 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3518 (. IF (et # SymTab.InvalidType)
|
|
|
- 3519 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3520 SemError(211) END;
|
|
|
- 3521 t := SymTab.CharType(); .)
|
|
|
- 3522 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 3523 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3524 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
- 3525 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3526 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3527 (. IF et # SymTab.InvalidType THEN
|
|
|
- 3528 IF (SymTab.ClassOf(et) #
|
|
|
- 3529 SymTab.ClChar)
|
|
|
- 3530 AND (SymTab.ClassOf(et) #
|
|
|
- 3531 SymTab.ClBool)
|
|
|
- 3532 AND (SymTab.ClassOf(et) #
|
|
|
- 3533 SymTab.ClEnum)
|
|
|
- 3534 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3535 SemError(211) END
|
|
|
- 3536 END;
|
|
|
- 3537 t := SymTab.IntType(); .)
|
|
|
- 3538 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 3539 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3540 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
- 3541 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3542 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3543 (. QbeGen.CapQ(q, qa);
|
|
|
- 3544 QbeGen.CopyOp(qa, q);
|
|
|
- 3545 t := SymTab.CharType(); .)
|
|
|
- 3546 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 3547 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3548 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
- 3549 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3550 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3551 (. (* UCHR: the UCHAR constructor.
|
|
|
- 3552 CHAR -> UCHAR (identity);
|
|
|
- 3553 INTEGER familly -> UCHAR
|
|
|
- 3554 (codepoint value). *)
|
|
|
- 3555 IF (et # SymTab.InvalidType)
|
|
|
- 3556 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 3557 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3558 SemError(211) END;
|
|
|
- 3559 t := SymTab.UCharType(); .)
|
|
|
- 3560 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 3561 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3562 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
- 3563 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3564 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3565 (. IF (et # SymTab.InvalidType)
|
|
|
- 3566 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3567 SemError(211) END;
|
|
|
- 3568 QbeGen.WidenLong(q, qa);
|
|
|
- 3569 QbeGen.CheckRange(qa, "0", "255");
|
|
|
- 3570 t := SymTab.CharType(); .)
|
|
|
- 3571 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 3572 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3573 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
- 3574 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3575 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3576 (. (* UORD(u): the codepoint as a
|
|
|
- 3577 32-bit ordinal (INTEGER),
|
|
|
- 3578 cf. ORD for CHAR. *)
|
|
|
- 3579 IF (et # SymTab.InvalidType)
|
|
|
- 3580 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3581 SemError(211) END;
|
|
|
- 3582 t := SymTab.IntType(); .)
|
|
|
- 3583 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 3584 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3585 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
- 3586 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3587 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3588 (. IF (et # SymTab.InvalidType)
|
|
|
- 3589 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 3590 AND (SymTab.ClassOf(et) #
|
|
|
- 3591 SymTab.ClReal) THEN
|
|
|
- 3592 SemError(211)
|
|
|
- 3593 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 3594 SymTab.ClassOf(et) =
|
|
|
- 3595 SymTab.ClReal);
|
|
|
- 3596 QbeGen.CopyOp(qa, q)
|
|
|
- 3597 END;
|
|
|
- 3598 t := et; .)
|
|
|
- 3599 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
- 3600 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3601 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3602 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3603 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3604 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3605 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 3606 SemError(201);
|
|
|
- 3607 t := SymTab.InvalidType
|
|
|
- 3608 ELSE vt := SymTab.SymType(vn);
|
|
|
- 3609 IF vt = SymTab.InvalidType THEN
|
|
|
- 3610 t := SymTab.InvalidType
|
|
|
- 3611 ELSIF et =
|
|
|
- 3612 SymTab.InvalidType THEN
|
|
|
- 3613 t := vt
|
|
|
- 3614 ELSE
|
|
|
- 3615 c1 := SymTab.ClassOf(et);
|
|
|
- 3616 c2 := SymTab.ClassOf(vt);
|
|
|
- 3617 IF (c1 = SymTab.ClInt)
|
|
|
- 3618 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3619 QbeGen.WidenLong(q, qa);
|
|
|
- 3620 QbeGen.CopyOp(qa, q);
|
|
|
- 3621 t := vt
|
|
|
- 3622 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3623 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3624 QbeGen.NarrowLong(q, qa);
|
|
|
- 3625 QbeGen.CopyOp(qa, q);
|
|
|
- 3626 t := vt
|
|
|
- 3627 ELSIF (c1 = SymTab.ClInt)
|
|
|
- 3628 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3629 QbeGen.ConvIR(q, qa);
|
|
|
- 3630 QbeGen.CopyOp(qa, q);
|
|
|
- 3631 t := vt
|
|
|
- 3632 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3633 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3634 QbeGen.ConvLR(q, qa);
|
|
|
- 3635 QbeGen.CopyOp(qa, q);
|
|
|
- 3636 t := vt
|
|
|
- 3637 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3638 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3639 QbeGen.ConvRI(q, qa);
|
|
|
- 3640 QbeGen.CopyOp(qa, q);
|
|
|
- 3641 t := vt
|
|
|
- 3642 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3643 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3644 QbeGen.ConvRL(q, qa);
|
|
|
- 3645 QbeGen.CopyOp(qa, q);
|
|
|
- 3646 t := vt
|
|
|
- 3647 ELSIF ((c1 = SymTab.ClInt)
|
|
|
- 3648 OR (c1 =
|
|
|
- 3649 SymTab.ClChar)
|
|
|
- 3650 OR (c1 =
|
|
|
- 3651 SymTab.ClBool)
|
|
|
- 3652 OR (c1 =
|
|
|
- 3653 SymTab.ClEnum))
|
|
|
- 3654 AND ((c2 = SymTab.ClInt)
|
|
|
- 3655 OR (c2 =
|
|
|
- 3656 SymTab.ClChar)
|
|
|
- 3657 OR (c2 =
|
|
|
- 3658 SymTab.ClBool)
|
|
|
- 3659 OR (c2 =
|
|
|
- 3660 SymTab.ClEnum)) THEN
|
|
|
- 3661 t := vt
|
|
|
- 3662 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 3663 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 3664 t := vt
|
|
|
- 3665 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3666 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3667 t := vt
|
|
|
- 3668 ELSE SemError(230);
|
|
|
- 3669 t := SymTab.InvalidType
|
|
|
- 3670 END
|
|
|
- 3671 END
|
|
|
- 3672 END; .)
|
|
|
- 3673 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
- 3674 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
- 3675 QbeGen.CopyOp(sq, q); .)
|
|
|
- 3676 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
- 3677 IF SymTab.BoolCheck(t2) THEN
|
|
|
- 3678 t := SymTab.BoolType()
|
|
|
- 3679 ELSE SemError(212);
|
|
|
- 3680 t := SymTab.InvalidType END;
|
|
|
- 3681 IF t # SymTab.InvalidType THEN
|
|
|
- 3682 QbeGen.NotQ(q2, q)
|
|
|
- 3683 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3386 END; .)
|
|
|
+ 3387 | ( "MIN" (. isMax := FALSE; .)
|
|
|
+ 3388 | "MAX" (. isMax := TRUE; .) )
|
|
|
+ 3389 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3390 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3391 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3392 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
+ 3393 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3394 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
+ 3395 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3396 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3397 IF (dt # SymTab.InvalidType)
|
|
|
+ 3398 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
+ 3399 (* REAL/LONGREAL: the
|
|
|
+ 3400 implementation bounds *)
|
|
|
+ 3401 IF isMax THEN
|
|
|
+ 3402 QbeGen.NormReal(
|
|
|
+ 3403 "3.402823e38", q)
|
|
|
+ 3404 ELSE QbeGen.NormReal(
|
|
|
+ 3405 "-3.402823e38", q)
|
|
|
+ 3406 END;
|
|
|
+ 3407 t := SymTab.RealType()
|
|
|
+ 3408 ELSIF (dt #
|
|
|
+ 3409 SymTab.InvalidType)
|
|
|
+ 3410 AND (SymTab.ClassOf(dt) =
|
|
|
+ 3411 SymTab.ClLong) THEN
|
|
|
+ 3412 IF isMax THEN
|
|
|
+ 3413 QbeGen.CopyOp(
|
|
|
+ 3414 "9223372036854775807", q)
|
|
|
+ 3415 ELSE QbeGen.CopyOp(
|
|
|
+ 3416 "-9223372036854775808", q)
|
|
|
+ 3417 END;
|
|
|
+ 3418 t := SymTab.LongType()
|
|
|
+ 3419 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
+ 3420 hi) THEN
|
|
|
+ 3421 IF isMax THEN
|
|
|
+ 3422 QbeGen.IntStr(hi, q)
|
|
|
+ 3423 ELSE QbeGen.IntStr(lo, q)
|
|
|
+ 3424 END;
|
|
|
+ 3425 t := SymTab.IntType()
|
|
|
+ 3426 ELSE SemError(230);
|
|
|
+ 3427 t := SymTab.InvalidType;
|
|
|
+ 3428 QbeGen.CopyOp("0", q)
|
|
|
+ 3429 END; .)
|
|
|
+ 3430 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3431 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3432 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
+ 3433 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3434 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3435 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3436 t := SymTab.InvalidType;
|
|
|
+ 3437 QbeGen.CopyOp("0", q)
|
|
|
+ 3438 ELSE
|
|
|
+ 3439 IF sfx THEN
|
|
|
+ 3440 QbeGen.CopyOp(qd, q)
|
|
|
+ 3441 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 3442 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 3443 QbeGen.AddrOf(qn, q)
|
|
|
+ 3444 ELSE SemError(230);
|
|
|
+ 3445 QbeGen.CopyOp("0", q)
|
|
|
+ 3446 END;
|
|
|
+ 3447 t := SymTab.AddrType()
|
|
|
+ 3448 END; .)
|
|
|
+ 3449 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 3450 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3451 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
+ 3452 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3453 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3454 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3455 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3456 SemError(211) END;
|
|
|
+ 3457 t := SymTab.CharType(); .)
|
|
|
+ 3458 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 3459 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3460 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
+ 3461 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3462 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3463 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 3464 IF (SymTab.ClassOf(et) #
|
|
|
+ 3465 SymTab.ClChar)
|
|
|
+ 3466 AND (SymTab.ClassOf(et) #
|
|
|
+ 3467 SymTab.ClBool)
|
|
|
+ 3468 AND (SymTab.ClassOf(et) #
|
|
|
+ 3469 SymTab.ClEnum)
|
|
|
+ 3470 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3471 SemError(211) END
|
|
|
+ 3472 END;
|
|
|
+ 3473 t := SymTab.IntType(); .)
|
|
|
+ 3474 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 3475 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3476 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
+ 3477 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3478 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3479 (. QbeGen.CapQ(q, qa);
|
|
|
+ 3480 QbeGen.CopyOp(qa, q);
|
|
|
+ 3481 t := SymTab.CharType(); .)
|
|
|
+ 3482 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 3483 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3484 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
+ 3485 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3486 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3487 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 3488 CHAR -> UCHAR (identity);
|
|
|
+ 3489 INTEGER familly -> UCHAR
|
|
|
+ 3490 (codepoint value). *)
|
|
|
+ 3491 IF (et # SymTab.InvalidType)
|
|
|
+ 3492 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 3493 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3494 SemError(211) END;
|
|
|
+ 3495 t := SymTab.UCharType(); .)
|
|
|
+ 3496 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 3497 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3498 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
+ 3499 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3500 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3501 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3502 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3503 SemError(211) END;
|
|
|
+ 3504 QbeGen.WidenLong(q, qa);
|
|
|
+ 3505 QbeGen.CheckRange(qa, "0", "255");
|
|
|
+ 3506 t := SymTab.CharType(); .)
|
|
|
+ 3507 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 3508 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3509 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
+ 3510 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3511 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3512 (. (* UORD(u): the codepoint as a
|
|
|
+ 3513 32-bit ordinal (INTEGER),
|
|
|
+ 3514 cf. ORD for CHAR. *)
|
|
|
+ 3515 IF (et # SymTab.InvalidType)
|
|
|
+ 3516 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3517 SemError(211) END;
|
|
|
+ 3518 t := SymTab.IntType(); .)
|
|
|
+ 3519 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 3520 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3521 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
+ 3522 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3523 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3524 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3525 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 3526 AND (SymTab.ClassOf(et) #
|
|
|
+ 3527 SymTab.ClReal) THEN
|
|
|
+ 3528 SemError(211)
|
|
|
+ 3529 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 3530 SymTab.ClassOf(et) =
|
|
|
+ 3531 SymTab.ClReal);
|
|
|
+ 3532 QbeGen.CopyOp(qa, q)
|
|
|
+ 3533 END;
|
|
|
+ 3534 t := et; .)
|
|
|
+ 3535 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
+ 3536 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3537 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3538 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3539 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3540 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3541 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 3542 SemError(201);
|
|
|
+ 3543 t := SymTab.InvalidType
|
|
|
+ 3544 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 3545 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3546 t := SymTab.InvalidType
|
|
|
+ 3547 ELSIF et =
|
|
|
+ 3548 SymTab.InvalidType THEN
|
|
|
+ 3549 t := vt
|
|
|
+ 3550 ELSE
|
|
|
+ 3551 c1 := SymTab.ClassOf(et);
|
|
|
+ 3552 c2 := SymTab.ClassOf(vt);
|
|
|
+ 3553 IF (c1 = SymTab.ClInt)
|
|
|
+ 3554 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3555 QbeGen.WidenLong(q, qa);
|
|
|
+ 3556 QbeGen.CopyOp(qa, q);
|
|
|
+ 3557 t := vt
|
|
|
+ 3558 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3559 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3560 QbeGen.NarrowLong(q, qa);
|
|
|
+ 3561 QbeGen.CopyOp(qa, q);
|
|
|
+ 3562 t := vt
|
|
|
+ 3563 ELSIF (c1 = SymTab.ClInt)
|
|
|
+ 3564 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3565 QbeGen.ConvIR(q, qa);
|
|
|
+ 3566 QbeGen.CopyOp(qa, q);
|
|
|
+ 3567 t := vt
|
|
|
+ 3568 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3569 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3570 QbeGen.ConvLR(q, qa);
|
|
|
+ 3571 QbeGen.CopyOp(qa, q);
|
|
|
+ 3572 t := vt
|
|
|
+ 3573 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3574 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3575 QbeGen.ConvRI(q, qa);
|
|
|
+ 3576 QbeGen.CopyOp(qa, q);
|
|
|
+ 3577 t := vt
|
|
|
+ 3578 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3579 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3580 QbeGen.ConvRL(q, qa);
|
|
|
+ 3581 QbeGen.CopyOp(qa, q);
|
|
|
+ 3582 t := vt
|
|
|
+ 3583 ELSIF ((c1 = SymTab.ClInt)
|
|
|
+ 3584 OR (c1 =
|
|
|
+ 3585 SymTab.ClChar)
|
|
|
+ 3586 OR (c1 =
|
|
|
+ 3587 SymTab.ClBool)
|
|
|
+ 3588 OR (c1 =
|
|
|
+ 3589 SymTab.ClEnum))
|
|
|
+ 3590 AND ((c2 = SymTab.ClInt)
|
|
|
+ 3591 OR (c2 =
|
|
|
+ 3592 SymTab.ClChar)
|
|
|
+ 3593 OR (c2 =
|
|
|
+ 3594 SymTab.ClBool)
|
|
|
+ 3595 OR (c2 =
|
|
|
+ 3596 SymTab.ClEnum)) THEN
|
|
|
+ 3597 t := vt
|
|
|
+ 3598 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 3599 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 3600 t := vt
|
|
|
+ 3601 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3602 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3603 t := vt
|
|
|
+ 3604 ELSE SemError(230);
|
|
|
+ 3605 t := SymTab.InvalidType
|
|
|
+ 3606 END
|
|
|
+ 3607 END
|
|
|
+ 3608 END; .)
|
|
|
+ 3609 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
+ 3610 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
+ 3611 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 3612 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
+ 3613 IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 3614 t := SymTab.BoolType()
|
|
|
+ 3615 ELSE SemError(212);
|
|
|
+ 3616 t := SymTab.InvalidType END;
|
|
|
+ 3617 IF t # SymTab.InvalidType THEN
|
|
|
+ 3618 QbeGen.NotQ(q2, q)
|
|
|
+ 3619 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3620 END;
|
|
|
+ 3621 astIsLit := TRUE;
|
|
|
+ 3622 astCur := AST.MakeUn(
|
|
|
+ 3623 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
+ 3624 )
|
|
|
+ 3625 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
+ 3626 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 3627 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 3628 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 3629 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3630 (. VAR astNode: AST.Node; .)
|
|
|
+ 3631 = "{" (. t := SymTab.NewSet(
|
|
|
+ 3632 SymTab.NewSubR(0, 255));
|
|
|
+ 3633 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
+ 3634 QbeGen.NewSetTemp(8, q);
|
|
|
+ 3635 QbeGen.SetZero(q, 8); .)
|
|
|
+ 3636 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
+ 3637 "}" (. astCur := astNode; .) .
|
|
|
+ 3638 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
+ 3639 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
+ 3640 declared type sets the width (set) or element type (array). *)
|
|
|
+ 3641 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3642 (. VAR nw: CARDINAL;
|
|
|
+ 3643 astNode, astTail: AST.Node;
|
|
|
+ 3644 savedCls: INTEGER; .)
|
|
|
+ 3645 = "{" (. savedCls := braceCls;
|
|
|
+ 3646 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
+ 3647 AST.SetTy(astNode, vt);
|
|
|
+ 3648 astTail := astNode;
|
|
|
+ 3649 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3650 braceCls := -1
|
|
|
+ 3651 ELSE braceCls :=
|
|
|
+ 3652 SymTab.ClassOf(vt)
|
|
|
+ 3653 END;
|
|
|
+ 3654 IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3655 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3656 nw := 8
|
|
|
+ 3657 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 3658 IF nw = 0 THEN nw := 8 END
|
|
|
+ 3659 END;
|
|
|
+ 3660 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 3661 QbeGen.SetZero(q, nw)
|
|
|
+ 3662 ELSIF (braceCls =
|
|
|
+ 3663 SymTab.ClArray)
|
|
|
+ 3664 OR (braceCls =
|
|
|
+ 3665 SymTab.ClRecord)
|
|
|
+ 3666 OR (braceCls =
|
|
|
+ 3667 SymTab.ClClass) THEN
|
|
|
+ 3668 QbeGen.CtorBegin(vt)
|
|
|
+ 3669 ELSE
|
|
|
+ 3670 IF vt # SymTab.InvalidType THEN
|
|
|
+ 3671 SemError(230) END;
|
|
|
+ 3672 braceCls := -1
|
|
|
+ 3673 END; .)
|
|
|
+ 3674 [ BraceElem<vt, q, astNode, astTail>
|
|
|
+ 3675 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
+ 3676 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
+ 3677 OR (braceCls =
|
|
|
+ 3678 SymTab.ClRecord)
|
|
|
+ 3679 OR (braceCls =
|
|
|
+ 3680 SymTab.ClClass) THEN
|
|
|
+ 3681 QbeGen.CtorEnd(q)
|
|
|
+ 3682 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
+ 3683 QbeGen.CopyOp("0", q)
|
|
|
3684 END;
|
|
|
- 3685 astIsLit := TRUE;
|
|
|
- 3686 astCur := AST.MakeUn(
|
|
|
- 3687 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
- 3688 )
|
|
|
- 3689 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
- 3690 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 3691 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 3692 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 3693 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3694 (. VAR astNode: AST.Node; .)
|
|
|
- 3695 = "{" (. t := SymTab.NewSet(
|
|
|
- 3696 SymTab.NewSubR(0, 255));
|
|
|
- 3697 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
- 3698 QbeGen.NewSetTemp(8, q);
|
|
|
- 3699 QbeGen.SetZero(q, 8); .)
|
|
|
- 3700 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
- 3701 "}" (. astCur := astNode; .) .
|
|
|
- 3702 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
- 3703 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
- 3704 declared type sets the width (set) or element type (array). *)
|
|
|
- 3705 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3706 (. VAR nw: CARDINAL;
|
|
|
- 3707 astNode, astTail: AST.Node;
|
|
|
- 3708 savedCls: INTEGER; .)
|
|
|
- 3709 = "{" (. savedCls := braceCls;
|
|
|
- 3710 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
- 3711 AST.SetTy(astNode, vt);
|
|
|
- 3712 astTail := astNode;
|
|
|
- 3713 IF vt = SymTab.InvalidType THEN
|
|
|
- 3714 braceCls := -1
|
|
|
- 3715 ELSE braceCls :=
|
|
|
- 3716 SymTab.ClassOf(vt)
|
|
|
- 3717 END;
|
|
|
- 3718 IF braceCls = SymTab.ClSet THEN
|
|
|
- 3719 IF vt = SymTab.InvalidType THEN
|
|
|
- 3720 nw := 8
|
|
|
- 3721 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 3722 IF nw = 0 THEN nw := 8 END
|
|
|
- 3723 END;
|
|
|
- 3724 QbeGen.NewSetTemp(nw, q);
|
|
|
- 3725 QbeGen.SetZero(q, nw)
|
|
|
- 3726 ELSIF (braceCls =
|
|
|
- 3727 SymTab.ClArray)
|
|
|
- 3728 OR (braceCls =
|
|
|
- 3729 SymTab.ClRecord)
|
|
|
- 3730 OR (braceCls =
|
|
|
- 3731 SymTab.ClClass) THEN
|
|
|
- 3732 QbeGen.CtorBegin(vt)
|
|
|
- 3733 ELSE
|
|
|
- 3734 IF vt # SymTab.InvalidType THEN
|
|
|
- 3735 SemError(230) END;
|
|
|
- 3736 braceCls := -1
|
|
|
- 3737 END; .)
|
|
|
- 3738 [ BraceElem<vt, q, astNode, astTail>
|
|
|
- 3739 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
- 3740 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
- 3741 OR (braceCls =
|
|
|
- 3742 SymTab.ClRecord)
|
|
|
- 3743 OR (braceCls =
|
|
|
- 3744 SymTab.ClClass) THEN
|
|
|
- 3745 QbeGen.CtorEnd(q)
|
|
|
- 3746 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
- 3747 QbeGen.CopyOp("0", q)
|
|
|
- 3748 END;
|
|
|
- 3749 braceCls := savedCls; .)
|
|
|
- 3750 (. astCur := astNode; .) .
|
|
|
- 3751 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
- 3752 VAR node, tail: AST.Node>
|
|
|
- 3753 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3754 qe, q2: QbeGen.QVal;
|
|
|
- 3755 v, v2, reps, k: INTEGER;
|
|
|
- 3756 elem: SymTab.TypeIndex;
|
|
|
- 3757 lo: INTEGER;
|
|
|
- 3758 span: CARDINAL;
|
|
|
- 3759 cl, cl2: INTEGER;
|
|
|
- 3760 hasR, hasB: BOOLEAN;
|
|
|
- 3761 astEl: AST.Node; .)
|
|
|
- 3762 = (. hasR := FALSE; hasB := FALSE;
|
|
|
- 3763 reps := 1; .)
|
|
|
- 3764 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3765 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3766 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3767 hasR := TRUE; .) ]
|
|
|
- 3768 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
- 3769 (. IF braceCls = SymTab.ClSet THEN
|
|
|
- 3770 IF hasB THEN SemError(230) END;
|
|
|
- 3771 lo := SymTab.SetBaseLo(vt);
|
|
|
- 3772 span := SymTab.SetCount(vt);
|
|
|
- 3773 IF (et = SymTab.InvalidType)
|
|
|
- 3774 OR (hasR AND (et2 =
|
|
|
- 3775 SymTab.InvalidType)) THEN
|
|
|
- 3776 ELSE cl :=
|
|
|
- 3777 SymTab.ClassOf(et);
|
|
|
- 3778 IF hasR THEN
|
|
|
- 3779 cl2 :=
|
|
|
- 3780 SymTab.ClassOf(et2)
|
|
|
- 3781 ELSE cl2 := SymTab.ClInt
|
|
|
- 3782 END;
|
|
|
- 3783 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3784 OR (hasR AND NOT
|
|
|
- 3785 SymTab.SetElemClassOk(cl2))
|
|
|
- 3786 THEN
|
|
|
- 3787 SemError(222)
|
|
|
- 3788 ELSIF hasR
|
|
|
- 3789 AND SymTab.ConstInt(qe, v)
|
|
|
- 3790 AND SymTab.ConstInt(q2,
|
|
|
- 3791 v2)
|
|
|
- 3792 AND ((v < lo)
|
|
|
- 3793 OR (v2 < lo)
|
|
|
- 3794 OR (v >= lo +
|
|
|
- 3795 VAL(INTEGER, span))
|
|
|
- 3796 OR (v2 >= lo +
|
|
|
- 3797 VAL(INTEGER, span))
|
|
|
- 3798 OR (v > v2)) THEN
|
|
|
- 3799 SemError(222)
|
|
|
- 3800 ELSIF hasR THEN
|
|
|
- 3801 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3802 lo, span)
|
|
|
- 3803 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3804 v)
|
|
|
- 3805 AND ((v < lo)
|
|
|
- 3806 OR (v >= lo +
|
|
|
- 3807 VAL(INTEGER,
|
|
|
- 3808 span))) THEN
|
|
|
- 3809 SemError(222)
|
|
|
- 3810 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3811 lo, span)
|
|
|
- 3812 END
|
|
|
- 3813 END
|
|
|
- 3814 ELSIF (braceCls = SymTab.ClArray)
|
|
|
- 3815 OR (braceCls =
|
|
|
- 3816 SymTab.ClRecord)
|
|
|
- 3817 OR (braceCls =
|
|
|
- 3818 SymTab.ClClass) THEN
|
|
|
- 3819 IF hasR THEN SemError(230) END;
|
|
|
- 3820 reps := 1;
|
|
|
- 3821 IF hasB THEN
|
|
|
- 3822 IF SymTab.ConstInt(q2, v2)
|
|
|
- 3823 AND (v2 >= 1) THEN
|
|
|
- 3824 reps := v2
|
|
|
- 3825 ELSE SemError(230)
|
|
|
- 3826 END
|
|
|
- 3827 END;
|
|
|
- 3828 k := 0;
|
|
|
- 3829 WHILE k < reps DO
|
|
|
- 3830 QbeGen.CtorElem(qe);
|
|
|
- 3831 INC(k)
|
|
|
- 3832 END
|
|
|
- 3833 END; .)
|
|
|
- 3834 (. (* the BY form repeats the
|
|
|
- 3835 element; keep the AST in
|
|
|
- 3836 step with CtorElem *)
|
|
|
- 3837 k := 0;
|
|
|
- 3838 WHILE k < reps DO
|
|
|
- 3839 AstAppend(AST.NkBlock,
|
|
|
- 3840 node, tail, astEl);
|
|
|
- 3841 INC(k)
|
|
|
- 3842 END; .) .
|
|
|
- 3843 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3844 qe, q2: QbeGen.QVal;
|
|
|
- 3845 v, v2: INTEGER;
|
|
|
- 3846 lo: INTEGER;
|
|
|
- 3847 span: CARDINAL;
|
|
|
- 3848 cl, cl2: INTEGER;
|
|
|
- 3849 hasR: BOOLEAN;
|
|
|
- 3850 astEl: AST.Node; .)
|
|
|
- 3851 = (. hasR := FALSE; .)
|
|
|
- 3852 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3853 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3854 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3855 hasR := TRUE; .) ]
|
|
|
- 3856 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 3857 span := SymTab.SetCount(st);
|
|
|
- 3858 IF (et = SymTab.InvalidType)
|
|
|
- 3859 OR (hasR AND (et2 =
|
|
|
- 3860 SymTab.InvalidType)) THEN
|
|
|
- 3861 ELSE cl :=
|
|
|
- 3862 SymTab.ClassOf(et);
|
|
|
- 3863 IF hasR THEN
|
|
|
- 3864 cl2 :=
|
|
|
- 3865 SymTab.ClassOf(et2)
|
|
|
- 3866 ELSE cl2 := SymTab.ClInt
|
|
|
- 3867 END;
|
|
|
- 3868 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3869 OR (hasR AND NOT
|
|
|
- 3870 SymTab.SetElemClassOk(cl2))
|
|
|
- 3871 THEN
|
|
|
- 3872 SemError(222)
|
|
|
- 3873 ELSIF hasR
|
|
|
- 3874 AND SymTab.ConstInt(qe, v)
|
|
|
- 3875 AND SymTab.ConstInt(q2,
|
|
|
- 3876 v2)
|
|
|
- 3877 AND ((v < lo)
|
|
|
- 3878 OR (v2 < lo)
|
|
|
- 3879 OR (v >= lo +
|
|
|
- 3880 VAL(INTEGER, span))
|
|
|
- 3881 OR (v2 >= lo +
|
|
|
- 3882 VAL(INTEGER, span))
|
|
|
- 3883 OR (v > v2)) THEN
|
|
|
- 3884 SemError(222)
|
|
|
- 3885 ELSIF hasR THEN
|
|
|
- 3886 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3887 lo, span)
|
|
|
- 3888 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3889 v)
|
|
|
- 3890 AND ((v < lo)
|
|
|
- 3891 OR (v >= lo +
|
|
|
- 3892 VAL(INTEGER,
|
|
|
- 3893 span))) THEN
|
|
|
- 3894 SemError(222)
|
|
|
- 3895 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3896 lo, span)
|
|
|
- 3897 END
|
|
|
- 3898 END; .)
|
|
|
- 3899 (. AST.SetChild(node,
|
|
|
- 3900 AST.NChild(node), astEl); .) .
|
|
|
- 3901 GetIdent<VAR n: SymTab.Name>
|
|
|
- 3902 = ident (. LexName(n); .) .
|
|
|
- 3903
|
|
|
- 3904 END M2.
|
|
|
+ 3685 braceCls := savedCls; .)
|
|
|
+ 3686 (. astCur := astNode; .) .
|
|
|
+ 3687 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
+ 3688 VAR node, tail: AST.Node>
|
|
|
+ 3689 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3690 qe, q2: QbeGen.QVal;
|
|
|
+ 3691 v, v2, reps, k: INTEGER;
|
|
|
+ 3692 elem: SymTab.TypeIndex;
|
|
|
+ 3693 lo: INTEGER;
|
|
|
+ 3694 span: CARDINAL;
|
|
|
+ 3695 cl, cl2: INTEGER;
|
|
|
+ 3696 hasR, hasB: BOOLEAN;
|
|
|
+ 3697 astEl: AST.Node; .)
|
|
|
+ 3698 = (. hasR := FALSE; hasB := FALSE;
|
|
|
+ 3699 reps := 1; .)
|
|
|
+ 3700 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3701 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3702 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3703 hasR := TRUE; .) ]
|
|
|
+ 3704 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
+ 3705 (. IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3706 IF hasB THEN SemError(230) END;
|
|
|
+ 3707 lo := SymTab.SetBaseLo(vt);
|
|
|
+ 3708 span := SymTab.SetCount(vt);
|
|
|
+ 3709 IF (et = SymTab.InvalidType)
|
|
|
+ 3710 OR (hasR AND (et2 =
|
|
|
+ 3711 SymTab.InvalidType)) THEN
|
|
|
+ 3712 ELSE cl :=
|
|
|
+ 3713 SymTab.ClassOf(et);
|
|
|
+ 3714 IF hasR THEN
|
|
|
+ 3715 cl2 :=
|
|
|
+ 3716 SymTab.ClassOf(et2)
|
|
|
+ 3717 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3718 END;
|
|
|
+ 3719 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3720 OR (hasR AND NOT
|
|
|
+ 3721 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3722 THEN
|
|
|
+ 3723 SemError(222)
|
|
|
+ 3724 ELSIF hasR
|
|
|
+ 3725 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3726 AND SymTab.ConstInt(q2,
|
|
|
+ 3727 v2)
|
|
|
+ 3728 AND ((v < lo)
|
|
|
+ 3729 OR (v2 < lo)
|
|
|
+ 3730 OR (v >= lo +
|
|
|
+ 3731 VAL(INTEGER, span))
|
|
|
+ 3732 OR (v2 >= lo +
|
|
|
+ 3733 VAL(INTEGER, span))
|
|
|
+ 3734 OR (v > v2)) THEN
|
|
|
+ 3735 SemError(222)
|
|
|
+ 3736 ELSIF hasR THEN
|
|
|
+ 3737 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3738 lo, span)
|
|
|
+ 3739 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3740 v)
|
|
|
+ 3741 AND ((v < lo)
|
|
|
+ 3742 OR (v >= lo +
|
|
|
+ 3743 VAL(INTEGER,
|
|
|
+ 3744 span))) THEN
|
|
|
+ 3745 SemError(222)
|
|
|
+ 3746 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3747 lo, span)
|
|
|
+ 3748 END
|
|
|
+ 3749 END
|
|
|
+ 3750 ELSIF (braceCls = SymTab.ClArray)
|
|
|
+ 3751 OR (braceCls =
|
|
|
+ 3752 SymTab.ClRecord)
|
|
|
+ 3753 OR (braceCls =
|
|
|
+ 3754 SymTab.ClClass) THEN
|
|
|
+ 3755 IF hasR THEN SemError(230) END;
|
|
|
+ 3756 reps := 1;
|
|
|
+ 3757 IF hasB THEN
|
|
|
+ 3758 IF SymTab.ConstInt(q2, v2)
|
|
|
+ 3759 AND (v2 >= 1) THEN
|
|
|
+ 3760 reps := v2
|
|
|
+ 3761 ELSE SemError(230)
|
|
|
+ 3762 END
|
|
|
+ 3763 END;
|
|
|
+ 3764 k := 0;
|
|
|
+ 3765 WHILE k < reps DO
|
|
|
+ 3766 QbeGen.CtorElem(qe);
|
|
|
+ 3767 INC(k)
|
|
|
+ 3768 END
|
|
|
+ 3769 END; .)
|
|
|
+ 3770 (. (* the BY form repeats the
|
|
|
+ 3771 element; keep the AST in
|
|
|
+ 3772 step with CtorElem *)
|
|
|
+ 3773 k := 0;
|
|
|
+ 3774 WHILE k < reps DO
|
|
|
+ 3775 AstAppend(AST.NkBlock,
|
|
|
+ 3776 node, tail, astEl);
|
|
|
+ 3777 INC(k)
|
|
|
+ 3778 END; .) .
|
|
|
+ 3779 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3780 qe, q2: QbeGen.QVal;
|
|
|
+ 3781 v, v2: INTEGER;
|
|
|
+ 3782 lo: INTEGER;
|
|
|
+ 3783 span: CARDINAL;
|
|
|
+ 3784 cl, cl2: INTEGER;
|
|
|
+ 3785 hasR: BOOLEAN;
|
|
|
+ 3786 astEl: AST.Node; .)
|
|
|
+ 3787 = (. hasR := FALSE; .)
|
|
|
+ 3788 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3789 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3790 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3791 hasR := TRUE; .) ]
|
|
|
+ 3792 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 3793 span := SymTab.SetCount(st);
|
|
|
+ 3794 IF (et = SymTab.InvalidType)
|
|
|
+ 3795 OR (hasR AND (et2 =
|
|
|
+ 3796 SymTab.InvalidType)) THEN
|
|
|
+ 3797 ELSE cl :=
|
|
|
+ 3798 SymTab.ClassOf(et);
|
|
|
+ 3799 IF hasR THEN
|
|
|
+ 3800 cl2 :=
|
|
|
+ 3801 SymTab.ClassOf(et2)
|
|
|
+ 3802 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3803 END;
|
|
|
+ 3804 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3805 OR (hasR AND NOT
|
|
|
+ 3806 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3807 THEN
|
|
|
+ 3808 SemError(222)
|
|
|
+ 3809 ELSIF hasR
|
|
|
+ 3810 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3811 AND SymTab.ConstInt(q2,
|
|
|
+ 3812 v2)
|
|
|
+ 3813 AND ((v < lo)
|
|
|
+ 3814 OR (v2 < lo)
|
|
|
+ 3815 OR (v >= lo +
|
|
|
+ 3816 VAL(INTEGER, span))
|
|
|
+ 3817 OR (v2 >= lo +
|
|
|
+ 3818 VAL(INTEGER, span))
|
|
|
+ 3819 OR (v > v2)) THEN
|
|
|
+ 3820 SemError(222)
|
|
|
+ 3821 ELSIF hasR THEN
|
|
|
+ 3822 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3823 lo, span)
|
|
|
+ 3824 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3825 v)
|
|
|
+ 3826 AND ((v < lo)
|
|
|
+ 3827 OR (v >= lo +
|
|
|
+ 3828 VAL(INTEGER,
|
|
|
+ 3829 span))) THEN
|
|
|
+ 3830 SemError(222)
|
|
|
+ 3831 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3832 lo, span)
|
|
|
+ 3833 END
|
|
|
+ 3834 END; .)
|
|
|
+ 3835 (. AST.SetChild(node,
|
|
|
+ 3836 AST.NChild(node), astEl); .) .
|
|
|
+ 3837 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 3838 = ident (. LexName(n); .) .
|
|
|
+ 3839
|
|
|
+ 3840 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|