From dacfee6d22663fa0610526a788b9bb90632d893c Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 27 Jun 2015 11:46:31 -0400 Subject: [PATCH] Added the []= overloadable operator and implemented it for vector, map, and string --- krakenGrammer.kgm | 2 +- src/ASTTransformation.cpp | 21 +++++++++++++++++++++ stdlib/map.krak | 3 +++ stdlib/string.krak | 6 ++++++ stdlib/vector.krak | 3 +++ tests/test_bracket_assign.expected_results | 1 + tests/test_bracket_assign.krak | 16 ++++++++++++++++ tests/test_map.expected_results | 1 + tests/test_map.krak | 2 ++ tests/test_string.expected_results | 1 + tests/test_string.krak | 4 ++++ tests/test_vectorTest.expected_results | 5 +++++ tests/test_vectorTest.krak | 7 +++++++ 13 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tests/test_bracket_assign.expected_results create mode 100644 tests/test_bracket_assign.krak diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 60dd92c..82a4d57 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -62,7 +62,7 @@ scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ; #Note that to prevent confilct with nested templates (T>) it is a nonterminal contructed as follows right_shift = ">" ">" ; -overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "[]" ; +overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "[]" | "[]=" ; func_identifier = identifier | identifier overloadable_operator ; # allow omitting of return type (automatic void) typed_return = dec_type | ; diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index fa99973..9e6eca4 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -35,6 +35,7 @@ ASTTransformation::ASTTransformation(Importer *importerIn) { languageLevelOperators["."].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree("function", ASTData(function, Symbol(".", true), NULL)))); languageLevelOperators["->"].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree("function", ASTData(function, Symbol("->", true), NULL)))); languageLevelOperators["[]"].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree("function", ASTData(function, Symbol("[]", true), NULL)))); + languageLevelOperators["[]="].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree("function", ASTData(function, Symbol("[]=", true), NULL)))); } ASTTransformation::~ASTTransformation() { @@ -608,6 +609,22 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree newNode = new NodeTree(name, ASTData(defer_statement)); } else if (name == "assignment_statement") { std::string assignFuncName = concatSymbolTree(children[1]); + // but first check to see if the lefthand side is a factor which is a unarad with "[" in order to first check for operator []=? + // checking for this very specific case + // ok, assuming the left side is a factor, we grab the unarad + auto unarad = getNode("unarad", children[0]); + if (unarad && getNode("[", unarad)) { + // allrightly, check to see if we have []= + NodeTree* lhs = transform(getNode("unarad", unarad), scope, types, limitToFunction, templateTypeReplacements); + NodeTree* indexArg = transform(getNode("expression", unarad), scope, types, limitToFunction, templateTypeReplacements); + NodeTree* rhs = transform(children[2], scope, types, limitToFunction, templateTypeReplacements); + std::vector*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(indexArg); transformedChildren.push_back(rhs); + // doFunction special cases []= to return null if it's not found as a method + NodeTree* function = doFunction(scope, "[]=", transformedChildren, templateTypeReplacements); + if (function) + return function; + // otherwise, screw it and do it regularly + } NodeTree* lhs = transform(children[0], scope, types, limitToFunction, templateTypeReplacements); NodeTree* rhs = transform(children[2], scope, types, limitToFunction, templateTypeReplacements); std::vector*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs); @@ -838,6 +855,10 @@ NodeTree* ASTTransformation::doFunction(NodeTree* scope, std:: return newNode; } std::cout << "Early method level operator was NOT found" << std::endl; + if (lookup == "[]=") { + std::cout << "as the operator was []= we're returning nullptr now and gonna let our above handle it as seperate ones" << std::endl; + return nullptr; + } } newNode = new NodeTree(lookup, ASTData(function_call, Symbol(lookup, true))); diff --git a/stdlib/map.krak b/stdlib/map.krak index 8adfc98..57af3de 100644 --- a/stdlib/map.krak +++ b/stdlib/map.krak @@ -29,6 +29,9 @@ obj map { fun find_index(key: T): int { return keys.find_index(key) } + fun operator[]=(key: T, value: U) { + set(key,value) + } fun set(key: T, value: U) { var keyIdx = find_index(key) if (keyIdx >= 0) { diff --git a/stdlib/string.krak b/stdlib/string.krak index 88fd967..8902d01 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -43,6 +43,12 @@ obj string (Object) { var new.construct(data.slice(first,second)): string return new } + fun operator[]=(index: int, toSet: char) { + data[index] = toSet + } + fun set(index: int, toSet: char) { + data.set(index, toSet) + } fun length():int { return data.size; } fun operator=(str: char*): void { diff --git a/stdlib/vector.krak b/stdlib/vector.krak index a5b7919..2a50033 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -140,6 +140,9 @@ obj vector (Object) { return -1; } + fun operator[]=(index: int, dataIn: T) { + set(index, dataIn) + } fun set(index: int, dataIn: T): void { if (index < 0 || index >= size) return; diff --git a/tests/test_bracket_assign.expected_results b/tests/test_bracket_assign.expected_results new file mode 100644 index 0000000..486056a --- /dev/null +++ b/tests/test_bracket_assign.expected_results @@ -0,0 +1 @@ +bracket assign: index: 4, rhs: 9 diff --git a/tests/test_bracket_assign.krak b/tests/test_bracket_assign.krak new file mode 100644 index 0000000..0ca2820 --- /dev/null +++ b/tests/test_bracket_assign.krak @@ -0,0 +1,16 @@ +import io:* + +obj BracketAssign { + fun operator[]=(index:int, rhs:int) { + print("bracket assign: index: ") + print(index) + print(", rhs: ") + println(rhs) + } +} + +fun main():int { + var test:BracketAssign + test[4] = 9 + return 0 +} diff --git a/tests/test_map.expected_results b/tests/test_map.expected_results index 0a2df2e..970c96a 100644 --- a/tests/test_map.expected_results +++ b/tests/test_map.expected_results @@ -4,4 +4,5 @@ 3 20 2 +30 4 diff --git a/tests/test_map.krak b/tests/test_map.krak index 5a25e99..e0f78f7 100644 --- a/tests/test_map.krak +++ b/tests/test_map.krak @@ -10,9 +10,11 @@ fun main():int { println(m[3]) m.set(3,4) m.set(4,20) + m[6] = 30 println(m[1]) println(m[4]) println(m[2]) + println(m[6]) println(m[3]) return 0 } diff --git a/tests/test_string.expected_results b/tests/test_string.expected_results index 7faf59b..ccc760d 100644 --- a/tests/test_string.expected_results +++ b/tests/test_string.expected_results @@ -6,3 +6,4 @@ hope hope3 new way! a +now win! diff --git a/tests/test_string.krak b/tests/test_string.krak index 8cd3421..41e2572 100644 --- a/tests/test_string.krak +++ b/tests/test_string.krak @@ -16,6 +16,10 @@ fun main(): int { var newWay = string::string("new way!") io::println(newWay) io::println(newWay[5]) + newWay.set(1, 'o') + newWay[5] = 'i' + newWay[6] = 'n' + io::println(newWay) return 0; } diff --git a/tests/test_vectorTest.expected_results b/tests/test_vectorTest.expected_results index d9e3a47..d333645 100644 --- a/tests/test_vectorTest.expected_results +++ b/tests/test_vectorTest.expected_results @@ -25,5 +25,10 @@ find test 0 1 2 +set and []= test +4 +8 +9 +7 done Destroyed: 0 diff --git a/tests/test_vectorTest.krak b/tests/test_vectorTest.krak index ea6aea6..ccdee5e 100644 --- a/tests/test_vectorTest.krak +++ b/tests/test_vectorTest.krak @@ -111,6 +111,13 @@ fun main(): int { println(multipleFindTest.find_index(2)) println(multipleFindTest.find_index(3)) + println("set and []= test") + var setTest = vector(4,5,6) + setTest.add(7) + setTest.set(1,8) + setTest[2] = 9 + setTest.do(fun(it: int) println(it);) + println("done") return 0;