Contribuyendo¶
Damos la bienvenida a todas las contribuciones, aún si usted es nuevo en código abierto. Al principio, puede parecer abrumador contribuir a un compilador, pero hágalo, no es complicado. Ayudaremos con cualquier problema técnico, así como a mejorar su contribución para que esta pueda integrarse.
Configuración básica¶
Para contribuir, asegúrese de configurar:
Su nombre de usuario + correo electrónico
Su
~/.gitconfig
Su indicador de interfaz para mostrar el nombre de la rama actual
Bifurcar LFortran¶
Paso 1. Crear una bifurcación del repositorio del proyecto
Paso 2. Configure su clave SSH con GitHub
Paso 3. Clone el repositório del proyecto desde Github y configure su repositório remoto
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
es el nombre de su repositório remoto y puede ser cualquier nombre de su elección, por ejemplo su primer nombre.
:fontawesome-solid-edit: YOUR_GITHUB_ID
es su identificador de usuario en Github y debe ser parte de la ruta de su cuenta.
Usted puede usar git remote -v
para verificar si el nuevo enlace remoto está correctamente configurado.
Enviar una nueva solicitud de fusión¶
Paso 1. Crear una nueva rama
git checkout -b fix1
Paso 2. Realizar cambios en archivos relevantes
Paso 3. Confirmar los cambios:
git add FILE1 (FILE2 ...)
git commit -m "YOUR_COMMIT_MESSAGE"
Aquí algunos consejos sobre como escribir buenos mensajes de confirmación.
Paso 4. Verifique que sus cambios se vean bien
git log --pretty=oneline --graph --decorate --all
Paso 5. Enviar la solicitud de fusión
git push REMOTE_NAME fix1
El comando insertará la nueva rama fix1
en su repositorio remoto REMOTE_NAME
que creó anteriormente. Además, también mostrará un enlace en el que puede hacer clic para abrir la nueva solicitud de fusión. Después de hacer clic en el enlace, escriba un título y una descripción concisa y luego haga clic en el botón «Create». Sí, ya está todo listo.
Adicionar nuevas características¶
El siguiente ejemplo muestra los pasos necesarios para crear un operador binario de intercalación ^ que calcula el valor promedio de los dos operandos.
Crear un nuevo identificador¶
Extendemos el tokenizer.re así como el parser.yy para adcionar el nuevo indentificador ^. También le decimos a LFortran como imprimir el nuevo identificador en parser.cpp.
: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, "^")
}
}
El código adicionado es evaluado con lfortran --show-tokens examples2/expr2.f90
Analizar el nuevo identificador¶
Ahora tenemos que analizar el nuevo operador. Lo agregamos al AST extendiendo BinOp con un operador de intercalación y modificando el archivo AST.asdl. Luego lo agregamos en parse.yy para analizar correctamente y generar el nuevo AST en semantics.h. Finalmente, extendemos pickle.cpp para que el nuevo operador pueda imprimirse solo.
: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
}
La sección es evaluada con lfortran --show-ast examples/expr2.f90
Implementar todas las semánticas del nuevo identificador¶
Primero extendemos el ASR en ASR.asdl y adicionamos ^ como una opción del operador BinOp.
: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;
}
}
}
}
}
}
Después lo transformamos desde AST para ASR extendiendo src/lfortran/semantics/ast_common_visitor.h.
También lo agregamos a la evaluación en tiempo de compilación desencadenada por expresiones como e = (2+3)^5
, que se evalúa en tiempo de compilación. Una expresión como e = x^5
se evalúa solo en tiempo de ejecución.
La sección es evaluada con lfortran --show-asr examples/expr2.f90
Implementando el nuevo identificador en LLVM¶
Para implementar en LLVM, extendemos la traducción de BinOp manejando el nuevo operador. Primero sumamos los dos números y luego dividimos por dos. :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;
};
}
}
}
La sección es evaluada con lfortran --show-llvm examples/expr2.f90
Ahora, cuando LLVM funciona, podemos probar el ejecutable final:
lfortran examples/expr2.f90
./a.out
Y debería imprimir 6.
También funciona de forma interactiva:
$ 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
Alcanzar¶
Si tiene alguna pregunta o necesita ayuda, pregunte en nuestra lista de correo o un chat.
Tenga en cuenta que se espera que todos los participantes de este proyecto sigan nuestro Código de conducta. Al participar en este proyecto, usted acepta cumplir con sus términos. Ver CODE_OF_CONDUCT.md.
Al enviar un PR, acepta licenciar su contribución bajo la licencia BSD de LFortran, a menos que se indique explícitamente lo contrario.