[PYTHON] Ich habe ein Tool erstellt, um Hy nativ zu kompilieren

Einführung

In Vorheriger Beitrag habe ich ein Tool zum gleichzeitigen Ausführen und Archivieren von Quellcode vorgestellt. Die Einführung dieser Zeit ist ein Tool, das Hy nativ kompiliert, um ausführbare Dateien und gemeinsam genutzte Bibliotheken zu erstellen. Sie können es auch in die Python- oder C-Sprache konvertieren. Es ist in PyPI unter dem Namen HyCC registriert. Es besteht jedoch weiterhin die Möglichkeit ** unerwarteter Fehler **. Verwenden Sie diese daher bitte unter ** Eigenverantwortung **. Übrigens ** sind alle in Hy ** implementiert.

Wie benutzt man

Bitte installieren Sie von pip. ** Der Vorgang in der Windows-Umgebung wurde jedoch nicht bestätigt. ** ** **

$ pip install hycc

~~ Wenn die neueste Version von PyPI Hy (v0.12.1) ist, kann ein Code aufgrund eines Fehlers in Hy einen Fehler verursachen. Installieren Sie daher bitte die neueste Version von Github. ~~ ** 01.07.2017 Nachtrag: Diese Arbeit ist aufgrund der Aktualisierung von Hy und HyCC nicht mehr erforderlich. **

Nachdem die Vorbereitung abgeschlossen ist, nehmen wir den folgenden Code als Beispiel.

hello.hy


(defn hello []
  (print "hello!"))

(defmain [&rest args]
  (hello))

Erstellen Sie eine ausführbare Datei

$ hycc hello.hy

Dadurch wird eine ausführbare Binärdatei mit dem Namen "Hallo" im aktuellen Verzeichnis erstellt.

$ ./hello
hello!

Erstellen Sie eine gemeinsam genutzte Bibliothek

Erstellen Sie mit der Option "--shared".

$ hycc hello.hy --shared

Dadurch wird ein freigegebenes Objekt mit dem Namen "hello.so" im aktuellen Verzeichnis erstellt. Python kann gemeinsam genutzte Objekte als Module importieren, aber Hy ist natürlich dasselbe. Daher kann dieses "Hallo" wie folgt verwendet werden.

Hy zu hallo.so importieren


(import hello)
(hello.hello)
; >hello!

Hallo von Python.so importieren


import hello
hello.hello()
# >hello!

Nativ kompilierte Module und ausführbare Dateien sind ** etwa 2-8 mal schneller **. Ich denke, es ist nützlicher als die Verwendung von "hyc" zum Byte-Kompilieren in eine ".pyc" -Datei. Und natürlich ** schneller als Python **. Intern wird Cython verwendet, aber das Bild der Geschwindigkeit ist wie folgt.

** C <Cython (mit Typspezifikation) << Cython (ohne Typspezifikation) <HyCC <Python <Hy **

Es ist im Allgemeinen ** aufwärtskompatibel mit hyc **, aber es gibt eine Einschränkung **. Da es sich um den internen Mechanismus handelt, werde ich ihn erläutern und den Mechanismus im Folgenden erläutern.

Wie es funktioniert

Grob gesagt wird Hy-Code in Python konvertiert, über Cython in C konvertiert und kompiliert. Wie in Letzter Beitrag erwähnt, wurde der Python-Code jedoch mit dem im Lieferumfang von Hy enthaltenen "hy2py" generiert. ** Funktioniert nicht so wie es ist **. Daher ist es nicht möglich, nur "hy2py" und "cythonize" zu verwenden.

Konvertieren Sie Hy in Python

Erstens ** Warum funktioniert der Code, den hy2py ausspuckt, nicht **? Weil Python einen ungültigen Bezeichner verwendet. Die ungültigen Bezeichner in Python sind:

    • Kennung beginnend mit der Nummer 0-9 *
  1. Bezeichner mit anderen Zeichen als * _, a-z, A-Z, 0-9 *

Nehmen Sie den folgenden Code als Beispiel.

sample.hy


(reduce + [1 2 3])
; > 6

Wenn Sie dies mit "hy2py" konvertieren, erhalten Sie Folgendes.

Code, den hy2py spuckt


from hy.core.language import reduce
from hy.core.shadow import +
# +Ist eine ungültige Kennung
reduce(+, [1, 2, 3])

Hier ist + die obige 2. Weil es entspricht, ist es nutzlos. Das einfache Ersetzen durch einen anderen gültigen Namen wie "Hinzufügen" funktioniert nicht.

Von dem Code, den hy2py spuckt+Durch Hinzufügen ersetzen


from hy.core.language import reduce
from hy.core.shadow import add
# ImportError
reduce(add, [1, 2, 3])

Offensichtlich ist für das Modul "hy.core.shadow" nicht der Name "add" definiert, daher ist es "ImportError". HyCC generiert zunächst den folgenden Python-Code aus der Hy-Quelle, um dieses Problem zu lösen.

HyCC Weg


