Skip to content

Commit 155ec90

Browse files
committed
done
1 parent 03f6ca9 commit 155ec90

File tree

9 files changed

+116
-14
lines changed

9 files changed

+116
-14
lines changed

src/libasr/ASR.asdl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ stmt
5353
| 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)
5454
| FileWrite(int label, expr? unit, expr? iomsg, expr? iostat, expr? id, expr* values, expr? separator, expr? end, stmt? overloaded)
5555
| Return()
56-
| Select(expr test, case_stmt* body, stmt* default)
56+
| Select(expr test, case_stmt* body, stmt* default, bool enable_fall_through)
5757
| Stop(expr? code)
5858
| Assert(expr test, expr? msg)
5959
| SubroutineCall(symbol name, symbol? original_name, call_arg* args, expr? dt)
@@ -207,7 +207,7 @@ ttype
207207
| Array(ttype type, dimension* dims, array_physical_type physical_type)
208208
| 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)
209209

210-
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
210+
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
211211
storage_type = Default | Save | Parameter
212212
access = Public | Private
213213
intent = Local | In | Out | InOut | ReturnVar | Unspecified
@@ -222,7 +222,7 @@ call_arg = (expr? value)
222222
tbind = Bind(string lang, string name)
223223
array_index = (expr? left, expr? right, expr? step)
224224
do_loop_head = (expr? v, expr? start, expr? end, expr? increment)
225-
case_stmt = CaseStmt(expr* test, stmt* body) | CaseStmt_Range(expr? start, expr? end, stmt* body)
225+
case_stmt = CaseStmt(expr* test, stmt* body, bool fall_through) | CaseStmt_Range(expr? start, expr? end, stmt* body)
226226
type_stmt = TypeStmtName(symbol sym, stmt* body) | ClassStmt(symbol sym, stmt* body) | TypeStmtType(ttype type, stmt* body)
227227
enumtype = IntegerConsecutiveFromZero | IntegerUnique | IntegerNotUnique | NonInteger
228228
require_instantiation = Require(identifier name, identifier* args)

src/libasr/asdl_cpp.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,6 +2738,10 @@ def main(argv):
27382738
elif subs["MOD"] == "AST":
27392739
subs["MOD"] = "LFortran::AST"
27402740
subs["lcompiler"] = "lfortran"
2741+
elif subs["MOD"] == "LC":
2742+
subs["MOD"] = "LC::AST"
2743+
subs["mod"] = "ast"
2744+
subs["lcompiler"] = "lc"
27412745
else:
27422746
subs["lcompiler"] = "lfortran"
27432747
is_asr = (mod.name.upper() == "ASR")

src/libasr/asr_verify.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
124124
current_symtab = nullptr;
125125
}
126126

127+
void visit_Select(const Select_t& x) {
128+
bool fall_through = false;
129+
for( size_t i = 0; i < x.n_body; i++ ) {
130+
if( ASR::is_a<ASR::CaseStmt_t>(*x.m_body[i]) ) {
131+
ASR::CaseStmt_t* case_stmt_t = ASR::down_cast<ASR::CaseStmt_t>(x.m_body[i]);
132+
fall_through = fall_through || case_stmt_t->m_fall_through;
133+
}
134+
}
135+
require(fall_through == x.m_enable_fall_through,
136+
"Select_t::m_enable_fall_through should be " +
137+
std::to_string(x.m_enable_fall_through));
138+
BaseWalkVisitor<VerifyVisitor>::visit_Select(x);
139+
}
140+
127141
// --------------------------------------------------------
128142
// symbol instances:
129143

