Skip to content

Commit

Permalink
done
Browse files Browse the repository at this point in the history
  • Loading branch information
czgdp1807 committed Mar 26, 2024
1 parent 03f6ca9 commit 155ec90
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 14 deletions.
6 changes: 3 additions & 3 deletions src/libasr/ASR.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ stmt
| FileInquire(int label, expr? unit, expr? file, expr? iostat, expr? err, expr? exist, expr? opened, expr? number, expr? named, expr? name, expr? access, expr? sequential, expr? direct, expr? form, expr? formatted, expr? unformatted, expr? recl, expr? nextrec, expr? blank, expr? position, expr? action, expr? read, expr? write, expr? readwrite, expr? delim, expr? pad, expr? flen, expr? blocksize, expr? convert, expr? carriagecontrol, expr? iolength)
| FileWrite(int label, expr? unit, expr? iomsg, expr? iostat, expr? id, expr* values, expr? separator, expr? end, stmt? overloaded)
| Return()
| Select(expr test, case_stmt* body, stmt* default)
| Select(expr test, case_stmt* body, stmt* default, bool enable_fall_through)
| Stop(expr? code)
| Assert(expr test, expr? msg)
| SubroutineCall(symbol name, symbol? original_name, call_arg* args, expr? dt)
Expand Down Expand Up @@ -207,7 +207,7 @@ ttype
| Array(ttype type, dimension* dims, array_physical_type physical_type)
| FunctionType(ttype* arg_types, ttype? return_var_type, abi abi, deftype deftype, string? bindc_name, bool elemental, bool pure, bool module, bool inline, bool static, symbol* restrictions, bool is_restriction)

cast_kind = RealToInteger | IntegerToReal | LogicalToReal | RealToReal | IntegerToInteger | RealToComplex | IntegerToComplex | IntegerToLogical | RealToLogical | CharacterToLogical | CharacterToInteger | CharacterToList | ComplexToLogical | ComplexToComplex | ComplexToReal | ComplexToInteger | LogicalToInteger | RealToCharacter | IntegerToCharacter | LogicalToCharacter | UnsignedIntegerToInteger | UnsignedIntegerToUnsignedInteger | UnsignedIntegerToReal | UnsignedIntegerToLogical | IntegerToUnsignedInteger | RealToUnsignedInteger | CPtrToUnsignedInteger | UnsignedIntegerToCPtr | IntegerToSymbolicExpression
cast_kind = RealToInteger | IntegerToReal | LogicalToReal | RealToReal | IntegerToInteger | RealToComplex | IntegerToComplex | IntegerToLogical | RealToLogical | CharacterToLogical | CharacterToInteger | CharacterToList | ComplexToLogical | ComplexToComplex | ComplexToReal | ComplexToInteger | LogicalToInteger | RealToCharacter | IntegerToCharacter | LogicalToCharacter | UnsignedIntegerToInteger | UnsignedIntegerToUnsignedInteger | UnsignedIntegerToReal | UnsignedIntegerToLogical | IntegerToUnsignedInteger | RealToUnsignedInteger | CPtrToUnsignedInteger | UnsignedIntegerToCPtr | IntegerToSymbolicExpression | ListToArray
storage_type = Default | Save | Parameter
access = Public | Private
intent = Local | In | Out | InOut | ReturnVar | Unspecified
Expand All @@ -222,7 +222,7 @@ call_arg = (expr? value)
tbind = Bind(string lang, string name)
array_index = (expr? left, expr? right, expr? step)
do_loop_head = (expr? v, expr? start, expr? end, expr? increment)
case_stmt = CaseStmt(expr* test, stmt* body) | CaseStmt_Range(expr? start, expr? end, stmt* body)
case_stmt = CaseStmt(expr* test, stmt* body, bool fall_through) | CaseStmt_Range(expr? start, expr? end, stmt* body)
type_stmt = TypeStmtName(symbol sym, stmt* body) | ClassStmt(symbol sym, stmt* body) | TypeStmtType(ttype type, stmt* body)
enumtype = IntegerConsecutiveFromZero | IntegerUnique | IntegerNotUnique | NonInteger
require_instantiation = Require(identifier name, identifier* args)
Expand Down
4 changes: 4 additions & 0 deletions src/libasr/asdl_cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2738,6 +2738,10 @@ def main(argv):
elif subs["MOD"] == "AST":
subs["MOD"] = "LFortran::AST"
subs["lcompiler"] = "lfortran"
elif subs["MOD"] == "LC":
subs["MOD"] = "LC::AST"
subs["mod"] = "ast"
subs["lcompiler"] = "lc"
else:
subs["lcompiler"] = "lfortran"
is_asr = (mod.name.upper() == "ASR")
Expand Down
23 changes: 22 additions & 1 deletion src/libasr/asr_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,20 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
current_symtab = nullptr;
}

