diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index f46a17b..0c4377d 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -100,7 +100,7 @@ defer_statement = "defer" WS statement ; function_call = unarad "\(" WS opt_parameter_list WS "\)" ; boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ; -and_boolean_expression = and_boolean_expression "&&" bool_exp | bool_exp ; +and_boolean_expression = and_boolean_expression WS "&&" WS bool_exp | bool_exp ; bool_exp = expression WS comparator WS expression | expression ; comparator = "==" | "<=" | ">=" | "!=" | "<" | ">" ; @@ -119,8 +119,7 @@ hexadecimal = "0x(1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" ; integer = numeric | hexadecimal ; floating_literal = numeric "." numeric ; bool = "true" | "false" ; -character = "'(`|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|<|>|\?| )'" ; +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))'" ; keywords_also_identifiers = "obj" | "def" | "fun" | "var" ; 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)*" ; diff --git a/stdlib/mem.krak b/stdlib/mem.krak index 5eb5573..be54a14 100644 --- a/stdlib/mem.krak +++ b/stdlib/mem.krak @@ -67,6 +67,16 @@ fun delete(toDelete: T*): void { free(toDelete); } +// a wrapper for construct if it has the Object trait +fun maybe_construct(it:T*):T* { + return it +} + +fun maybe_construct(it:T*):T* { + return it->construct() +} + + // a wrapper for copy constructing if it has the Object trait fun maybe_copy_construct(to:T*, from:T*):void { *to = *from @@ -76,3 +86,11 @@ fun maybe_copy_construct(to:T*, from:T*):void { to->copy_construct(from) } +// a wrapper for destruct if it has the Object trait +fun maybe_destruct(it:T*):void {} + +fun maybe_destruct(it:T*):void { + it->destruct() +} + + diff --git a/stdlib/regex.krak b/stdlib/regex.krak index 2d214c9..baf8191 100644 --- a/stdlib/regex.krak +++ b/stdlib/regex.krak @@ -2,6 +2,7 @@ import io import vector import string import mem +import util import conversions fun regex(in: char*):regex { @@ -52,27 +53,95 @@ obj regexState(Object) { obj regex(Object) { var regexString: string::string var begin: regexState + fun construct(regexStringIn: string::string): regex* { begin.construct() regexString.copy_construct(®exStringIn) - var traverse = &begin - for (var i = 0; i < regexString.length(); i++;) { - var next = mem::new()->construct(regexString[i]) - traverse->next_states.add(next) - traverse = next - } - traverse->next_states.add(mem::new()->construct(conversions::to_char(1))) + var beginningAndEnd = compile(regexStringIn) + // add each beginning state as a next state of our begin, and the end state as the next state of each end + beginningAndEnd.first.do(fun(it: regexState*, begin: regexState*): void { begin->next_states.add(it); }, &begin) + beginningAndEnd.second.do(fun(it: regexState*, end: regexState*): void { it->next_states.add(end); }, mem::new()->construct(conversions::to_char(1))) + + io::print("begin: ") + beginningAndEnd.first.do(fun(it: regexState*): void { io::print(it->character); }) + io::print("\nend: ") + beginningAndEnd.second.do(fun(it: regexState*): void { io::print(it->character); }) + io::println() + 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 operator=(other: regex):void { + destruct() + construct(other.regexString) + } + + fun compile(regex_string: string::string): util::pair, vector::vector> { + var first = mem::new()->construct() + var previous_begin = vector::vector() + var previous_end = vector::vector() + var current_begin = vector::vector(first) + var current_end = vector::vector(first) + var alternating = false + var escapeing = false + + for (var i = 0; i < regex_string.length(); i++;) { + //io::print("i: "); io::println(i) + if (regex_string[i] == '*' && !escapeing) { + for (var j = 0; j < current_end.size; j++;) + current_end[j]->next_states.add_all(current_begin) + //io::print("previous_begin size: "); io::println(previous_begin.size) + current_begin.add_all(previous_begin) + current_end.add_all(previous_end) + } else if (regex_string[i] == '+' && !escapeing) { + for (var j = 0; j < current_end.size; j++;) + current_end[j]->next_states.add_all(current_begin) + //io::print("previous_begin size +: "); io::println(previous_begin.size) + } else if (regex_string[i] == '?' && !escapeing) { + current_begin.add_all(previous_begin) + current_end.add_all(previous_end) + } else if (regex_string[i] == '|' && !escapeing) { + alternating = true + } else if (regex_string[i] == '(' && !escapeing) { + } else if (regex_string[i] == '\\' && !escapeing) { + escapeing = true + } else { + var next = mem::new()->construct(regex_string[i]) + if (alternating) { + previous_end.do(fun(it: regexState*, next: regexState*):void { it->next_states.add(next); }, next) + current_begin.add(next) + current_end.add(next) + } else { + current_end.do(fun(it: regexState*, next: regexState*):void { io::print("adding: "); io::print(next->character); io::print(" to "); io::println(it->character); it->next_states.add(next); }, next) + //current_end.do(fun(it: regexState*, next: regexState*):void { it->next_states.add(next); }, next) + //io::print("previous_begin size before current: "); io::println(previous_begin.size) + //io::print("current_begin size before current: "); io::println(current_begin.size) + previous_begin = current_begin + //io::print("previous_begin size after current: "); io::println(previous_begin.size) + previous_end = current_end + current_begin = vector::vector(next) + //io::print("current_begin size after current: "); io::println(current_begin.size) + current_end = vector::vector(next) + } + } + } + var beginAndEnd = util::make_pair(first->next_states, current_end) + mem::delete(first) + return beginAndEnd + } + + 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) diff --git a/stdlib/util.krak b/stdlib/util.krak index a46f852..d563286 100644 --- a/stdlib/util.krak +++ b/stdlib/util.krak @@ -1,3 +1,4 @@ +import mem fun greater(a: T, b: T): T { if (a > b) @@ -10,3 +11,36 @@ fun lesser(a: T, b: T): T { return b; return a; } + +fun make_pair(first: T, second: U): pair { + var it.construct(first, second): pair + return it +} + +obj pair(Object) { + var first: T + var second: U + + fun construct(firstIn: T, secondIn: U): pair* { + mem::maybe_copy_construct(&first, &firstIn) + mem::maybe_copy_construct(&second, &secondIn) + return this + } + + fun construct(): pair* { + mem::maybe_construct(&first) + mem::maybe_construct(&second) + return this + } + + fun copy_construct(old: pair*):void { + mem::maybe_copy_construct(&first, &old->first) + mem::maybe_copy_construct(&second, &old->second) + } + + fun destruct():void { + mem::maybe_destruct(&first) + mem::maybe_destruct(&second) + } +} + diff --git a/stdlib/vector.krak b/stdlib/vector.krak index 2081d17..b2c14be 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -8,6 +8,11 @@ fun vector(in:T):vector { return out } +fun vector():vector { + var out.construct():vector + return out +} + obj vector (Object) { var data: T*; var size: int; @@ -41,9 +46,8 @@ obj vector (Object) { } fun operator=(other:vector):void { - resize(other.size) - for (var i = 0; i < other.size; i++;) - set(i, other.get(i)) + destruct() + copy_construct(&other) } fun operator+(other:vector):vector { @@ -101,6 +105,10 @@ obj vector (Object) { return; data[index] = dataIn; } + fun add_all(dataIn: vector): void { + for (var i = 0; i < dataIn.size; i++;) + addEnd(dataIn[i]); + } fun add(dataIn: T): void { addEnd(dataIn); } fun addEnd(dataIn: T): void { size++; @@ -112,6 +120,10 @@ obj vector (Object) { for (var i = 0; i < size; i++;) func(data[i]) } + fun do(func: fun(T,U):void, extraParam: U):void { + for (var i = 0; i < size; i++;) + func(data[i], extraParam) + } fun in_place(func: fun(T):T):void { for (var i = 0; i < size; i++;) data[i] = func(data[i]) diff --git a/tests/test_badMath.expected_results b/tests/test_badMath.expected_results index 8ae1da9..7b7e90f 100644 --- a/tests/test_badMath.expected_results +++ b/tests/test_badMath.expected_results @@ -4,3 +4,4 @@ Spam 28 We'll find out. 34 +woo not diff --git a/tests/test_badMath.krak b/tests/test_badMath.krak index 570cd1e..6b1288e 100644 --- a/tests/test_badMath.krak +++ b/tests/test_badMath.krak @@ -15,4 +15,7 @@ fun main(): void { for (var i:int = 0; i < 20; i++;) z++; if (z > 20) io::println("We'll find out."); io::println(z); + var boolean = false + if ( z > 20 && !boolean) + io::println("woo not") } diff --git a/tests/test_regex.krak b/tests/test_regex.krak index 85449ae..568cf5a 100644 --- a/tests/test_regex.krak +++ b/tests/test_regex.krak @@ -5,5 +5,15 @@ fun main():int { var reg = regex("ab") println(reg.long_match("abab")) println(reg.long_match("aab")) + + println("second") + + reg = regex("a*b+c") + println(reg.long_match("bc")) + println(reg.long_match("aaaaaaaaaaaaaaaabc")) + println(reg.long_match("aaaaaaaaaaaaaaaabbbbbbbbbc")) + println(reg.long_match("aaaaaaaaaaaaaaaa")) + println(reg.long_match("aaaaaaaaaaaaaaaac")) + println(reg.long_match("aaaaaaaaaaaaaaaab")) return 0 } diff --git a/tests/test_util.expected_results b/tests/test_util.expected_results new file mode 100644 index 0000000..b83449b --- /dev/null +++ b/tests/test_util.expected_results @@ -0,0 +1,33 @@ +1 +7.000000 +2 +8.000000 +3 +hi +construct +construct with 0 +construct with 100 +make_pair +copy construct from 0 to 1 +copy construct from 100 to 101 +copy construct from 1 to 2 +copy construct from 101 to 102 +copy construct from 2 to 3 +copy construct from 102 to 103 +destruct with 102 +destruct with 2 +copy construct from 3 to 4 +copy construct from 103 to 104 +destruct with 3 +destruct with 103 +destruct with 101 +destruct with 1 +copy construct from 4 to 5 +copy construct from 104 to 105 +destruct with 4 +destruct with 104 +done +destruct with 5 +destruct with 105 +destruct with 100 +destruct with 0 diff --git a/tests/test_util.krak b/tests/test_util.krak new file mode 100644 index 0000000..b37c2a1 --- /dev/null +++ b/tests/test_util.krak @@ -0,0 +1,45 @@ +import util:* +import io:* + +obj test(Object) { + var counter:int + fun construct(): test* { + counter = 0 + println("construct with 0") + return this + } + + fun construct(it:int): test* { + counter = it + print("construct with "); println(it) + return this + } + + fun copy_construct(old: test*):void { + counter = old->counter+1 + print("copy construct from "); print(old->counter); print(" to "); println(counter) + } + + fun destruct():void { + print("destruct with "); println(counter) + } +} + +fun main():int { + println(lesser(1,2)) + println(lesser(7.0,8.0)) + println(greater(1,2)) + println(greater(7.0,8.0)) + + var oddPair = make_pair(3, "hi") + println(oddPair.first) + println(oddPair.second) + + println("construct") + var test1.construct():test + var test2.construct(100):test + println("make_pair") + var test_pair = make_pair(test1, test2) + println("done") + return 0 +} diff --git a/tests/test_vectorTest.expected_results b/tests/test_vectorTest.expected_results index c2c28d0..0de9de3 100644 --- a/tests/test_vectorTest.expected_results +++ b/tests/test_vectorTest.expected_results @@ -11,5 +11,10 @@ Copied: 1 to 2 Destroyed: 1 delete vector Destroyed: 2 +hayyy +4.700000 +first +first +second done Destroyed: 0 diff --git a/tests/test_vectorTest.krak b/tests/test_vectorTest.krak index 8faffc9..67652c7 100644 --- a/tests/test_vectorTest.krak +++ b/tests/test_vectorTest.krak @@ -70,6 +70,21 @@ fun main(): int { desVec->addEnd(testDestruct); println("delete vector") delete(desVec); + + var newOne = vector("hayyy") + println(newOne[0]) + var noParam = vector() + noParam.add(4.7) + println(noParam[0]) + + var assignTest = vector("first") + println(assignTest[0]) + var toAssign = vector("first") + toAssign.add("second") + assignTest = toAssign + println(assignTest[0]) + println(assignTest[1]) + println("done") return 0;