Skip to content

Commit

Permalink
Merge pull request lcompilers#498 from namannimmo10/dict_remove
Browse files Browse the repository at this point in the history
Add Dict pop in ASR
  • Loading branch information
certik authored May 15, 2022
2 parents ea8512b + eb63223 commit 9eb6119
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/libasr/ASR.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ expr
| ListItem(symbol a, expr pos, ttype type, expr? value)
| ListSection(expr a, array_index section, ttype type, expr? value)
| ListPop(symbol a, expr? index, ttype type, expr? value)
| DictPop(symbol a, expr key, ttype type, expr? value)

-- `len` in Character:
-- >=0 ... the length of the string, known at compile time
Expand Down
2 changes: 2 additions & 0 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ static inline ASR::ttype_t* expr_type(const ASR::expr_t *f)
case ASR::exprType::ListItem: { return ((ASR::ListItem_t*)f)->m_type; }
case ASR::exprType::ListSection: { return ((ASR::ListSection_t*)f)->m_type; }
case ASR::exprType::ListPop: { return ((ASR::ListPop_t*)f)->m_type; }
case ASR::exprType::DictPop: { return ((ASR::DictPop_t*)f)->m_type; }
default : throw LFortranException("Not implemented");
}
}
Expand Down Expand Up @@ -309,6 +310,7 @@ static inline ASR::expr_t* expr_value(ASR::expr_t *f)
case ASR::exprType::ListItem: { return ASR::down_cast<ASR::ListItem_t>(f)->m_value; }
case ASR::exprType::ListSection: { return ASR::down_cast<ASR::ListSection_t>(f)->m_value; }
case ASR::exprType::ListPop: { return ASR::down_cast<ASR::ListPop_t>(f)->m_value; }
case ASR::exprType::DictPop: { return ASR::down_cast<ASR::DictPop_t>(f)->m_value; }
case ASR::exprType::DictItem: // Drop through
case ASR::exprType::ArrayConstant: // Drop through
case ASR::exprType::IntegerConstant: // Drop through
Expand Down
26 changes: 25 additions & 1 deletion src/lpython/semantics/python_attribute_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ struct AttributeHandler {
{"list@pop", &eval_list_pop},
{"set@add", &eval_set_add},
{"set@remove", &eval_set_remove},
{"dict@get", &eval_dict_get}
{"dict@get", &eval_dict_get},
{"dict@pop", &eval_dict_pop}
};
}

Expand Down Expand Up @@ -269,6 +270,29 @@ struct AttributeHandler {
return make_DictItem_t(al, loc, s, args[0], def, value_type);
}

static ASR::asr_t* eval_dict_pop(ASR::symbol_t *s, Allocator &al, const Location &loc,
Vec<ASR::expr_t*> &args, diag::Diagnostics &diag) {
if (args.size() != 1) {
throw SemanticError("'pop' takes only one argument for now", loc);
}
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(s);
ASR::ttype_t *type = v->m_type;
ASR::ttype_t *key_type = ASR::down_cast<ASR::Dict_t>(type)->m_key_type;
ASR::ttype_t *value_type = ASR::down_cast<ASR::Dict_t>(type)->m_value_type;
if (!ASRUtils::check_equal_type(ASRUtils::expr_type(args[0]), key_type)) {
std::string ktype = ASRUtils::type_to_str_python(ASRUtils::expr_type(args[0]));
std::string totype = ASRUtils::type_to_str_python(key_type);
diag.add(diag::Diagnostic(
"Type mismatch in pop's key value, the types must be compatible",
diag::Level::Error, diag::Stage::Semantic, {
diag::Label("type mismatch (found: '" + ktype + "', expected: '" + totype + "')",
{args[0]->base.loc})
})
);
throw SemanticAbort();
}
return make_DictPop_t(al, loc, s, args[0], value_type, nullptr);
}

}; // AttributeHandler

Expand Down
7 changes: 7 additions & 0 deletions tests/dictionary1.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,10 @@ def test_dict_get():
x: i32
x = y.get("a")
x = y.get("a", 0)