void visit_Select(const Select_t& x) {
bool fall_through = false;
for( size_t i = 0; i < x.n_body; i++ ) {
if( ASR::is_a<ASR::CaseStmt_t>(*x.m_body[i]) ) {
ASR::CaseStmt_t* case_stmt_t = ASR::down_cast<ASR::CaseStmt_t>(x.m_body[i]);
fall_through = fall_through || case_stmt_t->m_fall_through;
}
}
require(fall_through == x.m_enable_fall_through,
"Select_t::m_enable_fall_through should be " +
std::to_string(x.m_enable_fall_through));
BaseWalkVisitor<VerifyVisitor>::visit_Select(x);
}

// --------------------------------------------------------
// symbol instances:

Expand Down Expand Up @@ -698,6 +712,7 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
ASR::Module_t *m = ASRUtils::get_sym_module(x.m_external);
ASR::StructType_t* sm = nullptr;
ASR::EnumType_t* em = nullptr;
ASR::UnionType_t* um = nullptr;
ASR::Function_t* fm = nullptr;
bool is_valid_owner = false;
is_valid_owner = m != nullptr && ((ASR::symbol_t*) m == ASRUtils::get_asr_owner(x.m_external));
Expand All @@ -706,13 +721,17 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
ASR::symbol_t* asr_owner_sym = ASRUtils::get_asr_owner(x.m_external);
is_valid_owner = (ASR::is_a<ASR::StructType_t>(*asr_owner_sym) ||
ASR::is_a<ASR::EnumType_t>(*asr_owner_sym) ||
ASR::is_a<ASR::Function_t>(*asr_owner_sym));
ASR::is_a<ASR::Function_t>(*asr_owner_sym) ||
ASR::is_a<ASR::UnionType_t>(*asr_owner_sym));
if( ASR::is_a<ASR::StructType_t>(*asr_owner_sym) ) {
sm = ASR::down_cast<ASR::StructType_t>(asr_owner_sym);
asr_owner_name = sm->m_name;
} else if( ASR::is_a<ASR::EnumType_t>(*asr_owner_sym) ) {
em = ASR::down_cast<ASR::EnumType_t>(asr_owner_sym);
asr_owner_name = em->m_name;
} else if( ASR::is_a<ASR::UnionType_t>(*asr_owner_sym) ) {
um = ASR::down_cast<ASR::UnionType_t>(asr_owner_sym);
asr_owner_name = um->m_name;
} else if( ASR::is_a<ASR::Function_t>(*asr_owner_sym) ) {
fm = ASR::down_cast<ASR::Function_t>(asr_owner_sym);
asr_owner_name = fm->m_name;
Expand Down Expand Up @@ -741,6 +760,8 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
s = em->m_symtab->resolve_symbol(std::string(x.m_original_name));
} else if( fm ) {
s = fm->m_symtab->resolve_symbol(std::string(x.m_original_name));
} else if( um ) {
s = um->m_symtab->resolve_symbol(std::string(x.m_original_name));
}
require(s != nullptr,
"ExternalSymbol::m_original_name ('"
Expand Down
15 changes: 11 additions & 4 deletions src/libasr/casting_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace LCompilers::CastingUtil {
int get_src_dest(ASR::expr_t* left_expr, ASR::expr_t* right_expr,
ASR::expr_t*& src_expr, ASR::expr_t*& dest_expr,
ASR::ttype_t*& src_type, ASR::ttype_t*& dest_type,
bool is_assign) {
bool is_assign, bool allow_int_to_float) {
ASR::ttype_t* left_type = ASRUtils::expr_type(left_expr);
ASR::ttype_t* right_type = ASRUtils::expr_type(right_expr);
if( ASR::is_a<ASR::Const_t>(*left_type) ) {
Expand All @@ -71,7 +71,8 @@ namespace LCompilers::CastingUtil {
return 2;
}
if( is_assign ) {
if( ASRUtils::is_real(*left_type) && ASRUtils::is_integer(*right_type)) {
if( ASRUtils::is_real(*left_type) && ASRUtils::is_integer(*right_type) &&
!allow_int_to_float) {
throw LCompilersException("Assigning integer to float is not supported");
}
if ( ASRUtils::is_complex(*left_type) && !ASRUtils::is_complex(*right_type)) {
Expand Down Expand Up @@ -139,7 +140,13 @@ namespace LCompilers::CastingUtil {
return expr;
}
// TODO: Fix loc
return ASRUtils::EXPR(ASRUtils::make_Cast_t_value(al, loc, expr,
cast_kind, dest));
if( ASRUtils::is_array(src) ) {
ASR::dimension_t* m_dims = nullptr;
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(src, m_dims);
dest = ASRUtils::make_Array_t_util(al, loc, ASRUtils::extract_type(dest), m_dims, n_dims);
} else {
dest = ASRUtils::extract_type(dest);
}
return ASRUtils::EXPR(ASRUtils::make_Cast_t_value(al, loc, expr, cast_kind, dest));
}
}
2 changes: 1 addition & 1 deletion src/libasr/casting_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace LCompilers::CastingUtil {
int get_src_dest(ASR::expr_t* left_expr, ASR::expr_t* right_expr,
ASR::expr_t*& src_expr, ASR::expr_t*& dest_expr,
ASR::ttype_t*& src_type, ASR::ttype_t*& dest_type,
bool is_assign);
bool is_assign, bool allow_int_to_float=false);

ASR::expr_t* perform_casting(ASR::expr_t* expr, ASR::ttype_t* dest,
Allocator& al, const Location& loc);
Expand Down
2 changes: 1 addition & 1 deletion src/libasr/codegen/llvm_array_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ namespace LCompilers {
uint64_t size = data_layout.getTypeAllocSize(llvm_data_type);
llvm::Value* llvm_size = llvm::ConstantInt::get(context, llvm::APInt(32, size));
num_elements = builder->CreateMul(num_elements, llvm_size);
builder->CreateMemCpy(dest, llvm::MaybeAlign(), src, llvm::MaybeAlign(), num_elements);
builder->CreateMemCpy(src, llvm::MaybeAlign(), dest, llvm::MaybeAlign(), num_elements);
}

} // LLVMArrUtils
Expand Down
7 changes: 4 additions & 3 deletions src/libasr/compiler_tester/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def run_test(testname, basename, cmd, infile, update_reference=False,
log.debug(s + " " + check())


def tester_main(compiler, single_test):
def tester_main(compiler, single_test, is_lcompilers_executable_installed=False):
parser = argparse.ArgumentParser(description=f"{compiler} Test Suite")
parser.add_argument("-u", "--update", action="store_true",
help="update all reference results")
Expand Down Expand Up @@ -416,8 +416,9 @@ def tester_main(compiler, single_test):
no_color = args.no_color

# So that the tests find the `lcompiler` executable
os.environ["PATH"] = os.path.join(SRC_DIR, "bin") \
+ os.pathsep + os.environ["PATH"]
if not is_lcompilers_executable_installed:
os.environ["PATH"] = os.path.join(SRC_DIR, "bin") \
+ os.pathsep + os.environ["PATH"]
test_data = toml.load(open(os.path.join(ROOT_DIR, "tests", "tests.toml")))
filtered_tests = test_data["test"]
if specific_tests:
Expand Down
69 changes: 68 additions & 1 deletion src/libasr/pass/select_case.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,69 @@ Vec<ASR::stmt_t*> replace_selectcase(Allocator &al, const ASR::Select_t &select_
return body;
}

void case_to_if_with_fall_through(Allocator& al, const ASR::Select_t& x,
ASR::expr_t* a_test, Vec<ASR::stmt_t*>& body, SymbolTable* scope) {
body.reserve(al, x.n_body + 1);
const Location& loc = x.base.base.loc;
ASR::symbol_t* case_found_sym = ASR::down_cast<ASR::symbol_t>(ASR::make_Variable_t(
al, loc, scope, s2c(al, scope->get_unique_name("case_found")), nullptr, 0,
ASR::intentType::Local, nullptr, nullptr, ASR::storage_typeType::Default,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr, ASR::abiType::Source,
ASR::accessType::Public, ASR::presenceType::Required, false));
scope->add_symbol(scope->get_unique_name("case_found"), case_found_sym);
ASR::expr_t* true_asr = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, loc, true,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4))));
ASR::expr_t* false_asr = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, loc, false,
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4))));
ASR::expr_t* case_found = ASRUtils::EXPR(ASR::make_Var_t(al, loc, case_found_sym));
body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(al, loc, case_found, false_asr, nullptr)));
int label_id = ASRUtils::LabelGenerator::get_instance()->get_unique_label();
for( int idx = 0; idx < x.n_body; idx++ ) {
ASR::case_stmt_t* case_body = x.m_body[idx];
switch(case_body->type) {
case ASR::case_stmtType::CaseStmt: {
ASR::CaseStmt_t* Case_Stmt = ASR::down_cast<ASR::CaseStmt_t>(case_body);
ASR::expr_t* test_expr = gen_test_expr_CaseStmt(al, loc, Case_Stmt, a_test);
test_expr = ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, test_expr,
ASR::logicalbinopType::Or, case_found, ASRUtils::expr_type(case_found), nullptr));
Vec<ASR::stmt_t*> case_body; case_body.reserve(al, Case_Stmt->n_body);
case_body.from_pointer_n(Case_Stmt->m_body, Case_Stmt->n_body);
case_body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(
al, loc, case_found, true_asr, nullptr)));
if( !Case_Stmt->m_fall_through ) {
case_body.push_back(al, ASRUtils::STMT(ASR::make_GoTo_t(al, loc,
label_id, s2c(al, scope->get_unique_name("switch_case_label")))));
}
body.push_back(al, ASRUtils::STMT(ASR::make_If_t(al, loc,
test_expr, case_body.p, case_body.size(), nullptr, 0)));
break;
}
case ASR::case_stmtType::CaseStmt_Range: {
LCOMPILERS_ASSERT(false);
break;
}
}
}
for( int id = 0; id < x.n_default; id++ ) {
body.push_back(al, x.m_default[id]);
}
SymbolTable* block_symbol_table = al.make_new<SymbolTable>(scope);
ASR::symbol_t* empty_block = ASR::down_cast<ASR::symbol_t>(ASR::make_Block_t(
al, loc, block_symbol_table, s2c(al, scope->get_unique_name("switch_case_label")),
nullptr, 0));
scope->add_symbol(scope->get_unique_name("switch_case_label"), empty_block);
body.push_back(al, ASRUtils::STMT(ASR::make_BlockCall_t(al, loc, label_id, empty_block)));
}

Vec<ASR::stmt_t*> replace_selectcase_with_fall_through(
Allocator &al, const ASR::Select_t &select_case,
SymbolTable* scope) {
ASR::expr_t *a = select_case.m_test;
Vec<ASR::stmt_t*> body;
case_to_if_with_fall_through(al, select_case, a, body, scope);
return body;
}

class SelectCaseVisitor : public PassUtils::PassVisitor<SelectCaseVisitor>
{

Expand All @@ -165,7 +228,11 @@ class SelectCaseVisitor : public PassUtils::PassVisitor<SelectCaseVisitor>
}

void visit_Select(const ASR::Select_t &x) {
pass_result = replace_selectcase(al, x);
if( x.m_enable_fall_through ) {
pass_result = replace_selectcase_with_fall_through(al, x, current_scope);
} else {
pass_result = replace_selectcase(al, x);
}
}
};

Expand Down
2 changes: 2 additions & 0 deletions src/libasr/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ struct PassOptions {
};

struct CompilerOptions {
std::vector<std::string> runtime_linker_paths;

// TODO: Convert to std::filesystem::path (also change find_and_load_module())
PassOptions po;

Expand Down

0 comments on commit 155ec90

Please sign in to comment.