Generieren Sie mit Python eine C-Sprache aus dem S-Ausdruck

Einführung

Vorsichtsmaßnahmen

――Bitte betrachten Sie es als eine Art Spiel. -Es ist nicht die Geschichte von Gauche's Are. ――Der Autor ist mit der Sprache C nicht sehr vertraut. Bitte weisen Sie auf merkwürdige Punkte hin.

Vor kurzem habe ich damit gespielt, Lisp mit Python zu machen.

Das hat Spaß gemacht, aber ich war nicht motiviert, weil es nicht praktisch war, abgesehen davon, es zu benutzen und nicht zu benutzen, und ich fragte mich, was ich als nächstes spielen sollte. Zu dieser Zeit erinnere ich mich, dass ich irgendwo einen Artikel gelesen habe, in dem Gauche mit einem S-Typ → C-Sprachtranspiler zu kommen scheint, und es schien interessant zu sein, also habe ich den Leserteil meines eigenen Lisp vollständig abgelenkt. Ich habe es in Python implementiert. Das Original heißt CiSE (C in S-Expression), aber das diesmal implementierte ist ** ein völlig anderes **. Übrigens hat es einen eher Common Lisp Geschmack.

Veröffentlicht unter dem Namen CLOP. Wenn Sie also interessiert sind, bitte. Übrigens, es ist ein Name, den ich nicht wirklich mag, also könnte ich ihn ändern, wenn ich daran denken kann. CiSE kann cool sein.

Wie es funktioniert

Der Fluss der Erzeugung der C-Sprache aus dem S-Ausdruck ist wie folgt.

  1. Konvertieren Sie vom S-Ausdruck in eine Liste von Zeichenfolgen
  2. Wenn der Anfang der Liste * eine vordefinierte Funktion * ist, rufen Sie den Rest als Argument auf
  3. Wenn nicht, behandeln Sie es als * C-Funktion *

Eine * vordefinierte Funktion * ist zum Beispiel:

def aref(array, subscript):
    return f"{array}[{subscript}]"

Zum Beispiel wird "(aref hoge fuga)" in "[" aref "," hoge "," fuga "]" (1) konvertiert und dann "hoge [fuga]" "erzeugt (2). ist. Wenn zu diesem Zeitpunkt das erste Element der Liste nicht nachgeschlagen wird, wird es als Funktion von c verarbeitet. Zum Beispiel erzeugt "(printf" Hallo ")" "printf (" Hallo ")" "(3).

Außerdem wird "+ hoge +" in "HOGE" und "hoge-hoge" in "hoge_hoge" konvertiert.

Ich habe den Ausdruck ** Funktion ** wie im Voraus definiert verwendet, aber der Punkt ist, dass er wie ein Makro ist. Die folgenden Makros werden im Voraus in CLOP definiert.

* + - / 1+ 1- < > and aref ash break cast cond continue
decf declare defconstant defenum defstruct defsyntax
defun defunion defvar eq for if incf include let logand
logior logxor mod not or progn return setf when while

Die meisten Namen stammen von Common Lisp. C Es ist nur das, so dass Sie sich fast vorstellen können, was es tut.

Wenn Sie es nicht übersehen, sollten Sie in der Lage sein, fast alle Funktionen der C-Sprache zu handhaben.

Illustration

Hello, world!

hello.clop


(include stdio)

(defun int:main (void)
  (printf "Hello, world!\n")
  (return 0))

Ich glaube ich habe es nicht gesehen. Der Typ wird mit durch Doppelpunkte getrennten Bezeichnern deklariert, z. B. "unsigned: int: hoge". Sie können mit dem folgenden Befehl in die Sprache C konvertieren.

$ clop translate hello.clop --out hello.c

hello.c


#include <stdio.h>

int main (void)
{
  printf("Hello, world!\n");
  return 0;
}

Makro

