Added the []= overloadable operator and implemented it for vector, map, and string

This commit is contained in:
Nathan Braswell
2015-06-27 11:46:31 -04:00
parent b18c18ec30
commit dacfee6d22
13 changed files with 71 additions and 1 deletions

View File

@@ -62,7 +62,7 @@ scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ;
#Note that to prevent confilct with nested templates (T<A<B>>) 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 | ;

View File

@@ -35,6 +35,7 @@ ASTTransformation::ASTTransformation(Importer *importerIn) {
languageLevelOperators["."].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol(".", true), NULL))));
languageLevelOperators["->"].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("->", true), NULL))));
languageLevelOperators["[]"].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("[]", true), NULL))));
languageLevelOperators["[]="].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("[]=", true), NULL))));
}
ASTTransformation::~ASTTransformation() {
@@ -608,6 +609,22 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
newNode = new NodeTree<ASTData>(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<ASTData>* lhs = transform(getNode("unarad", unarad), scope, types, limitToFunction, templateTypeReplacements);
NodeTree<ASTData>* indexArg = transform(getNode("expression", unarad), scope, types, limitToFunction, templateTypeReplacements);
NodeTree<ASTData>* rhs = transform(children[2], scope, types, limitToFunction, templateTypeReplacements);
std::vector<NodeTree<ASTData>*> 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<ASTData>* function = doFunction(scope, "[]=", transformedChildren, templateTypeReplacements);
if (function)
return function;
// otherwise, screw it and do it regularly
}
NodeTree<ASTData>* lhs = transform(children[0], scope, types, limitToFunction, templateTypeReplacements);
NodeTree<ASTData>* rhs = transform(children[2], scope, types, limitToFunction, templateTypeReplacements);
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs);
@@ -838,6 +855,10 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* 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<ASTData>(lookup, ASTData(function_call, Symbol(lookup, true)));

View File

@@ -29,6 +29,9 @@ obj map<T,U> {
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) {

View File

@@ -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 {

View File

@@ -140,6 +140,9 @@ obj vector<T> (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;

View File

@@ -0,0 +1 @@
bracket assign: index: 4, rhs: 9

View File

@@ -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
}

View File

@@ -4,4 +4,5 @@
3
20
2
30
4

View File

@@ -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
}

View File

@@ -6,3 +6,4 @@ hope
hope3
new way!
a
now win!

View File

@@ -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;
}

View File

@@ -25,5 +25,10 @@ find test
0
1
2
set and []= test
4
8
9
7
done
Destroyed: 0

View File

@@ -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;