Skip to content

Commit

Permalink
Merge pull request lcompilers#233 from namannimmo10/type_checking
Browse files Browse the repository at this point in the history
Add strict type checking for assignment
  • Loading branch information
namannimmo10 committed Mar 14, 2022
2 parents 7998ab7 + d26127c commit 6121864
Show file tree
Hide file tree
Showing 29 changed files with 77 additions and 49 deletions.
9 changes: 9 additions & 0 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ static inline std::string type_to_str(const ASR::ttype_t *t)
case ASR::ttypeType::Character: {
return "character";
}
case ASR::ttypeType::Tuple: {
return "tuple";
}
case ASR::ttypeType::Set: {
return "set";
}
case ASR::ttypeType::Dict: {
return "dict";
}
default : throw LFortranException("Not implemented");
}
}
Expand Down
23 changes: 20 additions & 3 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,19 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
tmp = nullptr;
} else {
ASR::expr_t *value = ASRUtils::EXPR(tmp);
if (!ASRUtils::check_equal_type(ASRUtils::expr_type(target),
ASRUtils::expr_type(value))) {
std::string ltype = ASRUtils::type_to_str(ASRUtils::expr_type(target));
std::string rtype = ASRUtils::type_to_str(ASRUtils::expr_type(value));
diag.add(diag::Diagnostic(
"Type mismatch in assignment, the types must be compatible",
diag::Level::Error, diag::Stage::Semantic, {
diag::Label("type mismatch (" + ltype + " and " + rtype + ")",
{target->base.loc, value->base.loc})
})
);
throw SemanticAbort();
}
value = implicitcast_helper(ASRUtils::expr_type(target), value, true);
ASR::stmt_t *overloaded=nullptr;
tmp = ASR::make_Assignment_t(al, x.base.base.loc, target, value,
Expand Down Expand Up @@ -1615,9 +1628,10 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
int64_t op_value = ASR::down_cast<ASR::ConstantInteger_t>(
ASRUtils::expr_value(operand))->m_n;
if (op == ASR::unaryopType::Not) {
bool b = (op_value == 0) ? true : false;
bool b = (op_value == 0);
value = ASR::down_cast<ASR::expr_t>(ASR::make_ConstantLogical_t(
al, x.base.base.loc, b, logical_type));
operand_type = logical_type;
} else {
int64_t result = 0;
switch (op) {
Expand All @@ -1634,9 +1648,10 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
double op_value = ASR::down_cast<ASR::ConstantReal_t>(
ASRUtils::expr_value(operand))->m_r;
if (op == ASR::unaryopType::Not) {
bool b = (op_value == 0.0) ? true : false;
bool b = (op_value == 0.0);
value = ASR::down_cast<ASR::expr_t>(ASR::make_ConstantLogical_t(
al, x.base.base.loc, b, logical_type));
operand_type = logical_type;
} else {
double result = 0.0;
switch (op) {
Expand Down Expand Up @@ -1668,6 +1683,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
}
value = ASR::down_cast<ASR::expr_t>(
ASR::make_ConstantInteger_t(al, x.base.base.loc, result, int_type));
operand_type = int_type;
}

} else if (ASRUtils::is_complex(*operand_type)) {
Expand All @@ -1676,9 +1692,10 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
std::complex<double> op_value(c->m_re, c->m_im);
std::complex<double> result;
if (op == ASR::unaryopType::Not) {
bool b = (op_value.real() == 0.0 && op_value.imag() == 0.0) ? true : false;
bool b = (op_value.real() == 0.0 && op_value.imag() == 0.0);
value = ASR::down_cast<ASR::expr_t>(
ASR::make_ConstantLogical_t(al, x.base.base.loc, b, logical_type));
operand_type = logical_type;
} else {
switch (op) {
case (ASR::unaryopType::UAdd): { result = op_value; break; }
Expand Down
2 changes: 1 addition & 1 deletion tests/constants1.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def test_float():


def test_divmod():
a: i32
a: tuple[i32, i32]
a = divmod(9, 3)
a = divmod(9, -3)
a = divmod(3, 3)
Expand Down
8 changes: 4 additions & 4 deletions tests/dictionary1.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def test_Dict():
y: dict[str, i32]
y = {"a": -1, "b": -2}

z: i32
# this assignment should eventually work
z = x["a"]
z = x["b"]
# z: i32
# # this assignment should eventually work
# z = x["a"]
# z = x["b"]
7 changes: 4 additions & 3 deletions tests/expr10.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ def test_UnaryOp():
a = +4
a = -500
a = ~5
a = not 5
a = not -1
a = not 0
b: bool
b = not 5
b = not -1
b = not 0

f: f32
f = +1.0
Expand Down
2 changes: 1 addition & 1 deletion tests/expr8.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ def test_binop():
x: i32
x2: f32
x = 2**3
x = 2**3.5
x2 = 2**3.5
x = 54 - 100
x2 = (3.454 - 765.43) + 534.6
x2 = 5346.565 * 3.45
Expand Down
4 changes: 2 additions & 2 deletions tests/reference/asr-constants1-5828e8a.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"basename": "asr-constants1-5828e8a",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/constants1.py",
"infile_hash": "6adf0c1cf8ec1667bf19edaf62d087483e6229370ed0f10a207ee0b4",
"infile_hash": "488c771ec7195280a10fa5247d117ac339e0df7f39fa77dfd215619e",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-constants1-5828e8a.stdout",
"stdout_hash": "e868a321ec5699dcdd832b96904338cc235ecc63f02b7d893fb3714d",
"stdout_hash": "c2057db2ba5b67dd8c40824aeb624ce7ea3de67fe1fa43400b297cf3",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/asr-constants1-5828e8a.stdout

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions tests/reference/asr-dictionary1-a105a36.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"basename": "asr-dictionary1-a105a36",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/dictionary1.py",
"infile_hash": "0193140223269d4060d60fc088242809fd5942d391157c54dd0e2e0f",
"infile_hash": "54e129b4452b80bc7be61c0f25ce2d17ffe06784c2b84dfc85a0e4a2",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-dictionary1-a105a36.stdout",
"stdout_hash": "a1b435f14f711aab8b1ac266fdda7fa5379c00680f64506f88359dde",
"stdout_hash": "3225cd5bd1e7c6636c6004695b4934bfa9ee61c667f68d01ee9d699c",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/asr-dictionary1-a105a36.stdout
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_Dict: (Subroutine (SymbolTable 2 {x: (Variable 2 x Local () () Default (Dict (Integer 4 []) (Integer 4 [])) Source Public Required .false.), y: (Variable 2 y Local () () Default (Dict (Character 1 -2 () []) (Integer 4 [])) Source Public Required .false.), z: (Variable 2 z Local () () Default (Integer 4 []) Source Public Required .false.)}) test_Dict [] [(= (Var 2 x) (ConstantDictionary [(ConstantInteger 1 (Integer 4 [])) (ConstantInteger 3 (Integer 4 []))] [(ConstantInteger 2 (Integer 4 [])) (ConstantInteger 4 (Integer 4 []))] (Dict (Integer 4 []) (Integer 4 []))) ()) (= (Var 2 y) (ConstantDictionary [(ConstantString "a" (Character 1 1 () [])) (ConstantString "b" (Character 1 1 () []))] [(UnaryOp USub (ConstantInteger 1 (Integer 4 [])) (Integer 4 []) (ConstantInteger -1 (Integer 4 []))) (UnaryOp USub (ConstantInteger 2 (Integer 4 [])) (Integer 4 []) (ConstantInteger -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (= (Var 2 z) (ArrayRef 2 x [(() (BinOp (ConstantString "a" (Character 1 1 () [])) Add (ConstantInteger 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Dict (Integer 4 []) (Integer 4 [])) ()) ()) (= (Var 2 z) (ArrayRef 2 x [(() (BinOp (ConstantString "b" (Character 1 1 () [])) Add (ConstantInteger 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Dict (Integer 4 []) (Integer 4 [])) ()) ())] Source Public Implementation () .false. .false.)}) [])
(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_Dict: (Subroutine (SymbolTable 2 {x: (Variable 2 x Local () () Default (Dict (Integer 4 []) (Integer 4 [])) Source Public Required .false.), y: (Variable 2 y Local () () Default (Dict (Character 1 -2 () []) (Integer 4 [])) Source Public Required .false.)}) test_Dict [] [(= (Var 2 x) (ConstantDictionary [(ConstantInteger 1 (Integer 4 [])) (ConstantInteger 3 (Integer 4 []))] [(ConstantInteger 2 (Integer 4 [])) (ConstantInteger 4 (Integer 4 []))] (Dict (Integer 4 []) (Integer 4 []))) ()) (= (Var 2 y) (ConstantDictionary [(ConstantString "a" (Character 1 1 () [])) (ConstantString "b" (Character 1 1 () []))] [(UnaryOp USub (ConstantInteger 1 (Integer 4 [])) (Integer 4 []) (ConstantInteger -1 (Integer 4 []))) (UnaryOp USub (ConstantInteger 2 (Integer 4 [])) (Integer 4 []) (ConstantInteger -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ())] Source Public Implementation () .false. .false.)}) [])
4 changes: 2 additions & 2 deletions tests/reference/asr-expr10-efcbb1b.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"basename": "asr-expr10-efcbb1b",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/expr10.py",
"infile_hash": "b49c0f11a3568a0eac16d4998317034b70b81d6be5a597cfada7438c",
"infile_hash": "80c9f3a2b600abc397262dec37c78b74ca3132db7e78c3bbe2214c1f",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-expr10-efcbb1b.stdout",
"stdout_hash": "518a6785039886efd1ec9e0ad5e99c80db038d85f0d377fe74d8e085",
"stdout_hash": "35d921142ec8c2aa5bd5c9a9c43b4c172a0d9907a8b6e457849e3782",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/asr-expr10-efcbb1b.stdout
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_UnaryOp: (Subroutine (SymbolTable 2 {a: (Variable 2 a Local () () Default (Integer 4 []) Source Public Required .false.), b1: (Variable 2 b1 Local () () Default (Logical 1 []) Source Public Required .false.), b2: (Variable 2 b2 Local () () Default (Logical 1 []) Source Public Required .false.), b3: (Variable 2 b3 Local () () Default (Logical 1 []) Source Public Required .false.), c: (Variable 2 c Local () () Default (Complex 4 []) Source Public Required .false.), f: (Variable 2 f Local () () Default (Real 4 []) Source Public Required .false.)}) test_UnaryOp [] [(= (Var 2 a) (UnaryOp UAdd (ConstantInteger 4 (Integer 4 [])) (Integer 4 []) (ConstantInteger 4 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp USub (ConstantInteger 500 (Integer 4 [])) (Integer 4 []) (ConstantInteger -500 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp Invert (ConstantInteger 5 (Integer 4 [])) (Integer 4 []) (ConstantInteger -6 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp Not (ConstantInteger 5 (Integer 4 [])) (Integer 4 []) (ConstantLogical .false. (Logical 4 []))) ()) (= (Var 2 a) (UnaryOp Not (UnaryOp USub (ConstantInteger 1 (Integer 4 [])) (Integer 4 []) (ConstantInteger -1 (Integer 4 []))) (Integer 4 []) (ConstantLogical .false. (Logical 4 []))) ()) (= (Var 2 a) (UnaryOp Not (ConstantInteger 0 (Integer 4 [])) (Integer 4 []) (ConstantLogical .true. (Logical 4 []))) ()) (= (Var 2 f) (ImplicitCast (UnaryOp UAdd (ConstantReal 1.000000 (Real 8 [])) (Real 8 []) (ConstantReal 1.000000 (Real 8 []))) RealToReal (Real 4 []) ()) ()) (= (Var 2 f) (ImplicitCast (UnaryOp USub (ConstantReal 183745.534000 (Real 8 [])) (Real 8 []) (ConstantReal -183745.534000 (Real 8 []))) RealToReal (Real 4 []) ()) ()) (= (Var 2 b1) (ConstantLogical .true. (Logical 1 [])) ()) (= (Var 2 b2) (UnaryOp Not (ConstantLogical .false. (Logical 1 [])) (Logical 1 []) (ConstantLogical .true. (Logical 4 []))) ()) (= (Var 2 b3) (UnaryOp Not (Var 2 b2) (Logical 1 []) ()) ()) (= (Var 2 a) (UnaryOp UAdd (ConstantLogical .true. (Logical 1 [])) (Logical 1 []) (ConstantInteger 1 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp USub (ConstantLogical .false. (Logical 1 [])) (Logical 1 []) (ConstantInteger 0 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp Invert (ConstantLogical .true. (Logical 1 [])) (Logical 1 []) (ConstantInteger -2 (Integer 4 []))) ()) (= (Var 2 c) (UnaryOp UAdd (ConstantComplex 1.000000 2.000000 (Complex 8 [])) (Complex 8 []) (ConstantComplex 1.000000 2.000000 (Complex 8 []))) ()) (= (Var 2 c) (UnaryOp USub (ConstantComplex 3.000000 65.000000 (Complex 8 [])) (Complex 8 []) (ConstantComplex -3.000000 -65.000000 (Complex 8 []))) ()) (= (Var 2 b1) (UnaryOp Not (ConstantComplex 3.000000 4.000000 (Complex 8 [])) (Complex 8 []) (ConstantLogical .false. (Logical 4 []))) ()) (= (Var 2 b2) (UnaryOp Not (ConstantComplex 0.000000 0.000000 (Complex 8 [])) (Complex 8 []) (ConstantLogical .true. (Logical 4 []))) ())] Source Public Implementation () .false. .false.)}) [])
(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_UnaryOp: (Subroutine (SymbolTable 2 {a: (Variable 2 a Local () () Default (Integer 4 []) Source Public Required .false.), b: (Variable 2 b Local () () Default (Logical 1 []) Source Public Required .false.), b1: (Variable 2 b1 Local () () Default (Logical 1 []) Source Public Required .false.), b2: (Variable 2 b2 Local () () Default (Logical 1 []) Source Public Required .false.), b3: (Variable 2 b3 Local () () Default (Logical 1 []) Source Public Required .false.), c: (Variable 2 c Local () () Default (Complex 4 []) Source Public Required .false.), f: (Variable 2 f Local () () Default (Real 4 []) Source Public Required .false.)}) test_UnaryOp [] [(= (Var 2 a) (UnaryOp UAdd (ConstantInteger 4 (Integer 4 [])) (Integer 4 []) (ConstantInteger 4 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp USub (ConstantInteger 500 (Integer 4 [])) (Integer 4 []) (ConstantInteger -500 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp Invert (ConstantInteger 5 (Integer 4 [])) (Integer 4 []) (ConstantInteger -6 (Integer 4 []))) ()) (= (Var 2 b) (UnaryOp Not (ConstantInteger 5 (Integer 4 [])) (Logical 4 []) (ConstantLogical .false. (Logical 4 []))) ()) (= (Var 2 b) (UnaryOp Not (UnaryOp USub (ConstantInteger 1 (Integer 4 [])) (Integer 4 []) (ConstantInteger -1 (Integer 4 []))) (Logical 4 []) (ConstantLogical .false. (Logical 4 []))) ()) (= (Var 2 b) (UnaryOp Not (ConstantInteger 0 (Integer 4 [])) (Logical 4 []) (ConstantLogical .true. (Logical 4 []))) ()) (= (Var 2 f) (ImplicitCast (UnaryOp UAdd (ConstantReal 1.000000 (Real 8 [])) (Real 8 []) (ConstantReal 1.000000 (Real 8 []))) RealToReal (Real 4 []) ()) ()) (= (Var 2 f) (ImplicitCast (UnaryOp USub (ConstantReal 183745.534000 (Real 8 [])) (Real 8 []) (ConstantReal -183745.534000 (Real 8 []))) RealToReal (Real 4 []) ()) ()) (= (Var 2 b1) (ConstantLogical .true. (Logical 1 [])) ()) (= (Var 2 b2) (UnaryOp Not (ConstantLogical .false. (Logical 1 [])) (Logical 1 []) (ConstantLogical .true. (Logical 4 []))) ()) (= (Var 2 b3) (UnaryOp Not (Var 2 b2) (Logical 1 []) ()) ()) (= (Var 2 a) (UnaryOp UAdd (ConstantLogical .true. (Logical 1 [])) (Integer 4 []) (ConstantInteger 1 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp USub (ConstantLogical .false. (Logical 1 [])) (Integer 4 []) (ConstantInteger 0 (Integer 4 []))) ()) (= (Var 2 a) (UnaryOp Invert (ConstantLogical .true. (Logical 1 [])) (Integer 4 []) (ConstantInteger -2 (Integer 4 []))) ()) (= (Var 2 c) (UnaryOp UAdd (ConstantComplex 1.000000 2.000000 (Complex 8 [])) (Complex 8 []) (ConstantComplex 1.000000 2.000000 (Complex 8 []))) ()) (= (Var 2 c) (UnaryOp USub (ConstantComplex 3.000000 65.000000 (Complex 8 [])) (Complex 8 []) (ConstantComplex -3.000000 -65.000000 (Complex 8 []))) ()) (= (Var 2 b1) (UnaryOp Not (ConstantComplex 3.000000 4.000000 (Complex 8 [])) (Logical 4 []) (ConstantLogical .false. (Logical 4 []))) ()) (= (Var 2 b2) (UnaryOp Not (ConstantComplex 0.000000 0.000000 (Complex 8 [])) (Logical 4 []) (ConstantLogical .true. (Logical 4 []))) ())] Source Public Implementation () .false. .false.)}) [])
4 changes: 2 additions & 2 deletions tests/reference/asr-expr8-6beda60.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"basename": "asr-expr8-6beda60",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/expr8.py",
"infile_hash": "c1844ccb51b77fb43b14fb6836c09ee3154ecfc8f672deee149b765a",
"infile_hash": "7ce00d3c3fed97c9a05717065081674c55f2b0a5299e8abb30fd509a",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-expr8-6beda60.stdout",
"stdout_hash": "705c33360f609af378773a46ff17cc98651974c2ed6155166084d59a",
"stdout_hash": "9bedcf8188bfc5d1fb9cc1ff6c2d164a18b9279e3070ff4a1ae0ab47",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
Loading

0 comments on commit 6121864

Please sign in to comment.