Sie können vorerst Makros verwenden. CLOP ist jedoch nichts anderes als ein ** Listen → String-Konverter **, sodass es keine Listenoperationsfunktion gibt. Daher können Sie keine leistungsstarken Makros wie Common Lisp verwenden, aber Sie können flexibler als Makrofunktionen in C-Sprache schreiben. Zum Beispiel.

python


(defsyntax null (ptr)
  (eq ,ptr +null+))

Dies wird wie folgt erweitert.

hoge == NULL // (null hoge)

Es ist wirklich unangenehm, Anführungszeichen zu haben, obwohl es keine Anführungszeichen gibt. Wenn Sie jedoch Anführungszeichen hinzufügen, wird der Wert aus dem Argument eingefügt, das zum Zeitpunkt der Makroerweiterung angegeben wurde. Dies ist dasselbe wie das CPP-Makro, daher hier ein komplizierteres Beispiel. In CLOP können Sie Common Lisp-ähnliche Optionsargumente, Schlüsselwortargumente und Argumente variabler Länge verwenden.

with-open-file.clop


(include stdio)

(defsyntax null (ptr)
  (eq ,ptr +null+))

(defsyntax with-open-file ((stream filespec &optional (mode "w")) &body body)
  (let ((FILE*:,stream (fopen ,filespec ,mode)))
    (if (null ,stream)
      (perror "Failed to open file")
      (progn
        ,@body
        (fclose ,stream)))))

Wenn Sie , @ hoge tun, wird der Inhalt des Arguments so wie er ist erweitert. (Eine Klammer kann genommen werden)

Sie können die Makrodefinition in einen einzigen Quellcode schreiben, aber Sie können sie auch mit require aus einer anderen Datei ziehen. Wenn zu diesem Zeitpunkt die Header-Datei "include" noch nicht enthalten ist, wird sie gleichzeitig abgerufen. Beachten Sie, dass alle außer der Makrodefinition und dem Include übersprungen werden. Hier ist ein Beispiel für "erfordern" die vorherige "with-open-file.clop" mit "main.clop".

main.clop


(include stdio)
(require with-open-file)

(defun int:main (void)
  (with-open-file (fd "hello.txt")
    (fprintf fd "Hello, world!\n"))
  (return 0))
$ clop translate main.clop --out main.c

main.c


#include <stdio.h>

int main (void)
{
  ({
    FILE* fd = fopen("hello.txt", "w");
    fd == NULL? (perror("Failed to open file")) : (({
      fprintf(fd, "Hello, world!\n");
      fclose(fd);
    }));
  });
  return 0;
}

Es ist ein gruseliger Code, aber er funktioniert gut. CLOP verwendet häufig zusammengesetzte Ausdrücke (wie ({hoge; fuge; ...})), was es in einigen Fällen schrecklich machen kann.

Beiseite

1. Vorteile

Lassen Sie uns über die Vorteile nachdenken.

Mit Ausnahme des dritten ist es subtil.

2. Schwierigkeiten

Ich hatte das Gefühl, dass die Syntax der C-Sprache kompliziert war. Ich denke nicht, wenn ich rohes C schreibe, aber als ich aus dem S-Ausdruck generierte, war ich ziemlich besorgt darüber, wo ich Klammern setzen und wo ich Semikolon drücken sollte. Angesichts dessen finde ich die Ausdruckskraft der S-Formel erstaunlich.

Zusammenfassung

Oreore CiSE in Python implementiert. Ich denke, es gibt eine gewisse Anzahl universeller Wünsche, Dinge im Nicht-S-Stil im S-Stil zu schreiben (zum Beispiel Hy). Was ist mit C-Sprache? Ich würde gerne CiSE von der Hauptfamilie Gauche berühren, aber es ist schade, dass es nicht viele Informationen gibt. (Vielleicht können Sie es einfach nicht finden. Bitte lassen Sie mich wissen, wenn Sie ein gutes Dokument haben.)

** Nachtrag ** Da war so etwas. https://github.com/burtonsamograd/sxc

