diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 99b7401..9982f5a 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -51,13 +51,13 @@ param_assign_list = param_assign WS "," WS param_assign_list | param_assign ; param_assign = identifier WS "=" WS identifier | identifier ; opt_string = string | ; -triple_quoted_string = "\"\"\"((\"\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+)|(\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+))*(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )*(((`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+\")|((`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+\"\")|((`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+))*\"\"\"" ; +triple_quoted_string = "\"\"\"((\"\"(`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| +|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+)|(\"(`|[0-9]|-|=| |[a-z]|\[|]|\\|'| +|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+))*(`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| +|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )*(((`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| +|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+\")|((`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| +|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+\"\")|((`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| +|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+))*\"\"\"" ; #identifier = alpha_alphanumeric ; identifier = augmented_alpha_alphanumeric ; @@ -66,7 +66,7 @@ scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ; #Note that to prevent confilct with nested templates (T>) right_shift 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) @@ -133,7 +133,7 @@ expression = expression WS "<<" WS term | expression WS right_shift WS shiftand shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ; term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; -unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | compiler_intrinsic | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "[" WS expression WS "]" | lambda | cast_expression ; +unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | compiler_intrinsic | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "\[" WS expression WS "]" | lambda | cast_expression ; cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ; number = integer | floating_literal ; access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ; @@ -141,23 +141,23 @@ access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ; # if it's being assigned to, we allow type inferencing declaration_statement = "var" WS identifier WS "=" WS boolean_expression | "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ; -hexadecimal = "0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" ; +hexadecimal = "0x([0-9]|[a-f])+" ; integer = numeric | hexadecimal ; floating_literal = numeric "." float_end ; -float_end = "(0|1|2|3|4|5|6|7|8|9)+" | "(0|1|2|3|4|5|6|7|8|9)+f" | "(0|1|2|3|4|5|6|7|8|9)+d" ; +float_end = "[0-9]+" | "[0-9]+f" | "[0-9]+d" ; bool = "true" | "false" ; -character = "'(`|1|2|3|4|5|6|7|8|9|0|-|=|(\\t)|q|w|e|r|t|y|u|i|o|p|[|]|(\\\\)|a|s|d|f|g|h|j|k|l|;|(\\')|(\\n)|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| |(\\0))'" ; +character = "'(`|[0-9]|-|=|(\\t)|[a-z]|\[|]|(\\\\)|;|(\\')|(\\n)|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|\"|<|>|\?| |(\\0))'" ; keywords_also_identifiers = "obj" | "def" | "fun" | "var" | "ref" | "adt" | "cast" | "import" | "simple_passthrough" ; -alpha_alphanumeric = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_)(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|_|0|1|2|3|4|5|6|7|8|9)*" ; +alpha_alphanumeric = "([a-z]|[A-Z]|_)([a-z]|[A-Z]|_|[0-9])*" ; augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ; -numeric = "(0|1|2|3|4|5|6|7|8|9)+" ; +numeric = "[0-9]+" ; # note the hacks around \things. Hmm, I feel like it actually shouldn't be like this. Added \\\* because I want to come back later -string = triple_quoted_string | "\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|(\\\\)|(\\n)|(\\t)|(\\\*)|(\\0)|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| |(\\\"))*\"" ; +string = triple_quoted_string | "\"(`|[0-9]|-|=| |[a-z]|\[|]|(\\\\)|(\\n)|(\\t)|(\\\*)|(\\0)|;|'| +|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| |(\\\"))*\"" ; comment = cpp_comment | c_comment ; -cpp_comment = "//(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| )* +cpp_comment = "//(`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|\"|<|>|\?| )* " ; -c_comment = "(/\*/*\**((`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| -|z|x|c|v|b|n|m|,|.|~|!|@|#|$|%|^|&|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| )/*\**)+\*/)|(/\*\*/)" ; +c_comment = "(/\*/*\**((`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| +|,|.|~|!|@|#|$|%|^|&|\(|\)|_|\+|[A-Z]|{|}|\||:|\"|<|>|\?| )/*\**)+\*/)|(/\*\*/)" ; diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index 116e1d6..9efe733 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -638,8 +638,7 @@ obj ast_transformation (Object) { if (factor_part->children.size == 1) { /*println("Factor has only one child!")*/ var inner_unarad = get_node("unarad", factor_part) - if (get_node("\"[\"", inner_unarad)) { - /*println("Inner Unarad has [!")*/ + if (get_node("\"]\"", inner_unarad)) { var assign_to = transform(get_node("unarad", inner_unarad), scope, template_replacements) var assign_idx = transform(get_node("expression", inner_unarad), scope, template_replacements) var possible_bracket_assign = find_and_make_any_operator_overload_call(string("[]="), vector(assign_to, assign_idx, to_assign), scope, template_replacements) diff --git a/stdlib/grammer.krak b/stdlib/grammer.krak index 1661f9b..795a215 100644 --- a/stdlib/grammer.krak +++ b/stdlib/grammer.krak @@ -179,22 +179,22 @@ obj grammer (Object, Serializable) { } fun first_vector(rhs: ref vector::vector): set::set { var toRet = set::set() - if (rhs.size) { - for (var i = 0; i < rhs.size; i++;) { - var lookahead = first_set_map[rhs[i]] - if (lookahead.contains(symbol::null_symbol())) { - // remove the null if this is not the last in the rule - if (i != rhs.size-1) - lookahead.remove(symbol::null_symbol()) - toRet.add(lookahead) - } else { - toRet.add(lookahead) - break - } + if (rhs.size) { + for (var i = 0; i < rhs.size; i++;) { + var lookahead = first_set_map[rhs[i]] + if (lookahead.contains(symbol::null_symbol())) { + // remove the null if this is not the last in the rule + if (i != rhs.size-1) + lookahead.remove(symbol::null_symbol()) + toRet.add(lookahead) + } else { + toRet.add(lookahead) + break } - } else { - toRet.add(symbol::null_symbol()) } + } else { + toRet.add(symbol::null_symbol()) + } return toRet } diff --git a/stdlib/parser.krak b/stdlib/parser.krak index 442ff9a..55f596f 100644 --- a/stdlib/parser.krak +++ b/stdlib/parser.krak @@ -19,6 +19,7 @@ obj parser (Object) { var to_shift: stack< pair<*tree, int> > var SPPFStepNodes: vector< pair<*tree, int> > var packed_map: map<*tree, bool> + var reduces_to_null_map: map, bool> fun construct(grammerIn: grammer): *parser { input.construct() @@ -28,6 +29,7 @@ obj parser (Object) { to_shift.construct() SPPFStepNodes.construct() packed_map.construct() + reduces_to_null_map.construct() return this } fun copy_construct(old: *parser) { @@ -38,6 +40,7 @@ obj parser (Object) { to_shift.copy_construct(&old->to_shift) SPPFStepNodes.copy_construct(&old->SPPFStepNodes) packed_map.copy_construct(&old->packed_map) + reduces_to_null_map.copy_construct(&old->reduces_to_null_map) } fun operator=(old: ref parser) { destruct() @@ -51,6 +54,7 @@ obj parser (Object) { to_shift.destruct() SPPFStepNodes.destruct() packed_map.destruct() + reduces_to_null_map.destruct() } fun parse_input(inputStr: string, name: string): *tree { @@ -386,7 +390,9 @@ obj parser (Object) { return r.position == 0 && reduces_to_null(r) } fun reduces_to_null(r: ref rule): bool { - return gram.first_vector(r.rhs).contains(null_symbol()) + if (!reduces_to_null_map.contains_key(r.rhs)) + reduces_to_null_map[r.rhs] = gram.first_vector(r.rhs).contains(null_symbol()) + return reduces_to_null_map[r.rhs] } fun get_nullable_parts(r: ref rule): *tree { if (reduces_to_null(r)) diff --git a/stdlib/regex.krak b/stdlib/regex.krak index b6ec195..64113ef 100644 --- a/stdlib/regex.krak +++ b/stdlib/regex.krak @@ -1,4 +1,6 @@ import io +import string +import ast_transformation import vector import string import mem @@ -15,10 +17,16 @@ fun regex(in: string::string):regex { } obj regexState (Object) { - var character: char + // if only one character, both are the same + var characterBegin: char + var characterEnd: char var next_states: set::set<*regexState> fun construct(charIn:char): *regexState { - character = charIn + return construct(charIn, charIn) + } + fun construct(charFirst:char, charSecond:char): *regexState { + characterBegin = charFirst + characterEnd = charSecond next_states.construct() return this } @@ -26,17 +34,18 @@ obj regexState (Object) { return construct((0) cast char) } fun copy_construct(old:*regexState): void { - character = old->character + characterBegin = old->characterBegin + characterEnd = old->characterEnd next_states.copy_construct(&old->next_states) } fun destruct():void { next_states.destruct() } fun match_char(input: char): set::set<*regexState> { - return next_states.filter(fun(it:*regexState):bool { return it->character == input; }) + return next_states.filter(fun(it:*regexState):bool { return it->characterBegin <= input && input <= it->characterEnd; }) } fun is_end():bool { - return next_states.any_true(fun(state: *regexState):bool { return state->character == 1; }) + return next_states.any_true(fun(state: *regexState):bool { return state->characterBegin == 1; }) } } @@ -67,14 +76,6 @@ obj regex (Object, Serializable) { begin = old->begin referenceCounter = old->referenceCounter *referenceCounter += 1 - /*construct(old->regexString)*/ - /*begin = mem::safe_recursive_clone(old->begin, fun(it: *regexState, cloner: fun(*regexState):*regexState, register: fun(*regexState):void): void {*/ - /*var newOne = mem::new()->construct(it->character)*/ - /*register(newOne)*/ - /*it->next_states.for_each(fun(next_state: *regexState) {*/ - /*newOne->next_states.add(cloner(next_state))*/ - /*})*/ - /*})*/ } fun destruct():void { @@ -105,6 +106,7 @@ obj regex (Object, Serializable) { } fun compile(regex_string: string::string): util::pair<*regexState, set::set<*regexState>> { + /*io::println(regex_string)*/ var first = mem::new()->construct() var previous_begin = set::set<*regexState>() var previous_end = set::set<*regexState>() @@ -132,11 +134,14 @@ obj regex (Object, Serializable) { } else if (regex_string[i] == '(' && !escapeing) { // note that we don't have a ')' case, as we skip past it with our indicies var perenEnd = i + 1 - for (var depth = 1; depth > 0; perenEnd++;) + for (var depth = 1; depth > 0; perenEnd++;) { + if (perenEnd >= regex_string.length()) + ast_transformation::error(string::string("can't find matching peren in: ") + regex_string) if (regex_string[perenEnd] == '(') depth++ else if (regex_string[perenEnd] == ')') depth-- + } var innerBeginEnd = compile(regex_string.slice(i+1, perenEnd-1)) // NOTE: perenEnd is one past the close peren i = perenEnd-1 @@ -158,7 +163,13 @@ obj regex (Object, Serializable) { escapeing = true } else { - var next = mem::new()->construct(regex_string[i]) + var next: *regexState + if (regex_string[i] == '[' && !escapeing) { + next = mem::new()->construct(regex_string[i+1], regex_string[i+3]) + i += 4 // [a-b] is 5, i++ adds one + } else { + next = mem::new()->construct(regex_string[i]) + } if (alternating) { previous_end.for_each(fun(it: *regexState):void { it->next_states.add(next); }) current_begin.add(next) diff --git a/stdlib/set.krak b/stdlib/set.krak index f04b6ad..2b6e1cb 100644 --- a/stdlib/set.krak +++ b/stdlib/set.krak @@ -34,8 +34,9 @@ obj set (Object, Serializable) { data.copy_construct(&old->data) } fun operator=(rhs: ref set) { - destruct() - copy_construct(&rhs) + /*destruct()*/ + /*copy_construct(&rhs)*/ + data = rhs.data } fun serialize(): vector::vector { return serialize::serialize(data) @@ -43,12 +44,12 @@ obj set (Object, Serializable) { fun unserialize(it: ref vector::vector, pos: int): int { return data.unserialize(it, pos) } - fun operator==(rhs: set): bool { + fun operator==(rhs: ref set): bool { if (size() != rhs.size()) return false return !data.any_true( fun(item: T): bool return !rhs.contains(item); ) } - fun operator!=(rhs: set): bool { + fun operator!=(rhs: ref set): bool { return ! (*this == rhs) } fun destruct() { @@ -57,10 +58,10 @@ obj set (Object, Serializable) { fun size():int { return data.size } - fun contains(items: set): bool { + fun contains(items: ref set): bool { return items.size() == 0 || !items.any_true( fun(item: T): bool return !contains(item); ) } - fun contains(item: T): bool { + fun contains(item: ref T): bool { return data.find(item) != -1 } fun operator+=(item: ref T) { @@ -84,7 +85,7 @@ obj set (Object, Serializable) { fun add(items: ref set) { items.for_each( fun(item: ref T) add(item); ) } - fun remove(item: T) { + fun remove(item: ref T) { var idx = data.find(item) if (idx == -1) { /*io::println("CANNOT FIND ITEM TO REMOVE")*/ diff --git a/stdlib/string.krak b/stdlib/string.krak index 10e70d3..0259a79 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -94,8 +94,9 @@ obj string (Object, Serializable) { } fun operator=(str: ref string): void { - destruct(); - data.copy_construct(&str.data) + /*destruct();*/ + /*data.copy_construct(&str.data)*/ + data = str.data } fun destruct():void { @@ -147,8 +148,9 @@ obj string (Object, Serializable) { } fun operator+(str: ref string): string { - var newStr.construct(str):string - var ret.construct(data + newStr.data):string + /*var newStr.construct(str):string*/ + /*var ret.construct(data + newStr.data):string*/ + var ret.construct(data + str.data):string return ret } @@ -210,7 +212,7 @@ obj string (Object, Serializable) { out.add(current) return out } - fun join(to_join: vector::vector): string { + fun join(to_join: ref vector::vector): string { var to_ret = to_join.first() for (var i = 1; i < to_join.size; i++;) to_ret += *this + to_join[i] diff --git a/stdlib/vector.krak b/stdlib/vector.krak index 2bd0229..54f5233 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -65,31 +65,36 @@ obj vector (Object, Serializable) { data = 0 } - fun operator=(other:vector):void { - destruct() - copy_construct(&other) + fun operator=(other:ref vector):void { + if (size < other.size) { + destruct() + copy_construct(&other) + } else { + clear() + for (var i = 0; i < other.size; i++;) + addEnd(other.get(i)) + } } - fun operator+(other:vector):vector { - // lets be at least a little bit smarter by copy_constructing our copy. - // We could get a lot better than this by initially creating enough space - // for both and copy_constructing all of them, but this is just a quick fix - var newVec.copy_construct(this):vector + fun operator+(other: ref vector):vector { + var newVec.construct(size+other.size):vector + for (var i = 0; i < size; i++;) + newVec.addEnd(get(i)) for (var i = 0; i < other.size; i++;) newVec.addEnd(other.get(i)) return newVec } - fun operator+(other: T):vector { + fun operator+(other: ref T):vector { var newVec.copy_construct(this):vector newVec.addEnd(other) return newVec } - fun operator+=(other: T):void { + fun operator+=(other: ref T):void { addEnd(other) } - fun operator+=(other:vector):void { + fun operator+=(other: ref vector):void { for (var i = 0; i < other.size; i++;) addEnd(other.get(i)) } @@ -180,7 +185,7 @@ obj vector (Object, Serializable) { return true } - fun set(index: int, dataIn: T): void { + fun set(index: int, dataIn: ref T): void { if (index < 0 || index >= size) return; data[index] = dataIn; @@ -190,7 +195,7 @@ obj vector (Object, Serializable) { addEnd(dataIn[i]); } // same darn trick - fun add_unique(dataIn: U): void { + fun add_unique(dataIn: ref U): void { if (!contains(dataIn)) addEnd(dataIn) }