Beitragen¶
Wir freuen uns über Beiträge von jedem, auch wenn du neu im Bereich Open Source bist. Es mag zunächst entmutigend klingen, zu einem Compiler beizutragen, aber tu es einfach, denn es ist nicht so kompliziert, wie es aussieht. Wir werden bei allen technischen Problemen helfen und deinen Beitrag verbessern, damit er eingefügt werden kann.
Grundeinstellung¶
Um Beizutragen solltest du folgendes vorbereitet haben:
Dein Benutzername + E-Mail
Deine
~/.gitconfig
Deine Shell Eingabe sollte den aktuellen Branch Namen anzeigen
LFortran abspalten¶
Schritt 1. Erstelle einen Fork des Projekt Repositorys
Schritt 2: Richte deinen SSH key mit GitHub ein
Schritt 3: Klone das Projekt Repository von GitHub und richte dein Remote-Repository ein
git clone https://github.com/lfortran/lfortran.git
cd lfortran
git remote add REMOTE_NAME git@github.com:YOUR_GITHUB_ID/lfortran.git
:fontawesome-solid-edit: REMOTE_NAME
ist der Name deines Remote-Repositorys und kann prinzipiell beliebig sein, beispielsweise dein Vorname.
:fontawesome-solid-edit: YOUR_GITHUB_ID
ist deine Nutzer-ID auf GitHub und sollte Teil deines Accountpfades sein.
Du kannst git remote -v
verwenden um zu überprüfen ob der neue Remote korrekt eingerichtet ist.
Sende einen neuen Merge request¶
Schritt 1. Erstellen Sie einen neuen Zweig
git checkout -b fix1
Schritt 2. Nehmen Sie Änderungen in der/den betreffenden Datei(en) vor
Schritt 3: Committe deine Änderungen:
git add FILE1 (FILE2 ...)
git commit -m "YOUR_COMMIT_MESSAGE"
Hier gibt es sehr hilfreiche Tipps zum Schreiben guter Commit-Messages.
Schritt 4: Überprüfe, dass deine Änderungen gut aussehen
git log --pretty=oneline --graph --decorate --all
Schritt 5: Sende den merge-request
git push REMOTE_NAME fix1
Der Befehl pushed den neuen Branch fix1
in dein remote Repository REMOTE_NAME
, welches du zuvor erstellt hast. Zusätzlich wird ein Link angezeigt, welcher geklickt werden kann um einen neuen merge request zu starten. Nach dem Klicken, schreibe einen Titel und eine kurze Beschreibung, anschließend klicke auf den „Create“-Button. Du bist nun fertig.
Neue Funktionen hinzufügen¶
Das folgende Beispiel zeigt die Schritte die erforderlich sind um den binären Operator ^ zu erstellen, welcher den Mittelwert der beiden Operanden berechnet.
Neue(s) Token erstellen¶
Wir erweitern den tokenizer.re und den parser.yy um den Token ^. Wir werden außerdem LFortran in parser.cpp sagen, wie der neue Token ausgegeben werden soll.
:fontawesome-solid-code: src/lfortran/parser/tokenizer.re
// "^" { RET(TK_CARET) }
:fontawesome-solid-code: src/lfortran/parser/parser.yy
%token TK_CARET "^"
:fontawesome-solid-code: src/lfortran/parser/parser.cpp
std:string token2text(const int token)
{
switch (token) {
T(TK_CARET, "^")
}
}
Der hinzugefügte Code wird mit lfortran --show-tokens examples2/expr2.f90
getestet
Parsen des neuen Tokens¶
Nun muss der neue Operator geparsed werden. Wir fügen ihn zum AST hinzu, indem wir den BinOp um den Caret-Operator erweitern und die AST.asdl -Datei anpassen. Anschließend fügen wir ihn in parse.yy hinzu um den neuen AST in semantics.h richtig zu parsen und zu generieren. Abschließend erweitern wir pickle.cpp, sodass der neue Operator sich selbst ausgeben kann.
:fontawesome-solid-code:grammar/AST.asdl
operator = Add | Sub | Mul | Div | Pow | Caret
:fontawesome-solid-code:src/lfortran/parser/parser.yy
%left "^"
expr
: id { $$=$1; }
| expr "^" expr { $$ = CARET($1, $3, @$); }
:fontawesome-solid-code:src/lfortran/parser/semantics.h
#define CARET(x,y,l) make_BinOp_t(p.m_a, l, EXPR(x), operatorType::Caret, EXPR(y))
:fontawesome-solid-code:src/lfortran/pickle.cpp
std::string op2str(const operatorType type)
{
switch (type) {
case (operatorType::Caret) : return "^";
} // now the caret operator can print itself
}
Der Abschnitt lässt sich mit lfortran --show-ast examples/expr2.f90
testen
Implementieren der Semantik des neuen Tokens¶
Zuerst erweitern wir den ASR in ASR.asdl und fügen ^ als eine BinOp-operator Option hinzu.
:fontawesome-solid-code:src/libasr/ASR.asdl
binop = Add | Sub | Mul | Div | Pow | Caret
:fontawesome-solid-code:src/lfortran/semantics/ast_common_visitor.h
namespace LFortran {
class CommonVisitorMethods {
public:
inline static void visit_BinOp(Allocator &al, const AST::BinOp_t &x,
ASR::expr_t *&left, ASR::expr_t *&right,
ASR::asr_t *&asr) {
ASR::binopType op;
switch (x.m_op) {
case (AST::Caret):
op = ASR::Caret;
break;
}
if (LFortran::ASRUtils::expr_value(left) != nullptr &&
LFortran::ASRUtils::expr_value(right) != nullptr) {
if (ASR::is_a<LFortran::ASR::Integer_t>(*dest_type)) {
int64_t left_value = ASR::down_cast<ASR::IntegerConstant_t>(
LFortran::ASRUtils::expr_value(left))
->m_n;
int64_t right_value = ASR::down_cast<ASR::IntegerConstant_t>(
LFortran::ASRUtils::expr_value(right))
->m_n;
int64_t result;
switch (op) {
case (ASR::Caret):
result = (left_value + right_value)/2;
break;
}
}
}
}
}
}
Anschließend wandeln wir ihn vom AST zum ASR um, indem wir src/lfortran/semantics/ast_common_visitor.h ergänzen.
Zusätzlich fügen wir ihn in die „Compile time evaluation“ hinzu, die durch Ausdrücke wie z.B. e = (2+3)^5
ausgelöst wird. Ein Ausdruck wie beispielsweise e = x^5
wird nur zur Laufzeit evaluiert.
Dieser Abschnitt lässt sich mit lfortran --show-asr examples/expr2.f90
testen
Implementierung des neuen Tokens in LLVM¶
Zur Implementierung in LLVM erweitern wir die BinOp-Übersetzung um die Verarbeitung des neuen Operators. Wir addieren im ersten Schritt die beiden Zahlen und dividieren diese anschließend durch zwei. :fontawesome-solid-code:src/lfortran/codegen/asr_to_llvm.cpp
void visit_BinOp(const ASR::BinOp_t &x) {
if (x.m_value) {
this->visit_expr_wrapper(x.m_value, true);
return;
}
this->visit_expr_wrapper(x.m_left, true);
llvm::Value *left_val = tmp;
this->visit_expr_wrapper(x.m_right, true);
llvm::Value *right_val = tmp;
if (x.m_type->type == ASR::ttypeType::Integer ||
x.m_type->type == ASR::ttypeType::IntegerPointer) {
switch (x.m_op) {
case ASR::binopType::Caret: {
tmp = builder->CreateAdd(left_val, right_val);
llvm::Value *two = llvm::ConstantInt::get(context,
llvm::APInt(32, 2, true));
tmp = builder->CreateUDiv(tmp, two);
break;
};
}
}
}
Dieser Abschnitt lässt sich mit lfortran --show-llvm examples/expr2.f90
testen
Wenn LLVM nun funktioniert, können wir die endgültige ausführbare Datei testen, indem wir:
lfortran examples/expr2.f90
./a.out
Und es sollte 6 ausgegeben werden.
Es funktioniert auch interaktiv:
$ lfortran
Interactive Fortran. Experimental prototype, not ready for end users.
* Use Ctrl-D to exit
* Use Enter to submit
* Use Alt-Enter or Ctrl-N to make a new line
- Editing (Keys: Left, Right, Home, End, Backspace, Delete)
- History (Keys: Up, Down)
>>> 4^8 1,4 ]
6
>>> integer :: x 1,13 ]
>>> x = 4 1,6 ]
>>> x^8 1,4 ]
6
Kontakt aufnehmen¶
Wenn du Fragen hast oder Hilfe brauchst, wende dich bitte an unsere Mailinglist oder and den Chat.
Bitte beachte, dass von allen Teilnehmern an diesem Projekt erwartet wird, dass sie unseren Verhaltenskodex befolgen. Mit der Teilnahme an diesem Projekt erklärst du dich damit einverstanden, diese Bedingungen einzuhalten. Siehe CODE_OF_CONDUCT.md.
Durch das Einreichen eines Beitrags stimmst du der Lizenzierung deines Beitrags unter LFortrans BSD Lizenz zu, es sei denn, es ist ausdrücklich anders vermerkt.