From 47bc52f00cb840068ffef94fa484c6512b561eb4 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Mon, 8 Jun 2015 21:47:02 -0400 Subject: [PATCH] Some bugfixes, allow overloading of [] and add that to vector and string, work on regex. Need closures before that finishes.... --- include/RegExState.h | 9 +-- krakenGrammer.kgm | 2 +- src/ASTTransformation.cpp | 6 +- src/CGenerator.cpp | 24 ++++---- src/RegEx.cpp | 2 +- src/RegExState.cpp | 23 +------- stdlib/io.krak | 11 +++- stdlib/regex.krak | 78 ++++++++++++++++++++++++++ stdlib/string.krak | 8 +++ stdlib/vector.krak | 22 ++++++-- tests/test_regex.expected_results | 1 + tests/test_regex.krak | 9 +++ tests/test_regex/test_regex.results | 0 tests/test_string.expected_results | 2 + tests/test_string.krak | 3 + tests/test_traitsTest.expected_results | 14 +++++ tests/test_traitsTest.krak | 18 ++++++ tests/test_vectorTest.expected_results | 1 + tests/test_vectorTest.krak | 3 + 19 files changed, 188 insertions(+), 48 deletions(-) create mode 100644 stdlib/regex.krak create mode 100644 tests/test_regex.expected_results create mode 100644 tests/test_regex.krak create mode 100644 tests/test_regex/test_regex.results diff --git a/include/RegExState.h b/include/RegExState.h index de4096a..2927c9e 100644 --- a/include/RegExState.h +++ b/include/RegExState.h @@ -9,19 +9,15 @@ class RegExState { public: - RegExState(RegExState* inInnerState); RegExState(char inCharacter); RegExState(); - ~RegExState(); void addNext(RegExState* nextState); bool characterIs(char inCharacter); std::vector* advance(char advanceCharacter); - std::vector* getNextStates(); + std::vector getNextStates(); - RegExState* getInner(); - bool isGoal(); std::string toString(); std::string toString(RegExState* avoid); @@ -31,7 +27,6 @@ class RegExState { private: std::vector nextStates; - RegExState* inner; char character; }; -#endif \ No newline at end of file +#endif diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 926de15..750b2b8 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -61,7 +61,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 ; function = "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS statement ; lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS statement ; diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 920f4e8..155b567 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -972,7 +972,8 @@ NodeTree* ASTTransformation::templateClassLookup(NodeTree* sco int typeIndex = 0; int currentTraitsSatisfied = 0; for (auto j : nameTraitsPairs) { - if (!subset(j.second, templateInstantiationTypes[typeIndex]->traits)) { + // error out if not subset, or if we're a pointer but should have traits + if (!subset(j.second, templateInstantiationTypes[typeIndex]->traits) || (templateInstantiationTypes[typeIndex]->getIndirection() && j.second.size())) { traitsEqual = false; std::cout << "Traits not subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": "; //std::cout << baseType << " " << indirection << " " << typeDefinition << " " << templateDefinition << " " << traits << ; @@ -1137,7 +1138,8 @@ NodeTree* ASTTransformation::templateFunctionLookup(NodeTree* int typeIndex = 0; int currentTraitsSatisfied = 0; for (auto j : nameTraitsPairs) { - if (!subset(j.second, templateInstantiationTypesPerFunction[i][typeIndex]->traits)) { + // error out if not subset, or if we're a pointer but should have traits + if (!subset(j.second, templateInstantiationTypesPerFunction[i][typeIndex]->traits) || (templateInstantiationTypesPerFunction[i][typeIndex]->getIndirection() && j.second.size())) { traitsEqual = false; std::cout << "Traits not a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": |"; std::copy(j.second.begin(), j.second.end(), std::ostream_iterator(std::cout, " ")); diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 359788b..5e1a390 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -359,7 +359,7 @@ CCodeTriple CGenerator::generate(NodeTree* from, NodeTree* enc return tabs() + stat.preValue + stat.value + ";\n" + stat.postValue ; } case if_statement: - output += "if (" + generate(children[0], enclosingObject, true).oneString() + ")\n\t"; + output += "if (" + generate(children[0], enclosingObject, true) + ")\n\t"; // We have to see if the then statement is a regular single statement or a block. // If it's a block, because it's also a statement a semicolon will be emitted even though // we don't want it to be, as if (a) {b}; else {c}; is not legal C, but if (a) {b} else {c}; is. @@ -798,16 +798,16 @@ std::string CGenerator::CifyName(std::string name) { "&", "amprsd", "|", "pipe", "~", "tilde", - "!", "exclamationpt", + "!", "exlmtnpt", ",", "comma", - "=", "equals", - "++", "doubleplus", - "--", "doubleminus", - "<<", "doubleleft", - ">>", "doubleright", + "=", "eq", + "++", "dbplus", + "--", "dbminus", + "<<", "dbleft", + ">>", "dbright", "::", "scopeop", ":", "colon", - "==", "doubleequals", + "==", "dbq", "!=", "notequals", "&&", "doubleamprsnd", "||", "doublepipe", @@ -820,13 +820,13 @@ std::string CGenerator::CifyName(std::string name) { "|=", "pipeequals", "*=", "starequals", "<<=", "doublerightequals", - "<", "lessthan", - ">", "greaterthan", + "<", "lt", + ">", "gt", ">>=", "doubleleftequals", "(", "openparen", ")", "closeparen", - "[", "openbracket", - "]", "closebracket", + "[", "obk", + "]", "cbk", " ", "space", ".", "dot", "->", "arrow" }; diff --git a/src/RegEx.cpp b/src/RegEx.cpp index 18acabe..9a9c5e9 100644 --- a/src/RegEx.cpp +++ b/src/RegEx.cpp @@ -70,7 +70,7 @@ RegExState* RegEx::construct(std::vector* ending, std::string patte int perenEnd = findPerenEnd(pattern, i); RegExState* innerBegin = construct(&innerEnds, strSlice(pattern, i+1, perenEnd)); i = perenEnd; - std::vector innerBegins = *(innerBegin->getNextStates()); + std::vector innerBegins = innerBegin->getNextStates(); if (alternating) { for (std::vector::size_type j = 0; j < previousStatesEnd.size(); j++) for (std::vector::size_type k = 0; k < innerBegins.size(); k++) diff --git a/src/RegExState.cpp b/src/RegExState.cpp index c147ad2..0bf8fb1 100644 --- a/src/RegExState.cpp +++ b/src/RegExState.cpp @@ -1,17 +1,11 @@ #include "RegExState.h" -RegExState::RegExState(RegExState* inInnerState) { - inner = inInnerState; -} - RegExState::RegExState(char inCharacter) { character = inCharacter; - inner = NULL; } RegExState::RegExState() { character = 0; - inner = NULL; } RegExState::~RegExState() { @@ -29,22 +23,17 @@ bool RegExState::characterIs(char inCharacter) { std::vector* RegExState::advance(char advanceCharacter) { std::vector* advanceStates = new std::vector(); for (std::vector::size_type i = 0; i < nextStates.size(); i++) { - if (nextStates[i] != NULL && nextStates[i]->characterIs(advanceCharacter)) + if (nextStates[i] != NULL && nextStates[i]->characterIs(advanceCharacter)) advanceStates->push_back(nextStates[i]); } return advanceStates; } -RegExState* RegExState::getInner() { - return inner; -} - -std::vector* RegExState::getNextStates() { - return &nextStates; +std::vector RegExState::getNextStates() { + return nextStates; } bool RegExState::isGoal() { - //return inner == NULL && nextStates.size() == 0; for (std::vector::size_type i = 0; i < nextStates.size(); i++) if (nextStates[i] == NULL) return true; @@ -66,11 +55,6 @@ std::string RegExState::toString(std::vector* avoid) { avoid->push_back(this); std::string string = ""; string += std::string("\"") + character + "\""; - if (inner != NULL) { - string += "inner: "; - string += inner->toString(avoid); - string += " end inner "; - } for (std::vector::size_type i = 0; i < nextStates.size(); i++) { bool inAvoid = false; for (std::vector::size_type j = 0; j < avoid->size(); j++) { @@ -90,7 +74,6 @@ std::string RegExState::toString(std::vector* avoid) { else string += "->this"; } - //std::cout << "inner = " << inner << " nextStates size = " << nextStates.size() <(toPrint: T) : void { fun print(toPrint: char*) : void { __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ - printf(toPrint); + printf("%s", toPrint); + """ + } + return; +} + +fun print(toPrint: char) : void { + __if_comp__ __C__ { + simple_passthrough(toPrint = toPrint::) """ + printf("%c", toPrint); """ } return; diff --git a/stdlib/regex.krak b/stdlib/regex.krak new file mode 100644 index 0000000..a6cc5d7 --- /dev/null +++ b/stdlib/regex.krak @@ -0,0 +1,78 @@ +import io +import vector +import string + +fun regex(in: char*):regex { + return regex(string::string(in)) +} +fun regex(in: string::string):regex { + var out.construct(in):regex + return out +} + +obj regexState(Object) { + var character: char + var next_states: vector::vector + fun construct(charIn:char): regexState* { + character = charIn + next_states.construct() + return this + } + fun construct(): regexState* { + return construct(0) + } + fun copy_construct(old:regexState*): void { + character = regexState->character + next_states.copy_construct(®exState->next_states) + } + fun destruct():void { + next_states.destruct() + } + fun match(input: char): vector::vector { + return next_states.filter(fun(it:regexState*):bool { return it->character == input; } ) + } +} + +obj regex(Object) { + var regexString: string::string + var begin: regexState + fun construct(regexStringIn: string::string): regex* { + regexState.construct() + regexString.copy_construct(®exStringIn) + + var traverse = &begin + for (var i = 0; i < regexString.length(); i++;) { + var next = new()->construct(regexString[i]) + traverse->next_states->add(next) + traverse = next + } + traverse->next_states->add(new()->construct(1)) + + return this + } + fun copy_construct(old:regex*):void { + begin.copy_construct(&old->begin) + regexString.copy_construct(&old->regexString) + } + fun destruct():void { + begin.destruct() + regexString.destruct() + } + fun long_match(to_match: char*): int { return long_match(string::string(to_match)); } + fun long_match(to_match: string::string): int { + var next = vector::vector(&begin) + var longest = 0 + for (var i = 0; i < to_match.length(); i++;) { + if (next.size == 0) + return longest + if (next.any_true(fun(state: regexState*):bool { return state->character == 1; })) + longest = i + next = next.flatten_map(fun(state: regexState*): vector::vector { return state->match(to_match[i]); }) + } + if (next.any_true(fun(state: regexState*):bool { return state->character == 1; })) + return to_match.length() + return longest + } +} + + diff --git a/stdlib/string.krak b/stdlib/string.krak index 1fae5a1..f0aef39 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -1,6 +1,11 @@ import vector; import mem; +fun string(in:char*):string { + var out:string = in + return out +} + obj string (Object) { var data: vector::vector; fun construct(): string* { @@ -33,6 +38,9 @@ obj string (Object) { data.destruct() } + fun operator[](index: int): char { return data[index]; } + fun length():int { return data.size; } + fun operator=(str: char*): void { destruct(); construct(str) diff --git a/stdlib/vector.krak b/stdlib/vector.krak index 8b36dc6..b14e154 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -74,10 +74,8 @@ obj vector (Object) { return true; } - fun at(index: int): T { - return get(index); - } - + fun at(index: int): T { return get(index); } + fun operator[](index: int): T { return get(index); } fun get(index: int): T { if (index < 0 || index >= size) { println("Vector access out of bounds! Retuning 0th element as sanest option"); @@ -97,6 +95,7 @@ obj vector (Object) { return; data[index] = dataIn; } + fun add(dataIn: T): void { addEnd(dataIn); } fun addEnd(dataIn: T): void { size++; if (size >= available) @@ -117,5 +116,20 @@ obj vector (Object) { newVec.addEnd(func(data[i])) return newVec } + fun flatten_map(func: fun(T):vector):vector { + var newVec.construct(): vector + for (var i = 0; i < size; i++;) { + var to_add = func(data[i]) + for (var j = 0; j < to_add.size; j++;) + newVec.addEnd(to_add.get(j)) + } + return newVec + } + fun any_true(func: fun(T):bool):bool { + for (var i = 0; i < size; i++;) + if (func(data[i])) + return true + return false + } }; diff --git a/tests/test_regex.expected_results b/tests/test_regex.expected_results new file mode 100644 index 0000000..7898192 --- /dev/null +++ b/tests/test_regex.expected_results @@ -0,0 +1 @@ +a diff --git a/tests/test_regex.krak b/tests/test_regex.krak new file mode 100644 index 0000000..f9a831d --- /dev/null +++ b/tests/test_regex.krak @@ -0,0 +1,9 @@ +import io:* +import regex:* + +fun main():int { + var reg = regex("a") + println(reg.regexString) + println(reg.long_match("a")) + return 0 +} diff --git a/tests/test_regex/test_regex.results b/tests/test_regex/test_regex.results new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_string.expected_results b/tests/test_string.expected_results index 55b29ed..7faf59b 100644 --- a/tests/test_string.expected_results +++ b/tests/test_string.expected_results @@ -4,3 +4,5 @@ assignment overload2 assignment overload with additional hope hope3 +new way! +a diff --git a/tests/test_string.krak b/tests/test_string.krak index a9790e4..8cd3421 100644 --- a/tests/test_string.krak +++ b/tests/test_string.krak @@ -13,6 +13,9 @@ fun main(): int { var initilized:string::string = "hope" io::println(initilized) io::println(initilized+ "3") + var newWay = string::string("new way!") + io::println(newWay) + io::println(newWay[5]) return 0; } diff --git a/tests/test_traitsTest.expected_results b/tests/test_traitsTest.expected_results index 603431e..693d2b7 100644 --- a/tests/test_traitsTest.expected_results +++ b/tests/test_traitsTest.expected_results @@ -2,8 +2,22 @@ No Traits First Trait Second Trait Both Traits +No Traits + +No Traits +First Trait +Second Trait +Both Traits +No Traits First Trait Second Trait Both Traits No Traits +First Trait + +First Trait +Second Trait +Both Traits +No Traits +First Trait diff --git a/tests/test_traitsTest.krak b/tests/test_traitsTest.krak index 37cc431..d2c043d 100644 --- a/tests/test_traitsTest.krak +++ b/tests/test_traitsTest.krak @@ -48,13 +48,22 @@ fun main(): int { var c: Trait2; var d: TwoTrait; var e: AlreadySpecilized; + var f: TwoTrait*; OneTwoFunc(a); OneTwoFunc(b); OneTwoFunc(c); OneTwoFunc(d); // OneTwoFunc(e); + OneTwoFunc(f); + println(); + OneTwoFunc(a); + OneTwoFunc(b); + OneTwoFunc(c); + OneTwoFunc(d); +// OneTwoFunc(e); + OneTwoFunc(f); println(); var alpha: OneTwoObj; @@ -62,11 +71,20 @@ fun main(): int { var gamma: OneTwoObj; var delta: OneTwoObj; // |OneTwoObj| epsilon; + var zeta: OneTwoObj; OneTwoFunc>(alpha); OneTwoFunc>(beta); OneTwoFunc>(gamma); OneTwoFunc>(delta); + OneTwoFunc>(zeta); + println() + + OneTwoFunc(alpha); + OneTwoFunc(beta); + OneTwoFunc(gamma); + OneTwoFunc(delta); + OneTwoFunc(zeta); //We can't pass along our inner part, so let's just make sure that it is the right object. //epsilon.proveSpecilized(); diff --git a/tests/test_vectorTest.expected_results b/tests/test_vectorTest.expected_results index 9422df1..c2c28d0 100644 --- a/tests/test_vectorTest.expected_results +++ b/tests/test_vectorTest.expected_results @@ -1,5 +1,6 @@ 4 1337 +1337 26614 9131321 15513 diff --git a/tests/test_vectorTest.krak b/tests/test_vectorTest.krak index ffbb5bb..8faffc9 100644 --- a/tests/test_vectorTest.krak +++ b/tests/test_vectorTest.krak @@ -43,6 +43,9 @@ fun main(): int { for (var i: int = 0; i < intVec.size; i++;) print(intVec.at(i)); println(); + for (var i: int = 0; i < intVec.size; i++;) + print(intVec[i]); + println(); // in place lambda map intVec.in_place(fun(it:int):int { return it*2; })