Recommended Posts

Generieren Sie mit Python eine C-Sprache aus dem S-Ausdruck
Rufen Sie die c-Sprache von Python aus auf (python.h)
Generieren Sie eine Klasse aus einer Zeichenfolge in Python
Weiter Python in C-Sprache
C-API in Python 3
So generieren Sie eine Sequenz in Python und C ++
Erweitern Sie Python in C ++ (Boost.NumPy)
Einbettung der Maschinensprache in die Sprache C.
Generieren Sie in Python ein abgerundetes Miniaturbild
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
OCR aus PDF in Python
Binäre Suche in Python / C ++
Generieren Sie eine U-Verteilung in Python
Generieren Sie QR-Code in Python
Generieren Sie 8 * 8 (64) Cubes mit Blender Python
Generieren Sie Word Cloud aus Testfalldaten mit Python3
Ruft Makrokonstanten aus der C (++) - Headerdatei (.h) in Python ab
Rufen Sie C von Python mit DragonFFI auf
Modultest mit mehreren Instanzen in C-Sprache
[Python] Generiert QR-Code im Speicher
100 Sprachverarbeitung Knock Kapitel 1 in Python
Realisieren Sie die Schnittstellenklasse in der Sprache C.
Generieren Sie das Jupyter-Notizbuch ".ipynb" in Python
Rufen Sie popcount von Ruby / Python / C # auf
Einführung in Protobuf-c (C-Sprache ⇔ Python)
Löse ABC036 A ~ C mit Python
Tipps zum Aufrufen von Python von C.
Führen Sie Python-Code über die C # -GUI aus
So verpacken Sie C in Python
Führen Sie Python-Skripte synchron von C # aus
Python, um von einer anderen Sprache zu wechseln
Löse ABC037 A ~ C mit Python
Segfo mit 16 Zeichen in C-Sprache
Schreiben Sie einen C-Sprach-Unit-Test in Python
Rufen Sie C / C ++ von Python auf dem Mac auf
Extrahieren Sie mit Python Zeichenfolgen aus Dateien
Rufen Sie mit ctypes Ihre eigene gemeinsam genutzte Bibliothek in C-Sprache von Python aus auf
Generieren Sie eine erstklassige Sammlung in Python
Linkliste (list_head / queue) in C-Sprache
Generieren Sie eine AWS-S3-signierte (zeitlich begrenzte) URL in Python
4-Sprachen-Vergleich des Abschlusses (Python, JavaScript, Java, C ++)
Algorithmus in Python (ABC 146 C Dichotomie
Wiederbelebt von "kein Internetzugang" in Python
Verhindern Sie den doppelten Start von cron in Python
Implementieren Sie den FIR-Filter in Python und C.
Python Docstring-Kommentar automatisch mit Emacs generieren
Schreiben Sie die O_SYNC-Datei in C und Python
Modul zum Generieren des Wortes N-Gramm in Python
Laden Sie Bilder von der URL-Liste in Python herunter
Holen Sie sich den Batteriestand von SwitchBot mit Python
Socket-Kommunikation in C-Sprache und Python
Verwenden von C ++ - Funktionen aus Python mit pybind11
In Python von Markdown in HTML konvertieren
Holen Sie sich mit Python die Niederschlagswahrscheinlichkeit aus XML
Führen Sie Python in C ++ unter Visual Studio 2017 aus
Abrufen des Metrikverlaufs von MLflow in Python
C-Sprache zum Anzeigen und Erinnern Teil 2 Rufen Sie die C-Sprache aus der Python-Zeichenfolge (Argument) auf
[C-Sprache] Ich möchte Zufallszahlen im angegebenen Bereich generieren
C-Sprache zum Sehen und Erinnern Teil 1 Rufen Sie die C-Sprache aus Python auf (Hallo Welt)
C-Sprache zum Anzeigen und Erinnern Teil 4 Rufen Sie die C-Sprache von Python (Argument) double auf