@@ -698,6 +712,7 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
698712
ASR::Module_t *m = ASRUtils::get_sym_module(x.m_external);
699713
ASR::StructType_t* sm = nullptr;
700714
ASR::EnumType_t* em = nullptr;
715+
ASR::UnionType_t* um = nullptr;
701716
ASR::Function_t* fm = nullptr;
702717
bool is_valid_owner = false;
703718
is_valid_owner = m != nullptr && ((ASR::symbol_t*) m == ASRUtils::get_asr_owner(x.m_external));
@@ -706,13 +721,17 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
706721
ASR::symbol_t* asr_owner_sym = ASRUtils::get_asr_owner(x.m_external);
707722
is_valid_owner = (ASR::is_a<ASR::StructType_t>(*asr_owner_sym) ||
708723
ASR::is_a<ASR::EnumType_t>(*asr_owner_sym) ||
709-
ASR::is_a<ASR::Function_t>(*asr_owner_sym));
724+
ASR::is_a<ASR::Function_t>(*asr_owner_sym) ||
725+
ASR::is_a<ASR::UnionType_t>(*asr_owner_sym));
710726
if( ASR::is_a<ASR::StructType_t>(*asr_owner_sym) ) {
711727
sm = ASR::down_cast<ASR::StructType_t>(asr_owner_sym);
712728
asr_owner_name = sm->m_name;
713729
} else if( ASR::is_a<ASR::EnumType_t>(*asr_owner_sym) ) {
714730
em = ASR::down_cast<ASR::EnumType_t>(asr_owner_sym);
715731
asr_owner_name = em->m_name;
732+
} else if( ASR::is_a<ASR::UnionType_t>(*asr_owner_sym) ) {
733+
um = ASR::down_cast<ASR::UnionType_t>(asr_owner_sym);
734+
asr_owner_name = um->m_name;
716735
} else if( ASR::is_a<ASR::Function_t>(*asr_owner_sym) ) {
717736
fm = ASR::down_cast<ASR::Function_t>(asr_owner_sym);
718737
asr_owner_name = fm->m_name;
@@ -741,6 +760,8 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
741760
s = em->m_symtab->resolve_symbol(std::string(x.m_original_name));
742761
} else if( fm ) {
743762
s = fm->m_symtab->resolve_symbol(std::string(x.m_original_name));
763+
} else if( um ) {
764+
s = um->m_symtab->resolve_symbol(std::string(x.m_original_name));
744765
}
745766
require(s != nullptr,
746767
"ExternalSymbol::m_original_name ('"

src/libasr/casting_utils.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ namespace LCompilers::CastingUtil {
5555
int get_src_dest(ASR::expr_t* left_expr, ASR::expr_t* right_expr,
5656
ASR::expr_t*& src_expr, ASR::expr_t*& dest_expr,
5757
ASR::ttype_t*& src_type, ASR::ttype_t*& dest_type,
58-
bool is_assign) {
58+
bool is_assign, bool allow_int_to_float) {
5959
ASR::ttype_t* left_type = ASRUtils::expr_type(left_expr);
6060
ASR::ttype_t* right_type = ASRUtils::expr_type(right_expr);
6161
if( ASR::is_a<ASR::Const_t>(*left_type) ) {
@@ -71,7 +71,8 @@ namespace LCompilers::CastingUtil {
7171
return 2;
7272
}
7373
if( is_assign ) {
74-
if( ASRUtils::is_real(*left_type) && ASRUtils::is_integer(*right_type)) {
74+
if( ASRUtils::is_real(*left_type) && ASRUtils::is_integer(*right_type) &&
75+
!allow_int_to_float) {
7576
throw LCompilersException("Assigning integer to float is not supported");
7677
}
7778
if ( ASRUtils::is_complex(*left_type) && !ASRUtils::is_complex(*right_type)) {
@@ -139,7 +140,13 @@ namespace LCompilers::CastingUtil {
139140
return expr;
140141
}
141142
// TODO: Fix loc
142-
return ASRUtils::EXPR(ASRUtils::make_Cast_t_value(al, loc, expr,
143-
cast_kind, dest));
143+
if( ASRUtils::is_array(src) ) {
144+
ASR::dimension_t* m_dims = nullptr;
145+
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(src, m_dims);
146+
dest = ASRUtils::make_Array_t_util(al, loc, ASRUtils::extract_type(dest), m_dims, n_dims);
147+
} else {
148+
dest = ASRUtils::extract_type(dest);
149+
}
150+
return ASRUtils::EXPR(ASRUtils::make_Cast_t_value(al, loc, expr, cast_kind, dest));
144151
}
145152
}

src/libasr/casting_utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace LCompilers::CastingUtil {
1313
int get_src_dest(ASR::expr_t* left_expr, ASR::expr_t* right_expr,
1414
ASR::expr_t*& src_expr, ASR::expr_t*& dest_expr,
1515
ASR::ttype_t*& src_type, ASR::ttype_t*& dest_type,
16-
bool is_assign);
16+
bool is_assign, bool allow_int_to_float=false);
1717

1818
ASR::expr_t* perform_casting(ASR::expr_t* expr, ASR::ttype_t* dest,
1919
Allocator& al, const Location& loc);

src/libasr/codegen/llvm_array_utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ namespace LCompilers {
874874
uint64_t size = data_layout.getTypeAllocSize(llvm_data_type);
875875
llvm::Value* llvm_size = llvm::ConstantInt::get(context, llvm::APInt(32, size));
876876
num_elements = builder->CreateMul(num_elements, llvm_size);
877-
builder->CreateMemCpy(dest, llvm::MaybeAlign(), src, llvm::MaybeAlign(), num_elements);
877+
builder->CreateMemCpy(src, llvm::MaybeAlign(), dest, llvm::MaybeAlign(), num_elements);
878878
}
879879

880880
} // LLVMArrUtils

src/libasr/compiler_tester/tester.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ def run_test(testname, basename, cmd, infile, update_reference=False,
362362
log.debug(s + " " + check())
363363

364364

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

418418
# So that the tests find the `lcompiler` executable
419-
os.environ["PATH"] = os.path.join(SRC_DIR, "bin") \
420-
+ os.pathsep + os.environ["PATH"]
419+
if not is_lcompilers_executable_installed:
420+
os.environ["PATH"] = os.path.join(SRC_DIR, "bin") \
421+
+ os.pathsep + os.environ["PATH"]
421422
test_data = toml.load(open(os.path.join(ROOT_DIR, "tests", "tests.toml")))
422423
filtered_tests = test_data["test"]
423424
if specific_tests:

src/libasr/pass/select_case.cpp

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,69 @@ Vec<ASR::stmt_t*> replace_selectcase(Allocator &al, const ASR::Select_t &select_
150150
return body;
151151
}
152152

153+
void case_to_if_with_fall_through(Allocator& al, const ASR::Select_t& x,
154+
ASR::expr_t* a_test, Vec<ASR::stmt_t*>& body, SymbolTable* scope) {
155+
body.reserve(al, x.n_body + 1);
156+
const Location& loc = x.base.base.loc;
157+
ASR::symbol_t* case_found_sym = ASR::down_cast<ASR::symbol_t>(ASR::make_Variable_t(
158+
al, loc, scope, s2c(al, scope->get_unique_name("case_found")), nullptr, 0,
159+
ASR::intentType::Local, nullptr, nullptr, ASR::storage_typeType::Default,
160+
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr, ASR::abiType::Source,
161+
ASR::accessType::Public, ASR::presenceType::Required, false));
162+
scope->add_symbol(scope->get_unique_name("case_found"), case_found_sym);
163+
ASR::expr_t* true_asr = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, loc, true,
164+
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4))));
165+
ASR::expr_t* false_asr = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, loc, false,
166+
ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4))));
167+
ASR::expr_t* case_found = ASRUtils::EXPR(ASR::make_Var_t(al, loc, case_found_sym));
168+
body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(al, loc, case_found, false_asr, nullptr)));
169+
int label_id = ASRUtils::LabelGenerator::get_instance()->get_unique_label();
170+
for( int idx = 0; idx < x.n_body; idx++ ) {
171+
ASR::case_stmt_t* case_body = x.m_body[idx];
172+
switch(case_body->type) {
173+
case ASR::case_stmtType::CaseStmt: {
174+
ASR::CaseStmt_t* Case_Stmt = ASR::down_cast<ASR::CaseStmt_t>(case_body);
175+
ASR::expr_t* test_expr = gen_test_expr_CaseStmt(al, loc, Case_Stmt, a_test);
176+
test_expr = ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, test_expr,
177+
ASR::logicalbinopType::Or, case_found, ASRUtils::expr_type(case_found), nullptr));
178+
Vec<ASR::stmt_t*> case_body; case_body.reserve(al, Case_Stmt->n_body);
179+
case_body.from_pointer_n(Case_Stmt->m_body, Case_Stmt->n_body);
180+
case_body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(
181+
al, loc, case_found, true_asr, nullptr)));
182+
if( !Case_Stmt->m_fall_through ) {
183+
case_body.push_back(al, ASRUtils::STMT(ASR::make_GoTo_t(al, loc,
184+
label_id, s2c(al, scope->get_unique_name("switch_case_label")))));
185+
}
186+
body.push_back(al, ASRUtils::STMT(ASR::make_If_t(al, loc,
187+
test_expr, case_body.p, case_body.size(), nullptr, 0)));
188+
break;
189+
}
190+
case ASR::case_stmtType::CaseStmt_Range: {
191+
LCOMPILERS_ASSERT(false);
192+
break;
193+
}
194+
}
195+
}
196+
for( int id = 0; id < x.n_default; id++ ) {
197+
body.push_back(al, x.m_default[id]);
198+
}
199+
SymbolTable* block_symbol_table = al.make_new<SymbolTable>(scope);
200+
ASR::symbol_t* empty_block = ASR::down_cast<ASR::symbol_t>(ASR::make_Block_t(
201+
al, loc, block_symbol_table, s2c(al, scope->get_unique_name("switch_case_label")),
202+
nullptr, 0));
203+
scope->add_symbol(scope->get_unique_name("switch_case_label"), empty_block);
204+
body.push_back(al, ASRUtils::STMT(ASR::make_BlockCall_t(al, loc, label_id, empty_block)));
205+
}
206+
207+
Vec<ASR::stmt_t*> replace_selectcase_with_fall_through(
208+
Allocator &al, const ASR::Select_t &select_case,
209+
SymbolTable* scope) {
210+
ASR::expr_t *a = select_case.m_test;
211+
Vec<ASR::stmt_t*> body;
212+
case_to_if_with_fall_through(al, select_case, a, body, scope);
213+
return body;
214+
}
215+
153216
class SelectCaseVisitor : public PassUtils::PassVisitor<SelectCaseVisitor>
154217
{
155218

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

167230
void visit_Select(const ASR::Select_t &x) {
168-
pass_result = replace_selectcase(al, x);
231+
if( x.m_enable_fall_through ) {
232+
pass_result = replace_selectcase_with_fall_through(al, x, current_scope);
233+
} else {
234+
pass_result = replace_selectcase(al, x);
235+
}
169236
}
170237
};
171238

src/libasr/utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ struct PassOptions {
6161
};
6262

6363
struct CompilerOptions {
64+
std::vector<std::string> runtime_linker_paths;
65+
6466
// TODO: Convert to std::filesystem::path (also change find_and_load_module())
6567
PassOptions po;
6668

0 commit comments

Comments
 (0)