import hy.core.language as _
reduce = _.getattr("reduce")
import hy.core.shadow as _
+ = _.getattr("+")
reduce(+, [1, 2, 3])

Dieser Code entspricht dem Code, den hy2py ausspuckt, aber Sie können + durch einen beliebigen Namen ersetzen. HyCC vermeidet Fehler, indem der Zugriff auf AST-Ebene und der Zugriff auf Quellcode-Ebene ordnungsgemäß kombiniert werden. Ebenso wird der Mitgliederzugriff des Objekts mit "getattr" und "setattr" neu geschrieben.

Vorsichtsmaßnahmen bei der Verwendung von HyCC (** wichtig **)

Informationen zu den oben genannten Vorsichtsmaßnahmen bei der Verwendung von HyCC. Wie bisher erläutert, ersetzt HyCC ungültige Kennungen durch gültige mit einigem Einfallsreichtum. Zu diesem Zeitpunkt tritt nur eine Nebenwirkung oder ein Problem auf.

HyCC Bösewicht


(def hoge/fuga 0)
(print (get (globals) "hoge/fuga"))
; > 0

Der obige Code wird von HyCC in den folgenden Python-Code konvertiert.

Von HyCC generierter Code


from __future__ import print_function
import hy
hogex2Ffuga = 0L
print(globals()[u'hoge/fuga'])

Sie können das Hinzufügen einiger Importe ignorieren. Im ursprünglichen Hy-Code war "hoge / fuga" ein ungültiger Name in Python. Daher wird es im von HyCC generierten Code durch "hogex2Ffuga" ersetzt.

Das Ausführen dieses Codes führt zu folgendem Fehler.

  File "test.py", line 4, in <module>
    print(globals()[u'hoge/fuga'])
KeyError: u'hoge/fuga'

Hast du verstanden? Der negative Effekt des Ersetzens eines ungültigen Bezeichners durch einen gültigen besteht darin, dass die Module "Globals", "Locals" und "Inspect" in einigen Fällen möglicherweise nicht ordnungsgemäß funktionieren.

Wir erwägen einige Gegenmaßnahmen für dieses Problem, aber ** Hy selbst hat bereits ein ähnliches Problem **. In Hy wird "hoge!" In der Phase der Syntaxanalyse durch "hoge_bang" und "hoge" ersetzt. "Wird durch" is_hoge "ersetzt. Daher funktioniert der folgende Code nicht ordnungsgemäß.

Hy und Bösewicht


(def hoge! 0)
(print (get (globals) "hoge!"))
; > KeyError!

Daher kann die Verwendung von "Globals" usw. als ** Vorsichtsmaßnahmen bei der Verwendung von HyCC und nicht als Vorsichtsmaßnahmen bei der Verwendung von HyCC ** bezeichnet werden.

*** 2017/06/04 Nachtrag *** ** Unterstützt durch Update! ** Insbesondere wird ein Schlüsselfehler vermieden, indem "Globale" und "Einheimische" in eine Mystery-Klasse wie "dict" eingeschlossen werden. Wie üblich funktioniert das "inspect" -Modul nicht richtig, aber ** Cython selbst unterstützt "inspect" ** nicht, daher kann ich nichts dagegen tun. Weitere Informationen finden Sie unter This Commit.

Bonus (Konvertieren in Python, das richtig funktioniert)

HyCC hat auch eine Funktion zum Konvertieren von Hy nach Python wie "hy2py".

$ hycc hello.hy --python

Dies gibt "hello.py" in das aktuelle Verzeichnis aus. Wenn Sie die obigen Hinweise beachten, funktioniert es im Gegensatz zu dem von ** hy2py ** ausgegebenen Code ordnungsgemäß. Überraschenderweise ist diese Funktion möglicherweise stärker gefragt. Ebenso kann es mit der Option "--clang" in die Sprache C konvertiert werden, es ist jedoch schwierig, ob es verwendet werden kann.

Bekannter Fehler (Hinzugefügt am 13.06.2017)

Die gemeinsam genutzte Bibliothek beim Import schlägt fehl

Wie ich in Github-Ausgaben geschrieben habe, handelt es sich um eine Python-Spezifikation? Wenn Sie ein Submodul mit gettatr für ein Modulobjekt erhalten Es scheint "AttributeError" zu sein, wenn das Submodul eine gemeinsam genutzte Bibliothek enthält. Ich denke darüber nach, wie ich damit umgehen soll.

abschließend

Einführung von Tool zum nativen Kompilieren von Hy. Die gesamte Entwicklung erfolgt auf github. Sie können sich also gerne an Pururiku wenden. Sie können Pulls werfen) oder Probleme. Kommentare hier sind natürlich auch willkommen. Hy ist immer noch eine sich entwickelnde verdammte Nebensprache, aber ich hoffe, dass sie mit zunehmender Anzahl von Benutzern und aktiveren Diskussionen komplexer wird. Vielen Dank, dass Sie so weit gelesen haben.

Recommended Posts

