Contribuindo¶
Aceitamos contribuições de qualquer pessoa, mesmo se você é novo(a) ao mundo do código fonte aberto. Pode parecer assustador contribuir com um compilador logo no início, mas por favor o faça, não é complicado. Vamos te ajudar com qualquer problema técnico e ajudar com sua contribuição até que esta seja implementada.
Configuração Básica¶
Para contribuir, certifique-se de sua configuração:
Seu nome de usuário + e-mail
Seu
~/.gitconfig
Seu prompt de shell para exibir o nome atual do branch
Fork o LFortran¶
Passo 1. Crie um fork do repositório do projeto
Passo 2. Configure sua chave SSH no GitHub
Passo 3. Clone o repositório do projeto a partir do GitHub e configure seu 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
é o nome do seu repositório remoto e pode ser qualquer nome que você queira, por exemplo seu primeiro nome.
:fontawesome-solid-edit: YOUR_GITHUB_ID
é a sua identificação de usuário no GitHub e deve ser parte do caminho da sua conta.
Você pode usar git remote -v
para checar se o novo repositório está configurado corretamente.
Envie uma nova requisição de Merge¶
Passo 1. Crie um novo ramo
git checkout -b fix1
Passo 3. Faça mudanças no(s) ficheiro(s) relevante(s)
Passo 3. Realize o commit de suas mudanças:
git add FILE1 (FILE2 ...)
git commit -m "YOUR_COMMIT_MESSAGE"
Veja aqui algumas dicas excelentes sobre como escrever boas mensagens de commit.
Passo 4. Se assegure de que suas mudanças estão boas
git log --pretty=oneline --graph --decorate --all
Passo 5. Envie o pedido de merge
git push REMOTE_NAME fix1
O comando irá enviar o novo ramo fix1
para o seu repositório remoto REMOTE_NAME
que você criou anteriormente. Além disso, será mostrado um link que você pode clicar para abrir o novo pedido de merge. Após clicar no link, escreva um título com uma descrição breve e clique em no botão «Create». Uhull! Agora está tudo pronto.
Adicionar Novos Recursos¶
O exemplo abaixo mostra os passos que seriam necessários para criar o operador binário ^ que calcula o valor médio dos dois operandos.
Crie Novos Tokens¶
Estendemos o tokenizer.re bem como o parser.yy de modo a adicionar o novo token ^. Também dizemos ao LFortran como ele deve mostrar na tela o novo token no arquivo 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, "^")
}
}
O código adicionado é testado com o comando lfortran --show-tokens examples2/expr2.f90
Realize o Parsing do Novo Token¶
Agora temos que fazer o parsing do novo operador. Adicionamo-lo à AST ao extender o BinOp com o operador «chapéu» ao modificar o ficheiro AST.asdl. Então, colocamos-o no parse.yy para realizar o parsing apropriadamente e gerar a nova AST em semantics.h. Por fim, estendemos o ficheiro pickle.cpp para que o novo operador possa ser mostrado.
: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
}
Esta seção é testada usando o comando lfortran --show-ast examples/expr2.f90
Implementar a Semântica do Novo Token¶
Primeiro estendemos a ASR em ASR.asdl e adicionamos o «^» como um operador do tipo 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;
}
}
}
}
}
}
Então, transformamos da AST para a ASR editando o arquivo src/lfortran/semantics/ast_common_visitor.h.
Também o adicionamos para avaliação de expressões em tempo de compilação como e = (2+3)^5
que é calculado em tempo de compilação. Uma expressão como e = x^5
é calculada apenas em tempo de execução.
A seção é testada com lfortran --show-asr examples/expr2.f90
Implemente o Novo Token no LLVM¶
Para implementá-lo no LLVM estendemos a tradução da BinOp (operação binária) para o novo operador. Primeiro adicionamos os dois números e depois dividimos por dois. :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;
};
}
}
}
Esta seção é testada usando lfortran --show-llvm examples/expr2.f90
Agora que o LLVM funciona, podemos finalmente testar o executável usando:
lfortran examples/expr2.f90
./a.out
O que deve mostrar na tela 6.
Também funciona interativamente:
$ 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
Entre em contato¶
Se você tiver alguma dúvida ou precisa de ajuda, por favor pergunte na nossa lista de e-mail ou no chat.
Por favor, note que todos os participantes deste projeto devem seguir nosso Código de Conduta. Ao participar deste projeto, você concorda em cumprir seus termos. Consulte CODE_OF_CONDUCT.md.
Ao enviar um PR, você concorda em licenciar sua contribuição sob a licença BSD da LFortran, menos nos casos em que é explicitamente dito o contrário.