贡献¶
我们欢迎任何人的贡献,即使你是开源新手。起初为编译器做贡献可能听起来令人生畏,但可以尝试去做,这并不复杂。我们将帮助你解决任何技术问题并帮助改进你的贡献,以便将其合并。
基本设置¶
要做出贡献,请确保你的设置:
你的用户名 + 电子邮件
你的
~/.gitconfig
你的 shell 提示显示当前分支名称
拉取分叉 LFortran¶
步骤 1. 创建 项目存储库 的分支
步骤 2. 使用 GitHub 设置你的 SSH 密钥
步骤 3. 从 GitHub 克隆项目存储库并设置你的远程存储库
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
是你的远程仓库的名字,可以是你喜欢的任何名字,例如你的名字。
:fontawesome-solid-edit: YOUR_GITHUB_ID
是你在 GitHub 上的用户 ID,应该是你帐户路径的一部分。
你可以使用 git remote -v
检查新远程地址是否设置正确。
发送新的合并请求¶
步骤 1. 创建一个新分支
git checkout -b fix1
步骤 2. 更改相关文件
步骤 3. 提交更改:
git add FILE1 (FILE2 ...)
git commit -m "YOUR_COMMIT_MESSAGE"
这里 是一些关于编写好的提交消息的好技巧。
第 4 步:检查以确保你的更改看起来不错
git log --pretty=oneline --graph --decorate --all
步骤 5. 发送合并请求
git push REMOTE_NAME fix1
该命令会将新分支 fix1
推送到您之前创建的远程存储库 REMOTE_NAME
中。此外,它还将显示一个链接,你可以单击该链接以打开新的合并请求。单击链接后,写下标题和简明描述,然后单击 创建
按钮。是的,你现在一切就绪。
添加新功能¶
下面的示例显示了创建插入符号二元运算符 ^ 所需的步骤,该运算符计算两个操作数的平均值。
创建新令牌¶
我们扩展了 tokenizer.re 和 parser.yy 以添加新的令牌 ^。我们还告诉 LFortran 如何在 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, "^")
}
}
添加的代码使用 lfortran --show-tokens examples2/expr2.f90
进行测试
解析新令牌¶
现在我们必须解析 new 运算符。我们通过使用插入符运算符扩展 BinOp 并修改 AST.asdl 文件将其添加到 AST。然后我们将它添加到 parse.yy 中以正确解析并在 semantics.h 中生成新的 AST。最后我们扩展 pickle.cpp 以便新的操作符可以打印自己。
: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
}
该部分使用 lfortran --show-ast examples/expr2.f90
进行测试
实现新令牌的语义¶
我们首先在 ASR.asdl 中扩展 ASR,并添加 ^ 作为 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;
}
}
}
}
}
}
然后我们通过扩展 src/lfortran/semantics/ast_common_visitor.h 将其从 AST 转换为 ASR。
我们还将它添加到由表达式触发的编译时评估中,例如在编译时评估的 e = (2+3)^5
。诸如e = x^5
之类的表达式仅在运行时进行评估。
该部分使用 lfortran --show-asr examples/expr2.f90
进行测试
在 LLVM 中实现新令牌¶
为了在 LLVM 中实现,我们通过处理 new 运算符来扩展 BinOp 转换。我们首先将两个数字相加,然后除以 2。 :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;
};
}
}
}
该部分使用 lfortran --show-llvm examples/expr2.f90
进行测试
现在当 LLVM 工作时,我们可以通过以下方式测试最终的可执行文件:
lfortran examples/expr2.f90
./a.out
它应该打印 6。
它还可以交互工作:
$ 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
得到¶
如果你有任何问题或需要帮助,请通过我们的 mailinglist 或 chat 提问。
请注意,该项目的所有参与者都应遵守我们的行为准则。参与本项目即表示你同意遵守其条款。请参阅 CODE_OF_CONDUCT.md。
通过提交 PR,你同意根据 LFortran 的 BSD 许可 许可你的贡献,除非另有明确说明。