Ich habe ein Tool erstellt, um Hy nativ zu kompilieren
Ich habe ein Tool erstellt, um neue Artikel zu erhalten
Ich habe ein Tool erstellt, um eine Wortwolke aus Wikipedia zu erstellen
[Titan Craft] Ich habe ein Werkzeug gemacht, um einen Riesen nach Minecraft zu rufen
Ich habe ein Skript erstellt, um Piktogramme anzuzeigen
Ich habe ein automatisches Stempelwerkzeug für den Browser erstellt.
〇✕ Ich habe ein Spiel gemacht
Ich habe ein nützliches Tool für Digital Ocean erstellt
Ich habe ein Tool zum automatischen Durchsuchen mehrerer Websites mit Selenium (Python) erstellt.
Ich habe ein CLI-Tool erstellt, um Bilder in jedem Verzeichnis in PDF zu konvertieren
Ich habe ein Router-Konfigurationssammlungstool Config Collecor erstellt
Ich habe ein Tool erstellt, um Jupyter py mit VS Code in ipynb zu konvertieren
Ich habe ein Tool erstellt, um die Ausführungszeit von cron zu schätzen (+ PyPI-Debüt)
Ich habe gerade ein Tool erstellt, mit dem Daten mithilfe der GUI-Operation einfach als Diagramm angezeigt werden können
Ich habe ein Tool zum Generieren von Markdown aus der exportierten Scrapbox-JSON-Datei erstellt
Ich habe ein Tool zum automatischen Sichern der Metadaten der Salesforce-Organisation erstellt
Ich habe ein Paket erstellt, um eine ausführbare Datei aus dem Hy-Quellcode zu erstellen
Ich habe eine Bibliothek erstellt, um japanische Sätze schön zu brechen
Ich habe ein Reinigungstool für Google Container Registry erstellt
Ich habe ein Skript erstellt, um ein Snippet in README.md einzufügen
Ich habe ein Python-Modul erstellt, um Kommentare zu übersetzen
Ich habe einen Code erstellt, um illustration2vec in ein Keras-Modell zu konvertieren
Ich habe einen Befehl zum Markieren des Tabellenclips gegeben
Ich habe eine Python-Bibliothek erstellt, die einen rollierenden Rang hat
Ich habe ein Tool zur Erzeugung sich wiederholender Textdaten "rpttxt" erstellt.
Ich habe einen Python-Text gemacht
Ich habe einen Zwietrachtbot gemacht
Ich habe ein Paket erstellt, um Zeitreihen mit Python zu filtern
Ich habe eine Schachtel gemacht, um mich auszuruhen, bevor Pepper müde wird
Ich habe einen Befehl zum Generieren eines Kommentars für eine Tabelle in Django eingegeben
Ich habe eine Funktion erstellt, um das Modell von DCGAN zu überprüfen
Ich habe versucht, mit Hy ・ Define a class zu beginnen
Ich habe Sie dazu gebracht, Befehle über einen WEB-Browser auszuführen
Ich habe ein Drehbuch gemacht, um bei meinem Koshien Hallo zu sagen
Erstellt einen Toolsver, der Betriebssystem, Python, Module und Toolversionen an Markdown ausspuckt
Ich habe ein Tool erstellt, mit dem das Erstellen und Installieren eines öffentlichen Schlüssels etwas einfacher ist.
Ich habe ein Tool erstellt, um die Antwortlinks von OpenAI Gym auf einmal zu erhalten
Ich habe ein Tool erstellt, um automatisch ein einfaches ER-Diagramm aus der Anweisung CREATE TABLE zu generieren
Erstellt ein Tool, mit dem Sie bequem Parameter für Modelle des maschinellen Lernens festlegen können
Ich habe eine C ++ - Lernseite erstellt
Ich habe einen Line-Bot mit Python gemacht!
Ich habe einen Wikipedia Gacha Bot gemacht
Ich habe mit Python eine Lotterie gemacht.
Ich habe ein CUI-basiertes Übersetzungsskript erstellt
Tool zum Konvertieren der Juniper-Konfiguration
Ich habe mit Python einen Daemon erstellt
[5.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Ich habe versucht, ein Programm zu erstellen, um die Fehlersuche von Saiseriya zu lösen (Hinweis)
Ich habe eine Bibliothek erstellt, die Konfigurationsdateien mit Python einfach lesen kann
[2nd] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Ich habe mit Razpai einen Webserver erstellt, um Anime zu schauen
[3.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Erstelltes WebSocket Client / Server-CLI-Tool (wie WebSocket Version Netcat)
[4.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Ich habe versucht, ein Gerüstwerkzeug für Python Web Framework Bottle zu erstellen
[1.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Ich habe den Befehl gegeben, einen farbenfrohen Kalender im Terminal anzuzeigen
Ich habe versucht, einen Linebot zu erstellen (Implementierung)
Ich habe einen Docker-Container erstellt, um JUMAN ++, KNP, Python (für pyKNP) zu verwenden.
Ich habe ein Plugin erstellt, um mit Vim eine Markdown-Tabelle aus CSV zu generieren