def test_dict_pop():
y: dict[str, i32]
y = {"a": 1, "b": 2}
x: i32
x = y.pop("a")
5 changes: 5 additions & 0 deletions tests/errors/test_dict6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def f():
d: dict[i32, str]
d = {1: "a", 2: "b"}
res: str
res = d.pop("a")
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": "d24f9165c2fb6f0441d774936dc2dfce99a0fec7225713607806a19a",
"infile_hash": "31b7838c2cd2a67e4888ffa04070333904025cda07487029698c6183",
"outfile": null,
"outfile_hash": null,
"stdout": "asr-dictionary1-a105a36.stdout",
"stdout_hash": "92f1fa0d403591e2e096fc936d72fe6f6ebcd1a91e31cd56e8bd82a2",
"stdout_hash": "630b34fdc9d933db1c405d992fd3a4f5e619f2c6f014d746fe7013d0",
"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 5 {}) 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) (DictConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] [(IntegerConstant 2 (Integer 4 [])) (IntegerConstant 4 (Integer 4 []))] (Dict (Integer 4 []) (Integer 4 []))) ()) (= (Var 2 y) (DictConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () []))] [(UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (UnaryOp USub (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (= (Var 2 z) (DictItem 2 y (StringConstant "a" (Character 1 1 () [])) () (Integer 4 [])) ()) (= (Var 2 z) (DictItem 2 y (StringConstant "b" (Character 1 1 () [])) () (Integer 4 [])) ()) (= (Var 2 z) (DictItem 2 x (IntegerConstant 1 (Integer 4 [])) () (Integer 4 [])) ())] Source Public Implementation () .false. .false.), test_dict_get: (Subroutine (SymbolTable 4 {x: (Variable 4 x Local () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 4 y Local () () Default (Dict (Character 1 -2 () []) (Integer 4 [])) Source Public Required .false.)}) test_dict_get [] [(= (Var 4 y) (DictConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () []))] [(UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (UnaryOp USub (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (= (Var 4 x) (DictItem 4 y (StringConstant "a" (Character 1 1 () [])) () (Integer 4 [])) ()) (= (Var 4 x) (DictItem 4 y (StringConstant "a" (Character 1 1 () [])) (IntegerConstant 0 (Integer 4 [])) (Integer 4 [])) ())] Source Public Implementation () .false. .false.), test_dict_insert: (Subroutine (SymbolTable 3 {y: (Variable 3 y Local () () Default (Dict (Character 1 -2 () []) (Integer 4 [])) Source Public Required .false.)}) test_dict_insert [] [(= (Var 3 y) (DictConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () []))] [(UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (UnaryOp USub (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (DictInsert 3 y (StringConstant "c" (Character 1 1 () [])) (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))))] Source Public Implementation () .false. .false.)}) [])
(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 6 {}) 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) (DictConstant [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 3 (Integer 4 []))] [(IntegerConstant 2 (Integer 4 [])) (IntegerConstant 4 (Integer 4 []))] (Dict (Integer 4 []) (Integer 4 []))) ()) (= (Var 2 y) (DictConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () []))] [(UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (UnaryOp USub (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (= (Var 2 z) (DictItem 2 y (StringConstant "a" (Character 1 1 () [])) () (Integer 4 [])) ()) (= (Var 2 z) (DictItem 2 y (StringConstant "b" (Character 1 1 () [])) () (Integer 4 [])) ()) (= (Var 2 z) (DictItem 2 x (IntegerConstant 1 (Integer 4 [])) () (Integer 4 [])) ())] Source Public Implementation () .false. .false.), test_dict_get: (Subroutine (SymbolTable 4 {x: (Variable 4 x Local () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 4 y Local () () Default (Dict (Character 1 -2 () []) (Integer 4 [])) Source Public Required .false.)}) test_dict_get [] [(= (Var 4 y) (DictConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () []))] [(UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (UnaryOp USub (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (= (Var 4 x) (DictItem 4 y (StringConstant "a" (Character 1 1 () [])) () (Integer 4 [])) ()) (= (Var 4 x) (DictItem 4 y (StringConstant "a" (Character 1 1 () [])) (IntegerConstant 0 (Integer 4 [])) (Integer 4 [])) ())] Source Public Implementation () .false. .false.), test_dict_insert: (Subroutine (SymbolTable 3 {y: (Variable 3 y Local () () Default (Dict (Character 1 -2 () []) (Integer 4 [])) Source Public Required .false.)}) test_dict_insert [] [(= (Var 3 y) (DictConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () []))] [(UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) (UnaryOp USub (IntegerConstant 2 (Integer 4 [])) (Integer 4 []) (IntegerConstant -2 (Integer 4 [])))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (DictInsert 3 y (StringConstant "c" (Character 1 1 () [])) (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))))] Source Public Implementation () .false. .false.), test_dict_pop: (Subroutine (SymbolTable 5 {x: (Variable 5 x Local () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 5 y Local () () Default (Dict (Character 1 -2 () []) (Integer 4 [])) Source Public Required .false.)}) test_dict_pop [] [(= (Var 5 y) (DictConstant [(StringConstant "a" (Character 1 1 () [])) (StringConstant "b" (Character 1 1 () []))] [(IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 []))] (Dict (Character 1 1 () []) (Integer 4 []))) ()) (= (Var 5 x) (DictPop 5 y (StringConstant "a" (Character 1 1 () [])) (Integer 4 []) ()) ())] Source Public Implementation () .false. .false.)}) [])
13 changes: 13 additions & 0 deletions tests/reference/asr-test_dict6-95e3b14.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "asr-test_dict6-95e3b14",
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
"infile": "tests/errors/test_dict6.py",
"infile_hash": "96cf7e14615e027428b3f60969ef27fd9dbb07171e9088dfbede5d06",
"outfile": null,
"outfile_hash": null,
"stdout": null,
"stdout_hash": null,
"stderr": "asr-test_dict6-95e3b14.stderr",
"stderr_hash": "786fd07ddc3919823741b0db9a9ff0ba898b106d677657ea5f80fd2e",
"returncode": 2
}
5 changes: 5 additions & 0 deletions tests/reference/asr-test_dict6-95e3b14.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
semantic error: Type mismatch in pop's key value, the types must be compatible
--> tests/errors/test_dict6.py:5:17
|
5 | res = d.pop("a")
| ^^^ type mismatch (found: 'str', expected: 'i32')
4 changes: 2 additions & 2 deletions tests/reference/ast-dictionary1-1a7e00a.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"basename": "ast-dictionary1-1a7e00a",
"cmd": "lpython --show-ast --no-color {infile} -o {outfile}",
"infile": "tests/dictionary1.py",
"infile_hash": "d24f9165c2fb6f0441d774936dc2dfce99a0fec7225713607806a19a",
"infile_hash": "31b7838c2cd2a67e4888ffa04070333904025cda07487029698c6183",
"outfile": null,
"outfile_hash": null,
"stdout": "ast-dictionary1-1a7e00a.stdout",
"stdout_hash": "a4d907b481d700a454753881457ddb21264620b417ab442221241e1b",
"stdout_hash": "5785b52e8edbcfe38a6b15c576f6796561b2d328567eaaa20fa1ab9a",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/ast-dictionary1-1a7e00a.stdout
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(Module [(FunctionDef test_Dict ([] [] [] [] [] [] []) [(AnnAssign (Name x Store) (Subscript (Name dict Load) (Tuple [(Name i32 Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name x Store)] (Dict [(ConstantInt 1 ()) (ConstantInt 3 ())] [(ConstantInt 2 ()) (ConstantInt 4 ())]) ()) (AnnAssign (Name y Store) (Subscript (Name dict Load) (Tuple [(Name str Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name y Store)] (Dict [(ConstantStr "a" ()) (ConstantStr "b" ())] [(UnaryOp USub (ConstantInt 1 ())) (UnaryOp USub (ConstantInt 2 ()))]) ()) (AnnAssign (Name z Store) (Name i32 Load) () 1) (Assign [(Name z Store)] (Subscript (Name y Load) (ConstantStr "a" ()) Load) ()) (Assign [(Name z Store)] (Subscript (Name y Load) (ConstantStr "b" ()) Load) ()) (Assign [(Name z Store)] (Subscript (Name x Load) (ConstantInt 1 ()) Load) ())] [] () ()) (FunctionDef test_dict_insert ([] [] [] [] [] [] []) [(AnnAssign (Name y Store) (Subscript (Name dict Load) (Tuple [(Name str Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name y Store)] (Dict [(ConstantStr "a" ()) (ConstantStr "b" ())] [(UnaryOp USub (ConstantInt 1 ())) (UnaryOp USub (ConstantInt 2 ()))]) ()) (Assign [(Subscript (Name y Load) (ConstantStr "c" ()) Store)] (UnaryOp USub (ConstantInt 3 ())) ())] [] () ()) (FunctionDef test_dict_get ([] [] [] [] [] [] []) [(AnnAssign (Name y Store) (Subscript (Name dict Load) (Tuple [(Name str Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name y Store)] (Dict [(ConstantStr "a" ()) (ConstantStr "b" ())] [(UnaryOp USub (ConstantInt 1 ())) (UnaryOp USub (ConstantInt 2 ()))]) ()) (AnnAssign (Name x Store) (Name i32 Load) () 1) (Assign [(Name x Store)] (Call (Attribute (Name y Load) get Load) [(ConstantStr "a" ())] []) ()) (Assign [(Name x Store)] (Call (Attribute (Name y Load) get Load) [(ConstantStr "a" ()) (ConstantInt 0 ())] []) ())] [] () ())] [])
(Module [(FunctionDef test_Dict ([] [] [] [] [] [] []) [(AnnAssign (Name x Store) (Subscript (Name dict Load) (Tuple [(Name i32 Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name x Store)] (Dict [(ConstantInt 1 ()) (ConstantInt 3 ())] [(ConstantInt 2 ()) (ConstantInt 4 ())]) ()) (AnnAssign (Name y Store) (Subscript (Name dict Load) (Tuple [(Name str Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name y Store)] (Dict [(ConstantStr "a" ()) (ConstantStr "b" ())] [(UnaryOp USub (ConstantInt 1 ())) (UnaryOp USub (ConstantInt 2 ()))]) ()) (AnnAssign (Name z Store) (Name i32 Load) () 1) (Assign [(Name z Store)] (Subscript (Name y Load) (ConstantStr "a" ()) Load) ()) (Assign [(Name z Store)] (Subscript (Name y Load) (ConstantStr "b" ()) Load) ()) (Assign [(Name z Store)] (Subscript (Name x Load) (ConstantInt 1 ()) Load) ())] [] () ()) (FunctionDef test_dict_insert ([] [] [] [] [] [] []) [(AnnAssign (Name y Store) (Subscript (Name dict Load) (Tuple [(Name str Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name y Store)] (Dict [(ConstantStr "a" ()) (ConstantStr "b" ())] [(UnaryOp USub (ConstantInt 1 ())) (UnaryOp USub (ConstantInt 2 ()))]) ()) (Assign [(Subscript (Name y Load) (ConstantStr "c" ()) Store)] (UnaryOp USub (ConstantInt 3 ())) ())] [] () ()) (FunctionDef test_dict_get ([] [] [] [] [] [] []) [(AnnAssign (Name y Store) (Subscript (Name dict Load) (Tuple [(Name str Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name y Store)] (Dict [(ConstantStr "a" ()) (ConstantStr "b" ())] [(UnaryOp USub (ConstantInt 1 ())) (UnaryOp USub (ConstantInt 2 ()))]) ()) (AnnAssign (Name x Store) (Name i32 Load) () 1) (Assign [(Name x Store)] (Call (Attribute (Name y Load) get Load) [(ConstantStr "a" ())] []) ()) (Assign [(Name x Store)] (Call (Attribute (Name y Load) get Load) [(ConstantStr "a" ()) (ConstantInt 0 ())] []) ())] [] () ()) (FunctionDef test_dict_pop ([] [] [] [] [] [] []) [(AnnAssign (Name y Store) (Subscript (Name dict Load) (Tuple [(Name str Load) (Name i32 Load)] Load) Load) () 1) (Assign [(Name y Store)] (Dict [(ConstantStr "a" ()) (ConstantStr "b" ())] [(ConstantInt 1 ()) (ConstantInt 2 ())]) ()) (AnnAssign (Name x Store) (Name i32 Load) () 1) (Assign [(Name x Store)] (Call (Attribute (Name y Load) pop Load) [(ConstantStr "a" ())] []) ())] [] () ())] [])
4 changes: 4 additions & 0 deletions tests/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,10 @@ asr = true
filename = "errors/test_dict5.py"
asr = true

[[test]]
filename = "errors/test_dict6.py"
asr = true

# tests/tokens/errors

[[test]]
Expand Down

0 comments on commit 9eb6119

Please sign in to comment.