compiler-campusminden / mini-python-builder Goto Github PK
View Code? Open in Web Editor NEWMini-Python Builder (Backend)
License: MIT License
Mini-Python Builder (Backend)
License: MIT License
Für die C-Runtime wird eine POSIX-Funktion benötigt, die unter Windows nicht zur Verfügung steht. Es würde sich anbieten, ein passendes Docker-Image zu pflegen und bereitzustellen. Ggf. könnte dieses auch gleich als "Dev-Container" (VS Code) oder als "Codespace" (GitHub) definiert werden?
Die C-Runtime wird aktuell im Makefile mit CFLAGS ?= -pedantic -Wall -Werror
kompiliert. Das wirft auf macOS 14 mit dem Default-clang (Version 15.0.0) jede Menge Warnings bzgl. der Prototypen, die wg. -Werror
als Fehler behandelt werden:
In file included from compilerOutput/src/builtins-setup.c:2:
In file included from compilerOutput/include/builtins-setup.h:4:
In file included from compilerOutput/include/type-hierarchy/function.h:4:
compilerOutput/include/mpy_obj.h:89:24: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
__MPyObj* __mpy_obj_new();
^
void
In file included from compilerOutput/src/builtins-setup.c:2:
compilerOutput/include/builtins-setup.h:108:26: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
void __mpy_builtins_setup();
^
void
compilerOutput/include/builtins-setup.h:110:28: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
void __mpy_builtins_cleanup();
^
void
In file included from compilerOutput/src/builtins-setup.c:17:
compilerOutput/include/type-hierarchy/object.h:6:32: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
__MPyObj *__mpy_obj_init_object();
^
void
compilerOutput/src/builtins-setup.c:125:26: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
void __mpy_builtins_setup() {
^
void
compilerOutput/src/builtins-setup.c:308:28: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
void __mpy_builtins_cleanup() {
^
void
Optionen:
-Werror
im Makefile (Quick&Dirty)void
Wir haben ein Target, welches ein JAR des Projekts erzeugt. Dieses könnte im Rahmen eines Releases oder als Artefakt o.ä. angeboten werden.
Alternativ auch als Package?!
In section "Klassenobjekte" we use "__init
" (this should be "__init__
").
Der Mini-Python-Builder erzeugt aktuell C-Code, der zusammen mit einer rudimentären C-Runtime in ein ausführbares Programm kompiliert wird (gcc, clang) und nativ läuft.
Ziel dieses Issues ist die Konzipierung einer (Stack-basierten) VM sowie des zugehörigen Bytecodes. Somit könnte man den Mini-Python-Builder dann zum Erzeugen von Bytcode benutzen, der in der implementierten VM läuft.
Es muss ein entsprechendes Konzept erstellt werden, ggf. Schnittstellen etc. angepasst werden sowie eine Umsetzung implementiert werden.
Der Mini-Python-Builder erzeugt aktuell C-Code, der zusammen mit einer rudimentären C-Runtime in ein ausführbares Programm kompiliert wird (gcc, clang) und nativ läuft.
Es wäre wünschenswert, ein weiteres Target zu integrieren: WebAssembly (https://github.com/webassembly). Damit wäre man in der Lage, den vom Builder ausgegebenen Code direkt im Browser laufen zu lassen.
Es muss ein entsprechendes Konzept erstellt werden, ggf. Schnittstellen etc. angepasst werden sowie eine Umsetzung implementiert werden. Eine kleine Umgebung für den Browser wird ebenfalls benötigt.
Es wäre in Absprache auch denkbar, dieses neue Target in einer anderen Implementierungssprache als C zu realisieren.
Der Mini-Python-Builder erzeugt aktuell C-Code, der zusammen mit einer rudimentären C-Runtime in ein ausführbares Programm kompiliert wird (gcc, clang) und nativ läuft.
Um den Mini-Python-Builder auch in Zukunft weiterhin pflegen und erweitern zu können, brauchen wir eine Testsuite für den Builder sowie für die Runtime.
Dazu sollte das Projekt analysiert werden, ein Testkonzept erstellt werden und entsprechend umgesetzt werden. Eine Automatisierung bzgl. GitHub-Actions sollte es ebenfalls geben.
Wir haben ein Target, welches ein JAR erzeugt. Die Dokumentation sollte ergänzt werden: Wie binde ich das JAR in mein Projekt ein, ohne die Sourcen bzw. dieses Repo zu nutzen?
=> Das müsste vorher auch nochmal getestet werden!
Welche Java-Version wird gebraucht?
Prinzipiell sollte der CBuilder mit jeder Java-Version laufen, aber das eingebettete Gradle hat eine Abhängigkeit ... (siehe https://docs.gradle.org/current/userguide/compatibility.html).
Hier scheinen wir JDK 17 zu brauchen. Das sollte dokumentiert werden.
Wie in #1 (comment) beschrieben, muss die Reihenfolge der Funktionsdefinitionen im CBuilder beachtet werden.
Im generierten C-Code werden die Funktionen in der Reihenfolge definiert, wie sie im CBuilder hinzugefügt wurden. Da in C eine Funktion beim Aufruf aber bereits bekannt sein muss (oder zumindest die Deklaration), bedeutet dies, dass aktuell die Nutzer des CBuilders selbst dafür sorgen müssen, dass aufgerufene Funktionen vor den aufrufenden Funktionen im CBuilder definiert werden.
Beispiel aus #1 (comment):
def first():
second()
def second():
print("second")
Hier muss der User selbst Sorge dafür tragen, dass im CBuilder zunächst die Funktion second()
definiert wird und erst danach die Funktion first()
. Anderenfalls wird beim Compilieren des generierten C-Codes eine Fehlermeldung durch den C-Compiler entstehen, dass die Funktion second()
beim Aufruf in first()
nicht definiert ist.
Ein erster Lösungsvorschlag wäre, in ProgramBuilder#buildProgram()
die Schleife
Mini-Python-Builder/src/main/java/CBuilder/ProgramBuilder.java
Lines 141 to 144 in 902fd00
program.append(f.buildFuncObjectDeclaration())
), und in einer zweiten Schleife anschließend die Funktionsdefinitionen geschrieben werden (program.append(f.buildCFunction())
).
Follow-Up zu #1
Bei der Verwendung von Rekursion scheint es noch ein Problem zu geben, weshalb sich der generierte C-Quellcode nicht kompilieren lässt.
In Anbetracht des folgenden Java-Beispiels:
import CBuilder.ProgramBuilder;
import CBuilder.Reference;
import CBuilder.objects.Call;
import CBuilder.objects.functions.Function;
import java.nio.file.Path;
import java.util.List;
public class Program {
public static void main(String[] args) {
ProgramBuilder programBuilder = new ProgramBuilder();
programBuilder.addFunction(new Function(
"f",
List.of(new Call(new Reference("f"), List.of())),
List.of(),
List.of()));
programBuilder.writeProgram(Path.of("out"));
}
}
Landet im generierten C-Quellcode die Deklaration des Objektes f
hinter der Implementierung der Funktion func_f
__MPyObj* func_f(__MPyObj *args, __MPyObj *kwargs) {
assert(args != NULL && kwargs != NULL);
__MPyGetArgsState argHelper = __mpy_args_init("f", args, kwargs, 0);
__mpy_args_finish(&argHelper);
__MPyObj *retValue = NULL;
__mpy_obj_ref_dec(__mpy_call(f, __mpy_obj_init_tuple(0), NULL));
goto ret;
ret:
if (retValue == NULL) {
retValue = __mpy_obj_init_object();
}
return __mpy_obj_return(retValue);
}
__MPyObj *f;
Beim Builden des generierten C-Quellcodes wird dadurch folgende Fehlermeldung geworfen (GCC 11):
out/src/program.c:24:38: error: ‘f’ undeclared (first use in this function)
24 | __mpy_obj_ref_dec(__mpy_call(f, __mpy_obj_init_tuple(0), NULL));
|
Verschiebe ich nun manuell im C-Quellcode die Deklaration von f
vor die Implementierung func_f
läuft das Build erfolgreich durch und die Ausführung scheint korrekt zu funktionieren.
Das eingebettete Gradle erzwingt eine bestimmte Java-Version. Wir verwenden hier aktuell Gradle 7.4.2, wodurch wir maximal JDK 17 verwenden können. Das läuft zwar erst in 2024 aus, aber ...
(Leider kommen wir noch nicht auf die aktuell LTS (JDK 21), weil das von Gradle immer noch nicht unterstützt wird.)
https://docs.gradle.org/current/userguide/compatibility.html
Die Datei src/main/java/CBuilder/ManualTest.java
ist eine Testdatei und sollte in src/test/java/
liegen. Dito das "Package" CBuilder.manualTests
.
Im Builder wird commons-io:commons-io:2.11.0
als externe Abhängigkeit definiert.
Die einzige Stelle, wo ich einen entsprechenden Import finde, ist ProgramBuilder
(import org.apache.commons.io.FileUtils;
). Das wird an einer einzigen Stelle genutzt (Zeile 222 FileUtils.copyDirectory(p.toFile(), directory.toFile());
").
Muss das so oder gibt es eine Lösung innerhalb der JDK-Standardlibs?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.