Bugfixes, range(start,end,step), and beginning work on lexer and symbol
This commit is contained in:
@@ -113,7 +113,7 @@ term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor |
|
||||
factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\(" WS type WS "\)" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ;
|
||||
unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "[" WS expression WS "]" | lambda ;
|
||||
number = integer | floating_literal ;
|
||||
access_operation = unarad "." identifier | unarad "->" identifier | unarad "." identifier WS template_inst | unarad "->" identifier WS template_inst ;
|
||||
access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ;
|
||||
|
||||
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
|
||||
|
||||
@@ -444,6 +444,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
return output;
|
||||
}
|
||||
case for_loop:
|
||||
{
|
||||
// we push on a new vector to hold for stuff that might need a destructor call
|
||||
loopDistructStackDepth.push(distructDoubleStack.size());
|
||||
distructDoubleStack.push_back(std::vector<NodeTree<ASTData>*>());
|
||||
@@ -452,15 +453,37 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
// all of the inbetween scopes
|
||||
loopDeferStackDepth.push(deferDoubleStack.size());
|
||||
//The strSlice's are there to get ride of an unwanted return and an unwanted semicolon(s)
|
||||
output += "for (" + strSlice(generate(children[0], enclosingObject, true, enclosingFunction).oneString(),0,-3) + generate(children[1], enclosingObject, true, enclosingFunction).oneString() + ";" + strSlice(generate(children[2], enclosingObject, true, enclosingFunction).oneString(),0,-3) + ")";
|
||||
output += " {\n\t" + generate(children[3], enclosingObject, justFuncName, enclosingFunction).oneString();
|
||||
|
||||
std::string doUpdateName = "do_update" + getID();
|
||||
// INITIALIZER
|
||||
output += "{";
|
||||
output += generate(children[0], enclosingObject, true, enclosingFunction).oneString();
|
||||
output += "bool " + doUpdateName + " = false;\n";
|
||||
output += "for (;;) {";
|
||||
// UPDATE
|
||||
output += "if (" + doUpdateName + ") {";
|
||||
output += generate(children[2], enclosingObject, true, enclosingFunction).oneString();
|
||||
output += "}\n";
|
||||
output += doUpdateName + " = true;\n";
|
||||
// CONDITION
|
||||
// note that the postValue happens whether or not we break
|
||||
CCodeTriple condition = generate(children[1], enclosingObject, true, enclosingFunction);
|
||||
output += condition.preValue;
|
||||
output += "if (!(" + condition.value + ")) {\n";
|
||||
output += condition.postValue;
|
||||
output += "break;\n}";
|
||||
output += condition.postValue;
|
||||
// BODY
|
||||
output += generate(children[3], enclosingObject, justFuncName, enclosingFunction).oneString();
|
||||
output += emitDestructors(reverse(distructDoubleStack.back()),enclosingObject);
|
||||
output += + "}";
|
||||
output += "}";
|
||||
output += "}";
|
||||
distructDoubleStack.pop_back();
|
||||
loopDistructStackDepth.pop();
|
||||
// and pop it off again
|
||||
loopDeferStackDepth.pop();
|
||||
return output;
|
||||
}
|
||||
case return_statement:
|
||||
{
|
||||
// we pop off the vector and go through them in reverse emitting them, going
|
||||
@@ -716,11 +739,14 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
}
|
||||
// see if we should add a destructer call to this postValue
|
||||
Type* retType = children[0]->getDataRef()->valueType->returnType;
|
||||
if (methodExists(retType, "destruct", std::vector<Type>())) {
|
||||
if (retType->baseType != void_type) {
|
||||
// we always use return temps now :( (for psudo-pod objects that still have methods called on them, like range(1,3).for_each(...)
|
||||
std::string retTempName = "return_temp" + getID();
|
||||
output.preValue += ValueTypeToCType(retType, retTempName) + " = " + output.value + ";\n";
|
||||
output.value = retTempName;
|
||||
if (methodExists(retType, "destruct", std::vector<Type>())) {
|
||||
output.postValue = generateMethodIfExists(retType, "destruct", "&"+retTempName, std::vector<Type>()) + ";\n" + output.postValue;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
45
stdlib/lexer.krak
Normal file
45
stdlib/lexer.krak
Normal file
@@ -0,0 +1,45 @@
|
||||
import regex
|
||||
import symbol
|
||||
import string
|
||||
import vector
|
||||
import util
|
||||
|
||||
obj lexer {
|
||||
var regs: vector::vector<regex::regex>
|
||||
var input: string::string
|
||||
var position: int
|
||||
fun construct(): lexer* {
|
||||
regs.construct()
|
||||
input.construct()
|
||||
position = 0
|
||||
return this
|
||||
}
|
||||
fun destruct() {
|
||||
regs.destruct()
|
||||
input.destruct()
|
||||
}
|
||||
fun copy_construct(old: lexer*) {
|
||||
regs.copy_construct(&old->regs)
|
||||
input.copy_construct(&old->input)
|
||||
position = old->position
|
||||
}
|
||||
fun operator=(old: lexer) {
|
||||
destruct()
|
||||
copy_construct(&old)
|
||||
}
|
||||
fun add_regex(newOne: regex::regex) {
|
||||
regs.add(newOne)
|
||||
}
|
||||
fun set_input(in: string::string) {
|
||||
input = in
|
||||
}
|
||||
fun next(): symbol::symbol {
|
||||
var max = regs.map(fun(reg: regex::regex): util::pair<int, string::string> {
|
||||
return util::make_pair(reg.long_match(input.slice(position, -1)), reg.regexString); })
|
||||
.max(fun(first: util::pair<int, string::string>, second: util::pair<int, string::string>): bool
|
||||
{ return first.first < second.first; })
|
||||
position += max.first
|
||||
return symbol::symbol(input.slice(position-max.first, position), max.second, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,9 +52,10 @@ fun delete<T>(toDelete: T*, itemCount: int): void {
|
||||
fun delete<T(Object)>(toDelete: T*, itemCount: int): void {
|
||||
// start at one because the actual delete will call the destructor of the first one as it
|
||||
// finishes the pointer
|
||||
for (var i: int = 1; i < itemCount; i++;)
|
||||
for (var i: int = 0; i < itemCount; i++;)
|
||||
toDelete[i].destruct();
|
||||
delete<T>(toDelete);
|
||||
free<T>(toDelete);
|
||||
//delete<T>(toDelete);
|
||||
}
|
||||
|
||||
/* We specilize on the trait Object to decide on whether or not the destructor should be called */
|
||||
|
||||
@@ -51,7 +51,7 @@ obj regex(Object) {
|
||||
// init our begin, and the end state as the next state of each end
|
||||
begin = beginningAndEnd.first
|
||||
var end = mem::new<regexState>()->construct(conversions::to_char(1))
|
||||
beginningAndEnd.second.do(fun(it: regexState*): void { it->next_states.add(end); })
|
||||
beginningAndEnd.second.for_each(fun(it: regexState*): void { it->next_states.add(end); })
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ obj regex(Object) {
|
||||
i = perenEnd-1
|
||||
|
||||
if (alternating) {
|
||||
previous_end.do(fun(it: regexState*):void { it->next_states.add_all(innerBeginEnd.first->next_states); } )
|
||||
previous_end.for_each(fun(it: regexState*):void { it->next_states.add_all(innerBeginEnd.first->next_states); } )
|
||||
current_begin.add_all(innerBeginEnd.first->next_states)
|
||||
current_end.add_all(innerBeginEnd.second)
|
||||
} else {
|
||||
current_end.do(fun(it: regexState*):void { it->next_states.add_all(innerBeginEnd.first->next_states); } )
|
||||
current_end.for_each(fun(it: regexState*):void { it->next_states.add_all(innerBeginEnd.first->next_states); } )
|
||||
previous_begin = current_begin
|
||||
previous_end = current_end
|
||||
current_begin = innerBeginEnd.first->next_states
|
||||
@@ -129,11 +129,11 @@ obj regex(Object) {
|
||||
} else {
|
||||
var next = mem::new<regexState>()->construct(regex_string[i])
|
||||
if (alternating) {
|
||||
previous_end.do(fun(it: regexState*):void { it->next_states.add(next); })
|
||||
previous_end.for_each(fun(it: regexState*):void { it->next_states.add(next); })
|
||||
current_begin.add(next)
|
||||
current_end.add(next)
|
||||
} else {
|
||||
current_end.do(fun(it: regexState*):void { it->next_states.add(next); })
|
||||
current_end.for_each(fun(it: regexState*):void { it->next_states.add(next); })
|
||||
previous_begin = current_begin
|
||||
previous_end = current_end
|
||||
current_begin = vector::vector(next)
|
||||
|
||||
@@ -14,7 +14,7 @@ fun set<T>(item: T): set<T> {
|
||||
|
||||
fun from_vector<T>(items: vector::vector<T>): set<T> {
|
||||
var toRet.construct() : set<T>
|
||||
items.do( fun(item: T) toRet.add(item); )
|
||||
items.for_each( fun(item: T) toRet.add(item); )
|
||||
return toRet
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ obj set<T> {
|
||||
data.remove(idx)
|
||||
}
|
||||
fun for_each(func: fun(T):void) {
|
||||
data.do(func)
|
||||
data.for_each(func)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import vector
|
||||
import util
|
||||
import mem
|
||||
|
||||
fun string(in:char*):string {
|
||||
@@ -25,6 +26,9 @@ obj string (Object) {
|
||||
data.copy_construct(&vec);
|
||||
return this;
|
||||
}
|
||||
fun construct(str: string): string* {
|
||||
return construct(str.data);
|
||||
}
|
||||
|
||||
fun copy_construct(old: string*): void {
|
||||
data.copy_construct(&old->data)
|
||||
@@ -61,17 +65,32 @@ obj string (Object) {
|
||||
}
|
||||
fun length():int { return data.size; }
|
||||
|
||||
fun operator==(other: string): bool {
|
||||
return length() == other.length() && !util::range(length()).any_true(fun(i: int):bool { return data[i] != other[i]; } )
|
||||
}
|
||||
|
||||
fun operator+(str: char*): string {
|
||||
var newStr.construct(str):string
|
||||
var ret.construct(data + newStr.data):string
|
||||
return ret
|
||||
}
|
||||
|
||||
fun operator+(str: string): string {
|
||||
var newStr.construct(str):string
|
||||
var ret.construct(data + newStr.data):string
|
||||
return ret
|
||||
}
|
||||
|
||||
fun operator+=(str: char*): void {
|
||||
var newStr.construct(str):string
|
||||
data += newStr.data
|
||||
}
|
||||
|
||||
fun operator+=(str: string): void {
|
||||
var newStr.construct(str):string
|
||||
data += newStr.data
|
||||
}
|
||||
|
||||
fun toCharArray(): char* {
|
||||
var out: char* = mem::new<char>(data.size+1);
|
||||
for (var i: int = 0; i < data.size; i++;)
|
||||
|
||||
54
stdlib/symbol.krak
Normal file
54
stdlib/symbol.krak
Normal file
@@ -0,0 +1,54 @@
|
||||
import string
|
||||
|
||||
fun symbol(dataIn: char*, nameIn: char*, terminalIn: bool): symbol {
|
||||
var toRet.construct(string::string(dataIn), string::string(nameIn), terminalIn): symbol
|
||||
return toRet
|
||||
}
|
||||
|
||||
fun symbol(dataIn: string::string, nameIn: string::string, terminalIn: bool): symbol {
|
||||
var toRet.construct(dataIn, nameIn, terminalIn): symbol
|
||||
return toRet
|
||||
}
|
||||
|
||||
obj symbol {
|
||||
var data: string::string
|
||||
var name: string::string
|
||||
var terminal: bool
|
||||
|
||||
fun construct(): symbol* {
|
||||
data.construct()
|
||||
name.construct()
|
||||
return this
|
||||
}
|
||||
fun construct(dataIn: string::string, nameIn: string::string, terminalIn: bool): symbol* {
|
||||
data.construct(dataIn)
|
||||
name.construct(nameIn)
|
||||
terminal = terminalIn
|
||||
return this
|
||||
}
|
||||
fun destruct() {
|
||||
data.destruct()
|
||||
name.destruct()
|
||||
}
|
||||
fun copy_construct(old: symbol*) {
|
||||
data.copy_construct(&old->data)
|
||||
name.copy_construct(&old->name)
|
||||
terminal = old->terminal
|
||||
}
|
||||
fun operator=(old: symbol) {
|
||||
destruct()
|
||||
copy_construct(&old)
|
||||
}
|
||||
fun operator==(other: symbol): bool {
|
||||
return data == other.data && name == other.name && terminal == other.terminal;
|
||||
}
|
||||
fun to_string(): string::string {
|
||||
var terminalString: char*
|
||||
if (terminal)
|
||||
terminalString = "true"
|
||||
else
|
||||
terminalString = "false"
|
||||
return name + ": " + data + " " + terminalString
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,3 +44,38 @@ obj pair<T,U>(Object) {
|
||||
}
|
||||
}
|
||||
|
||||
fun range(end:int): range {
|
||||
var toRet.construct(0, end, 1): range
|
||||
return toRet
|
||||
}
|
||||
|
||||
fun range(begin: int, end:int): range {
|
||||
var toRet.construct(begin, end, 1): range
|
||||
return toRet
|
||||
}
|
||||
fun range(begin: int, end:int, step: int): range {
|
||||
var toRet.construct(begin, end, step): range
|
||||
return toRet
|
||||
}
|
||||
|
||||
obj range {
|
||||
var begin: int
|
||||
var end: int
|
||||
var step: int
|
||||
fun construct(beginIn: int, endIn: int, stepIn: int) : range* {
|
||||
begin = beginIn
|
||||
end = endIn
|
||||
step = stepIn
|
||||
}
|
||||
fun for_each(func: fun(int):void):void {
|
||||
for (var i = begin; i < end; i+= step;)
|
||||
func(i)
|
||||
}
|
||||
fun any_true(func: fun(int):bool):bool {
|
||||
for (var i = begin; i < end; i+= step;)
|
||||
if (func(i))
|
||||
return true
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,14 +169,10 @@ obj vector<T> (Object) {
|
||||
size--
|
||||
}
|
||||
|
||||
fun do(func: fun(T):void):void {
|
||||
fun for_each(func: fun(T):void):void {
|
||||
for (var i = 0; i < size; i++;)
|
||||
func(data[i])
|
||||
}
|
||||
fun do<U>(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])
|
||||
@@ -196,15 +192,6 @@ obj vector<T> (Object) {
|
||||
}
|
||||
return newVec
|
||||
}
|
||||
fun flatten_map<U,V>(func: fun(T,V):vector<U>, extraParam:V):vector<U> {
|
||||
var newVec.construct(): vector<U>
|
||||
for (var i = 0; i < size; i++;) {
|
||||
var to_add = func(data[i], extraParam)
|
||||
for (var j = 0; j < to_add.size; j++;)
|
||||
newVec.addEnd(to_add.get(j))
|
||||
}
|
||||
return newVec
|
||||
}
|
||||
fun filter(func: fun(T):bool):vector<T> {
|
||||
var newVec.construct(): vector<T>
|
||||
for (var i = 0; i < size; i++;)
|
||||
@@ -212,18 +199,18 @@ obj vector<T> (Object) {
|
||||
newVec.addEnd(data[i])
|
||||
return newVec
|
||||
}
|
||||
fun filter<U>(func: fun(T,U):bool, extraParam: U):vector<T> {
|
||||
var newVec.construct(): vector<T>
|
||||
for (var i = 0; i < size; i++;)
|
||||
if (func(data[i], extraParam))
|
||||
newVec.addEnd(data[i])
|
||||
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
|
||||
}
|
||||
fun max(func: fun(T,T):bool): T {
|
||||
var maxIdx = 0
|
||||
for (var i = 1; i < size; i++;)
|
||||
if (func(data[maxIdx], data[i]))
|
||||
maxIdx = i
|
||||
return data[maxIdx]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import io:*
|
||||
import vector:*
|
||||
|
||||
fun onlyMatch(vec: vector<int>, matchWith: int): vector<int> {
|
||||
return vec.filter(fun(it:int, other:int):bool { return it == other; }, matchWith)
|
||||
return vec.filter(fun(it:int):bool { return it == matchWith; })
|
||||
}
|
||||
|
||||
fun main():int {
|
||||
|
||||
2
tests/test_lexer.expected_results
Normal file
2
tests/test_lexer.expected_results
Normal file
@@ -0,0 +1,2 @@
|
||||
a+: aaaa true
|
||||
test: test true
|
||||
16
tests/test_lexer.krak
Normal file
16
tests/test_lexer.krak
Normal file
@@ -0,0 +1,16 @@
|
||||
import lexer:*
|
||||
import regex:*
|
||||
import string:*
|
||||
import symbol:*
|
||||
import io:*
|
||||
|
||||
fun main(): int {
|
||||
var lex.construct(): lexer
|
||||
lex.set_input(string("aaaatesta"))
|
||||
lex.add_regex(regex("a+"))
|
||||
lex.add_regex(regex("test"))
|
||||
println(lex.next().to_string())
|
||||
println(lex.next().to_string())
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -7,3 +7,5 @@ hope3
|
||||
new way!
|
||||
a
|
||||
now win!
|
||||
true
|
||||
false
|
||||
|
||||
@@ -20,6 +20,8 @@ fun main(): int {
|
||||
newWay[5] = 'i'
|
||||
newWay[6] = 'n'
|
||||
io::println(newWay)
|
||||
io::println( string::string("yes") == string::string("yes") )
|
||||
io::println( string::string("no") == string::string("yes") )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
7.000000
|
||||
2
|
||||
8.000000
|
||||
36912
|
||||
234567
|
||||
false
|
||||
true
|
||||
3
|
||||
hi
|
||||
construct
|
||||
|
||||
@@ -31,6 +31,13 @@ fun main():int {
|
||||
println(greater(1,2))
|
||||
println(greater(7.0,8.0))
|
||||
|
||||
range(3,13, 3).for_each(fun(i: int) { print(i); })
|
||||
println()
|
||||
range(2,8).for_each(fun(i: int) { print(i); })
|
||||
println()
|
||||
println(range(2,8,2).any_true(fun(i: int): bool { return i%2 == 1; } ))
|
||||
println(range(3).any_true(fun(i: int): bool { return i%2 == 1; } ))
|
||||
|
||||
var oddPair = make_pair(3, "hi")
|
||||
println(oddPair.first)
|
||||
println(oddPair.second)
|
||||
|
||||
@@ -71,9 +71,9 @@ Copied: 305 to 306
|
||||
Copied: 306 to 307
|
||||
Destroyed: 306
|
||||
Destroyed: 305
|
||||
Destroyed: 104
|
||||
Destroyed: 204
|
||||
Destroyed: 304
|
||||
Destroyed: 104
|
||||
Destroyed: 301
|
||||
Destroyed: 201
|
||||
Destroyed: 101
|
||||
@@ -92,15 +92,15 @@ Copied: 308 to 309
|
||||
Copied: 309 to 310
|
||||
Destroyed: 309
|
||||
Destroyed: 308
|
||||
Destroyed: 107
|
||||
Destroyed: 207
|
||||
Destroyed: 307
|
||||
Destroyed: 107
|
||||
Destroyed: 210
|
||||
Copied: 310 to 311
|
||||
Destroyed: 310
|
||||
done
|
||||
Destroyed: 311
|
||||
Destroyed: 110
|
||||
Destroyed: 311
|
||||
Destroyed: 300
|
||||
Destroyed: 200
|
||||
Destroyed: 100
|
||||
|
||||
@@ -52,7 +52,7 @@ fun main(): int {
|
||||
for (var i: int = 0; i < intVec.size; i++;)
|
||||
print(intVec.at(i));
|
||||
println();
|
||||
intVec.do(fun(it:int):void print(it+7);)
|
||||
intVec.for_each(fun(it:int):void print(it+7);)
|
||||
println();
|
||||
|
||||
var subd = intVec.map(fun(it:int):int { return it-1; })
|
||||
@@ -90,19 +90,19 @@ fun main(): int {
|
||||
sliceTest.add(3)
|
||||
sliceTest.add(4)
|
||||
print("full: ")
|
||||
sliceTest.do(fun(it:int):void print(it);)
|
||||
sliceTest.for_each(fun(it:int):void print(it);)
|
||||
println()
|
||||
print("middle: ")
|
||||
sliceTest.slice(1,-2).do(fun(it:int):void print(it);)
|
||||
sliceTest.slice(1,-2).for_each(fun(it:int):void print(it);)
|
||||
println()
|
||||
print("all but first: ")
|
||||
sliceTest.slice(1,-1).do(fun(it:int):void print(it);)
|
||||
sliceTest.slice(1,-1).for_each(fun(it:int):void print(it);)
|
||||
println()
|
||||
print("all but last: ")
|
||||
sliceTest.slice(0,-2).do(fun(it:int):void print(it);)
|
||||
sliceTest.slice(0,-2).for_each(fun(it:int):void print(it);)
|
||||
println()
|
||||
print("just some: ")
|
||||
sliceTest.slice(1,2).do(fun(it:int):void print(it);)
|
||||
sliceTest.slice(1,2).for_each(fun(it:int):void print(it);)
|
||||
println()
|
||||
|
||||
println("find test")
|
||||
@@ -116,10 +116,10 @@ fun main(): int {
|
||||
setTest.add(7)
|
||||
setTest.set(1,8)
|
||||
setTest[2] = 9
|
||||
setTest.do(fun(it: int) println(it);)
|
||||
setTest.for_each(fun(it: int) println(it);)
|
||||
println("delete")
|
||||
setTest.remove(2)
|
||||
setTest.do(fun(it: int) println(it);)
|
||||
setTest.for_each(fun(it: int) println(it);)
|
||||
|
||||
println("delete v2")
|
||||
var firstRem.construct(100): AbleToBeDestroyed;
|
||||
|
||||
Reference in New Issue
Block a user