Oui, troff est Turing-complete. Il prend en charge la récursion arbitraire et la ramification conditionnelle, ce qui est suffisant. Il a également des registres et diverses autres façons de stocker des données, ce qui vous donne à nouveau un autre chemin d'accès.
L'exhaustivité de Turing n'implique pas que des programmes très complexes sont pratiques - juste qu'ils sont théoriquement possibles, d'une manière ou d'une autre, à un certain niveau de suppression - et son absence n'implique pas non plus qu'ils ne le sont pas, donc ni Troff n'est Turing-complet ni L'absence de programmes complexes ne suggère pas grand chose dans un sens ou dans l'autre.
Turing l'exhaustivité n'est généralement pas une propriété qui signifie quelque chose d'utile pour vous, l'utilisateur. Tout ce que cela signifie, c'est que vous pouvez simuler une machine de Turing avec elle, pas que vous le souhaitiez, et non que la sortie que vous en obtiendriez ressemble à ce que vous vous attendez à lire. L'entrée ou la sortie peut être simplement un nombre, ou même le nombre de fois où quelque chose apparaît, plutôt que quelque chose d'utile, et les types de machines que vous finissez par simuler et leurs programmes sont souvent à peine compréhensibles au départ.
De nombreux langages et systèmes sont accessoirement Turing-complete mais ne s'appliquent raisonnablement à aucune programmation réelle dans ce sous-ensemble (par exemple, Conway's Game of Life ou CSS), et certains langages qui sont utiles pour la programmation réelle ne sont pas Turing-complete (par exemple, Agda). Les caractéristiques déterminantes sont que vous pouvez
- continue pour toujours
- rappelez-vous autant de données que vous le souhaitez
- choisir quoi, le cas échéant, faire ensuite
Souvent, ces propriétés - en particulier la non-terminaison - sont en fait indésirables, y compris éventuellement pour les troff. En dehors de l'informatique théorique et de la conception du langage, l'exhaustivité de Turing n'est pas une propriété terriblement intéressante pratiquement du temps, bien qu'elle soit accrocheuse.
mov
est Turing-complete. (En raison des modes d'adressage qui vous permettent d'utiliser des tables de recherche, et le même mnémonique est utilisé pour le chargement, le stockage et mov-immediate pour l'enregistrement.) Sur de nombreux autres ISA qui ont unemov
instruction (par exemple ARM), c'est juste un mouvement reg-reg et n'est pas complet. (Bien que sur ARM, il puisse effectuer des changements / rotations.) De plus, vous avez réellement besoin d'unjmp
pour créer une boucle autour de votre bloc d'mov
instructions, à moins que vous ne soyez en mode 16 bits où le pointeur d'instruction peut s'enrouler dans un segment de code 64k pour boucle implicitement.push {r4, lr}
/pop {r4,pc}
est commun dans les fonctions qui doivent enregistrer / restaurer un registre préservé par les appels et garder la pile alignée: ils enregistrent également le lien reg et le replacent dans le compteur de programme pour revenir. (Les instructions de stockage / chargement multiple de l'ARM 32 bits utilisent un champ de bits pour indiquer les registres à stocker / charger.) Et oui, vous pouvez utiliser PC comme destination d'unemov
ou de n'importe quelle instruction. Je ne savais pas que c'était commun dans le passé, cependant. Mais j'avais entendu parler d'ISA déclenchées par le transport.