Saving work pre-references
This commit is contained in:
@@ -3,7 +3,7 @@ cmake_minimum_required (VERSION 2.6)
|
|||||||
project(Kraken)
|
project(Kraken)
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||||
|
|
||||||
set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include)
|
set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include)
|
||||||
|
|||||||
@@ -65,9 +65,11 @@ right_shift = ">" ">" ;
|
|||||||
overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "[]" | "[]=" ;
|
overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "[]" | "[]=" ;
|
||||||
func_identifier = identifier | identifier overloadable_operator ;
|
func_identifier = identifier | identifier overloadable_operator ;
|
||||||
# allow omitting of return type (automatic void)
|
# allow omitting of return type (automatic void)
|
||||||
typed_return = dec_type | ;
|
|
||||||
function = "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" WS typed_return WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS typed_return WS statement ;
|
# HACKY - typed_return has it's own internal whitespace as to not make WS typed_return-reduces to null WS ambigious
|
||||||
lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" WS typed_return WS statement ;
|
typed_return = WS dec_type | ;
|
||||||
|
function = "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ;
|
||||||
|
lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ;
|
||||||
|
|
||||||
opt_typed_parameter_list = typed_parameter_list | ;
|
opt_typed_parameter_list = typed_parameter_list | ;
|
||||||
typed_parameter_list = typed_parameter_list WS "," WS typed_parameter | typed_parameter ;
|
typed_parameter_list = typed_parameter_list WS "," WS typed_parameter | typed_parameter ;
|
||||||
|
|||||||
@@ -389,7 +389,12 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
} else {
|
} else {
|
||||||
auto possibleMatches = scopeLookup(scope, lookupName);
|
auto possibleMatches = scopeLookup(scope, lookupName);
|
||||||
if (!possibleMatches.size()) {
|
if (!possibleMatches.size()) {
|
||||||
|
std::cerr << std::endl;
|
||||||
std::cerr << "scope lookup error! Could not find " << lookupName << " in identifier (scopeLookup)" << std::endl;
|
std::cerr << "scope lookup error! Could not find " << lookupName << " in identifier (scopeLookup)" << std::endl;
|
||||||
|
std::cerr << "lookup failedin file " << getUpperTranslationUnit(scope)->getDataRef()->symbol.getName() << std::endl;
|
||||||
|
std::cerr << "note that this might not be the file where the error is" << std::endl;
|
||||||
|
std::cerr << "obj.non_existant_member would fail in the file that defines obj's type, for instance" << std::endl;
|
||||||
|
std::cerr << std::endl;
|
||||||
throw "LOOKUP ERROR: " + lookupName;
|
throw "LOOKUP ERROR: " + lookupName;
|
||||||
}
|
}
|
||||||
// can't cull out functiokns b/c we might want them as values
|
// can't cull out functiokns b/c we might want them as values
|
||||||
|
|||||||
@@ -636,9 +636,23 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
if (name == "[]")
|
if (name == "[]")
|
||||||
return "(" + generate(children[1], enclosingObject, true, enclosingFunction) + ")[" + generate(children[2],enclosingObject, true, enclosingFunction) + "]";
|
return "(" + generate(children[1], enclosingObject, true, enclosingFunction) + ")[" + generate(children[2],enclosingObject, true, enclosingFunction) + "]";
|
||||||
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!="
|
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!="
|
||||||
|| name == "<" || name == ">" || name == "%" || name == "=" || name == "+=" || name == "-=" || name == "*=" || name == "/=" || name == "||"
|
|| name == "<" || name == ">" || name == "%" || name == "=" || name == "+=" || name == "-=" || name == "*=" || name == "/=") {
|
||||||
|| name == "&&") {
|
|
||||||
return "((" + generate(children[1], enclosingObject, true, enclosingFunction) + ")" + name + "(" + generate(children[2], enclosingObject, true, enclosingFunction) + "))";
|
return "((" + generate(children[1], enclosingObject, true, enclosingFunction) + ")" + name + "(" + generate(children[2], enclosingObject, true, enclosingFunction) + "))";
|
||||||
|
} else if (name == "&&" || name == "||") {
|
||||||
|
// b/c short circuiting, these have to be done seperately
|
||||||
|
CCodeTriple lhs = generate(children[1], enclosingObject, true, enclosingFunction);
|
||||||
|
CCodeTriple rhs = generate(children[2], enclosingObject, true, enclosingFunction);
|
||||||
|
output.preValue = lhs.preValue;
|
||||||
|
std::string shortcircuit_result = "shortcircuit_result" + getID();
|
||||||
|
output.preValue += "bool " + shortcircuit_result + " = " + lhs.value + ";\n";
|
||||||
|
output.preValue += lhs.postValue;
|
||||||
|
output.preValue += "if (" + std::string(name == "||" ? "!":"") + shortcircuit_result + ") { \n";
|
||||||
|
output.preValue += rhs.preValue;
|
||||||
|
output.preValue += shortcircuit_result + " = " + rhs.value + ";\n";
|
||||||
|
output.preValue += rhs.postValue;
|
||||||
|
output.preValue += "}\n";
|
||||||
|
output.value = shortcircuit_result;
|
||||||
|
return output;
|
||||||
} else if (name == "." || name == "->") {
|
} else if (name == "." || name == "->") {
|
||||||
if (children.size() == 1)
|
if (children.size() == 1)
|
||||||
return "/*dot operation with one child*/" + generate(children[0], enclosingObject, true, enclosingFunction).oneString() + "/*end one child*/";
|
return "/*dot operation with one child*/" + generate(children[0], enclosingObject, true, enclosingFunction).oneString() + "/*end one child*/";
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import string
|
import string
|
||||||
import vector
|
import vector
|
||||||
import set
|
import set
|
||||||
|
import map
|
||||||
import symbol
|
import symbol
|
||||||
import regex
|
import regex
|
||||||
import io
|
import io
|
||||||
@@ -68,9 +69,10 @@ fun load_grammer(gram_str: string::string): grammer {
|
|||||||
rightSide = vector::vector<symbol::symbol>()
|
rightSide = vector::vector<symbol::symbol>()
|
||||||
doLeftSide = true
|
doLeftSide = true
|
||||||
} else {
|
} else {
|
||||||
if (doLeftSide)
|
if (doLeftSide) {
|
||||||
leftSide = symbol::symbol(word, true)
|
leftSide = symbol::symbol(word, true)
|
||||||
else
|
gram.non_terminals.add(leftSide)
|
||||||
|
} else {
|
||||||
if (word[0] == '"') {
|
if (word[0] == '"') {
|
||||||
// ok, we support both plain terminals "hia*"
|
// ok, we support both plain terminals "hia*"
|
||||||
// and decorated terminals "hia*":hi_with_as
|
// and decorated terminals "hia*":hi_with_as
|
||||||
@@ -78,13 +80,18 @@ fun load_grammer(gram_str: string::string): grammer {
|
|||||||
// the end of the string
|
// the end of the string
|
||||||
var last_quote = word.length()-1
|
var last_quote = word.length()-1
|
||||||
while(word[last_quote] != '"') last_quote--
|
while(word[last_quote] != '"') last_quote--
|
||||||
rightSide.add(symbol::symbol(word.slice(1,last_quote), true))
|
if (last_quote != word.length()-1) {
|
||||||
if (last_quote != word.length()-1)
|
rightSide.add(symbol::symbol(word.slice(last_quote+2, -1), true))
|
||||||
gram.regexs.add(util::make_pair(word.slice(last_quote+2, -1), regex::regex(word.slice(1,last_quote))))
|
gram.terminals.add(util::make_pair(symbol::symbol(word.slice(last_quote+2, -1), true), regex::regex(word.slice(1,last_quote))))
|
||||||
else
|
|
||||||
gram.regexs.add(util::make_pair(word, regex::regex(word.slice(1,last_quote))))
|
|
||||||
} else {
|
} else {
|
||||||
rightSide.add(symbol::symbol(word, false))
|
rightSide.add(symbol::symbol(word, true))
|
||||||
|
gram.terminals.add(util::make_pair(symbol::symbol(word, true), regex::regex(word.slice(1,last_quote))))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var non_term = symbol::symbol(word, false)
|
||||||
|
rightSide.add(non_term)
|
||||||
|
gram.non_terminals.add(non_term)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
doLeftSide = false
|
doLeftSide = false
|
||||||
}
|
}
|
||||||
@@ -94,15 +101,21 @@ fun load_grammer(gram_str: string::string): grammer {
|
|||||||
|
|
||||||
obj grammer (Object) {
|
obj grammer (Object) {
|
||||||
var rules: vector::vector<rule>
|
var rules: vector::vector<rule>
|
||||||
var regexs: vector::vector<util::pair<string::string, regex::regex>>
|
var non_terminals: set::set<symbol::symbol>
|
||||||
|
var terminals: vector::vector<util::pair<symbol::symbol, regex::regex>>
|
||||||
|
var first_set_map: map::map<symbol::symbol, set::set<symbol::symbol>>
|
||||||
|
|
||||||
fun construct(): *grammer {
|
fun construct(): *grammer {
|
||||||
rules.construct()
|
rules.construct()
|
||||||
regexs.construct()
|
non_terminals.construct()
|
||||||
|
terminals.construct()
|
||||||
|
first_set_map.construct()
|
||||||
}
|
}
|
||||||
fun copy_construct(old: *grammer) {
|
fun copy_construct(old: *grammer) {
|
||||||
rules.copy_construct(&old->rules)
|
rules.copy_construct(&old->rules)
|
||||||
regexs.copy_construct(&old->regexs)
|
non_terminals.copy_construct(&old->non_terminals)
|
||||||
|
terminals.copy_construct(&old->terminals)
|
||||||
|
first_set_map.copy_construct(&old->first_set_map)
|
||||||
}
|
}
|
||||||
fun operator=(other: grammer) {
|
fun operator=(other: grammer) {
|
||||||
destruct()
|
destruct()
|
||||||
@@ -110,14 +123,71 @@ obj grammer (Object) {
|
|||||||
}
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
rules.destruct()
|
rules.destruct()
|
||||||
regexs.destruct()
|
non_terminals.destruct()
|
||||||
|
terminals.destruct()
|
||||||
|
first_set_map.destruct()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun calculate_first_set() {
|
||||||
|
// the first set of a terminal is itself
|
||||||
|
terminals.for_each( fun(terminal: util::pair<symbol::symbol, regex::regex>)
|
||||||
|
first_set_map[terminal.first] = set::set(terminal.first)
|
||||||
|
)
|
||||||
|
// start out the non-terminals as empty sets
|
||||||
|
non_terminals.for_each( fun(non_terminal: symbol::symbol)
|
||||||
|
first_set_map[non_terminal] = set::set<symbol::symbol>()
|
||||||
|
)
|
||||||
|
var first_helper = fun(rhs: vector::vector<symbol::symbol>): set::set<symbol::symbol> {
|
||||||
|
var toRet = set::set<symbol::symbol>()
|
||||||
|
rhs.for_each(fun(sym: symbol::symbol) {
|
||||||
|
toRet.add(first_set_map[sym])
|
||||||
|
})
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
var changed = true
|
||||||
|
while (changed) {
|
||||||
|
io::println("//////////current state of map/////////////")
|
||||||
|
first_set_map.keys.for_each(fun(sym: symbol::symbol) {
|
||||||
|
io::print("for ")
|
||||||
|
io::println(sym.to_string())
|
||||||
|
io::println("map is:")
|
||||||
|
first_set_map[sym].for_each(fun(look: symbol::symbol) {
|
||||||
|
io::print("lookahead: "); io::println(look.to_string())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
changed = false
|
||||||
|
rules.for_each( fun(r: rule) {
|
||||||
|
var rule_lookahead = first_helper(r.rhs)
|
||||||
|
if (!changed) {
|
||||||
|
io::println(r.to_string())
|
||||||
|
changed = !first_set_map[r.lhs].contains(rule_lookahead)
|
||||||
|
io::print("changed: "); io::println(changed)
|
||||||
|
io::print("\tcurrent lookahead is sized:")
|
||||||
|
io::println(first_set_map[r.lhs].size())
|
||||||
|
io::println("\tcurrent lookahead is:")
|
||||||
|
first_set_map[r.lhs].for_each(fun(look: symbol::symbol) {
|
||||||
|
io::print("\t\tlookahead: "); io::println(look.to_string())
|
||||||
|
})
|
||||||
|
io::println()
|
||||||
|
io::print("\rule lookahead is sized:")
|
||||||
|
io::println(rule_lookahead.size())
|
||||||
|
io::println("\trule lookahead is:")
|
||||||
|
rule_lookahead.for_each(fun(look: symbol::symbol) {
|
||||||
|
io::print("\t\tlookahead: "); io::println(look.to_string())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
first_set_map[r.lhs].add(rule_lookahead)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun to_string(): string::string {
|
fun to_string(): string::string {
|
||||||
var result = string::string("grammer rules:")
|
var result = string::string("grammer rules:")
|
||||||
rules.for_each( fun(i : rule) { result += string::string("\n\t") + i.to_string(); } )
|
rules.for_each( fun(i : rule) { result += string::string("\n\t") + i.to_string(); } )
|
||||||
result += "\nregexs:"
|
result += "\nnon_terminals:"
|
||||||
regexs.for_each( fun(i : util::pair<string::string, regex::regex>) { result += string::string("\n\t") + i.first + ": " + i.second.regexString; } )
|
non_terminals.for_each( fun(i : symbol::symbol) { result += string::string("\n\t") + i.to_string(); } )
|
||||||
|
result += "\nterminals:"
|
||||||
|
terminals.for_each( fun(i : util::pair<symbol::symbol, regex::regex>) { result += string::string("\n\t") + i.first.to_string() + ": " + i.second.regexString; } )
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,20 @@ import vector
|
|||||||
import util
|
import util
|
||||||
|
|
||||||
fun lexer(regs: vector::vector<regex::regex>): lexer {
|
fun lexer(regs: vector::vector<regex::regex>): lexer {
|
||||||
return lexer(regs.map( fun(reg: regex::regex): util::pair<string::string, regex::regex> {
|
/*var toRet:lexer*/
|
||||||
return util::make_pair(reg.regexString,reg)
|
var toRet.construct() :lexer
|
||||||
}))
|
regs.for_each( fun(reg: regex::regex) {
|
||||||
|
toRet.add_regex(util::make_pair(reg.regexString, reg));
|
||||||
|
})
|
||||||
|
return toRet
|
||||||
}
|
}
|
||||||
|
|
||||||
fun lexer(regs: vector::vector<util::pair<string::string, regex::regex>>): lexer {
|
fun lexer(regs: vector::vector<util::pair<symbol::symbol, regex::regex>>): lexer {
|
||||||
|
/*var toRet:lexer*/
|
||||||
var toRet.construct() :lexer
|
var toRet.construct() :lexer
|
||||||
regs.for_each( fun(reg: util::pair<string::string, regex::regex>) toRet.add_regex(reg); )
|
regs.for_each( fun(reg: util::pair<symbol::symbol, regex::regex>)
|
||||||
|
toRet.add_regex(util::make_pair(reg.first.name, reg.second));
|
||||||
|
)
|
||||||
return toRet
|
return toRet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ obj set<T> (Object) {
|
|||||||
fun size():int {
|
fun size():int {
|
||||||
return data.size
|
return data.size
|
||||||
}
|
}
|
||||||
|
fun contains(items: set<T>): bool {
|
||||||
|
return items.size() == 0 || !items.any_true( fun(item: T): bool return !contains(item); )
|
||||||
|
}
|
||||||
fun contains(item: T): bool {
|
fun contains(item: T): bool {
|
||||||
return data.find(item) != -1
|
return data.find(item) != -1
|
||||||
}
|
}
|
||||||
@@ -65,5 +68,8 @@ obj set<T> (Object) {
|
|||||||
fun for_each(func: fun(T):void) {
|
fun for_each(func: fun(T):void) {
|
||||||
data.for_each(func)
|
data.for_each(func)
|
||||||
}
|
}
|
||||||
|
fun any_true(func: fun(T):bool):bool {
|
||||||
|
return data.any_true(func)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ obj vector<T> (Object) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun copy_construct(old: *vector<T>): void {
|
fun copy_construct(old: *vector<T>): void {
|
||||||
construct()
|
construct()
|
||||||
for (var i = 0; i < old->size; i++;)
|
for (var i = 0; i < old->size; i++;)
|
||||||
|
|||||||
@@ -11,3 +11,6 @@ d = "has
|
|||||||
ll\"
|
ll\"
|
||||||
\\\"y8\" \\\\" ;
|
\\\"y8\" \\\\" ;
|
||||||
d = "has space" ;
|
d = "has space" ;
|
||||||
|
d = e ;
|
||||||
|
e = f | ;
|
||||||
|
f = ;
|
||||||
|
|||||||
@@ -3,15 +3,41 @@ import grammer:*
|
|||||||
import lexer:*
|
import lexer:*
|
||||||
import string:*
|
import string:*
|
||||||
import util:*
|
import util:*
|
||||||
|
import symbol:*
|
||||||
|
|
||||||
fun main():int {
|
fun main():int {
|
||||||
var a = load_grammer(read_file(string("../krakenGrammer.kgm")))
|
|
||||||
/*var a = load_grammer(read_file(string("grammer.kgm")))*/
|
/*var a = load_grammer(read_file(string("../krakenGrammer.kgm")))*/
|
||||||
|
var a = load_grammer(read_file(string("grammer.kgm")))
|
||||||
println(a.to_string())
|
println(a.to_string())
|
||||||
var lex = lexer(a.regexs)
|
/*a.calculate_first_set()*/
|
||||||
lex.set_input(read_file(string("test_grammer.krak")))
|
println("///////////////////START FIRST SET/////////////")
|
||||||
/*lex.set_input(string("ccdahas spacedhas*/
|
println("//TERMINALS//")
|
||||||
/*returndaaaaaaaaaaaaaa"))*/
|
a.terminals.for_each( fun(terminal: util::pair<symbol::symbol, regex::regex>) {
|
||||||
|
var set_str = string::string("{ ")
|
||||||
|
a.first_set_map[terminal.first].for_each( fun(sym: symbol::symbol) {
|
||||||
|
set_str += sym.to_string() + " "
|
||||||
|
})
|
||||||
|
set_str += "}"
|
||||||
|
print(terminal.first.to_string() + " first: " + set_str + "\n")
|
||||||
|
})
|
||||||
|
println("//NON TERMINALS//")
|
||||||
|
a.non_terminals.for_each( fun(non_terminal: symbol::symbol) {
|
||||||
|
var set_str = string::string("{ ")
|
||||||
|
a.first_set_map[non_terminal].for_each( fun(sym: symbol::symbol) {
|
||||||
|
set_str += sym.to_string() + " "
|
||||||
|
})
|
||||||
|
set_str += "}"
|
||||||
|
print(non_terminal.to_string() + " first: " + set_str + "\n")
|
||||||
|
println()
|
||||||
|
})
|
||||||
|
println("///////////////////END FIRST SET/////////////")
|
||||||
|
|
||||||
|
var lex = lexer(a.terminals)
|
||||||
|
|
||||||
|
/*lex.set_input(read_file(string("test_grammer.krak")))*/
|
||||||
|
lex.set_input(string("ccdahas spacedhas
|
||||||
|
returndaaaaaaaaaaaaaa"))
|
||||||
println("woo lexing:")
|
println("woo lexing:")
|
||||||
range(8).for_each(fun(i: int) { println(lex.next().to_string()); } )
|
range(8).for_each(fun(i: int) { println(lex.next().to_string()); } )
|
||||||
/*range(80).for_each(fun(i: int) { println(lex.next().to_string()); } )*/
|
/*range(80).for_each(fun(i: int) { println(lex.next().to_string()); } )*/
|
||||||
|
|||||||
@@ -9,5 +9,10 @@ false
|
|||||||
false
|
false
|
||||||
true
|
true
|
||||||
true
|
true
|
||||||
|
contains set:
|
||||||
|
false
|
||||||
|
false
|
||||||
|
true
|
||||||
|
all:
|
||||||
4
|
4
|
||||||
5
|
5
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import io:*
|
import io:*
|
||||||
import set:*
|
import set:*
|
||||||
|
import vector_literals:*
|
||||||
|
|
||||||
fun main():int {
|
fun main():int {
|
||||||
var s = set(3)
|
var s = set(3)
|
||||||
@@ -19,6 +20,12 @@ fun main():int {
|
|||||||
println(s.contains(4))
|
println(s.contains(4))
|
||||||
println(s.contains(5))
|
println(s.contains(5))
|
||||||
|
|
||||||
|
println("contains set:")
|
||||||
|
println(s.contains(from_vector(vector(1,2,3))))
|
||||||
|
println(s.contains(from_vector(vector(4,5,3))))
|
||||||
|
println(s.contains(from_vector(vector(4,5))))
|
||||||
|
|
||||||
|
println("all:")
|
||||||
s.for_each( fun(it: int) println(it); )
|
s.for_each( fun(it: int) println(it); )
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
8
tests/test_short_circuit.expected_results
Normal file
8
tests/test_short_circuit.expected_results
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
early or
|
||||||
|
was true
|
||||||
|
early and
|
||||||
|
|
||||||
|
late or
|
||||||
|
false_extra: was true
|
||||||
|
late and
|
||||||
|
true_extra:
|
||||||
38
tests/test_short_circuit.krak
Normal file
38
tests/test_short_circuit.krak
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import io:*
|
||||||
|
|
||||||
|
fun is_true():bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun is_true_extra():bool {
|
||||||
|
print("true_extra: ")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun is_false():bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun is_false_extra():bool {
|
||||||
|
print("false_extra: ")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
println("early or")
|
||||||
|
if (is_true() || is_false_extra())
|
||||||
|
println("was true")
|
||||||
|
println("early and")
|
||||||
|
if (is_false() && is_true_extra())
|
||||||
|
println("was false")
|
||||||
|
println()
|
||||||
|
println("late or")
|
||||||
|
if (is_false_extra() || is_true())
|
||||||
|
println("was true")
|
||||||
|
println("late and")
|
||||||
|
if (is_true_extra() && is_false())
|
||||||
|
println("was false")
|
||||||
|
println()
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user