Experimenting with fungll optimization, implement the okmij.org poly-variadic fix-point combinator for mutual recursion
This commit is contained in:
26
fungll.krak
26
fungll.krak
@@ -2,6 +2,7 @@ import vec:*
|
|||||||
import vec_literals:*
|
import vec_literals:*
|
||||||
import map:*
|
import map:*
|
||||||
import set:*
|
import set:*
|
||||||
|
import hash_set
|
||||||
import util:*
|
import util:*
|
||||||
import str:*
|
import str:*
|
||||||
import regex:*
|
import regex:*
|
||||||
@@ -216,7 +217,7 @@ fun pending(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int): Pen
|
|||||||
var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left): Pending
|
var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left): Pending
|
||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
obj Descriptor (Object) {
|
obj Descriptor (Object, Hashable) {
|
||||||
var nonterminal: int
|
var nonterminal: int
|
||||||
var rule_idx: int
|
var rule_idx: int
|
||||||
var idx_into_rule: int
|
var idx_into_rule: int
|
||||||
@@ -248,6 +249,10 @@ obj Descriptor (Object) {
|
|||||||
fun operator==(rhs: ref Descriptor): bool {
|
fun operator==(rhs: ref Descriptor): bool {
|
||||||
return nonterminal == rhs.nonterminal && rule_idx == rhs.rule_idx && idx_into_rule == rhs.idx_into_rule && left == rhs.left && pivot == rhs.pivot
|
return nonterminal == rhs.nonterminal && rule_idx == rhs.rule_idx && idx_into_rule == rhs.idx_into_rule && left == rhs.left && pivot == rhs.pivot
|
||||||
}
|
}
|
||||||
|
fun hash():ulong {
|
||||||
|
//return hash(nonterminal) ^ hash(rule_idx) ^ hash(idx_into_rule) ^ hash(left) ^ hash(pivot)
|
||||||
|
return nonterminal*3 + rule_idx*5 + idx_into_rule*7 + left*11 + pivot*13
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fun descriptor(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: int): Descriptor {
|
fun descriptor(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: int): Descriptor {
|
||||||
var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left, pivot): Descriptor
|
var to_ret.construct(nonterminal, rule_idx, idx_into_rule, left, pivot): Descriptor
|
||||||
@@ -304,22 +309,17 @@ fun bs(nonterminal: int, rule_idx: int, idx_into_rule: int, left: int, pivot: in
|
|||||||
/*}*/
|
/*}*/
|
||||||
fun fungll<T,K>(grammar: ref Grammer<T,K>, start_symbol: int, input: ref str): set<BS> {
|
fun fungll<T,K>(grammar: ref Grammer<T,K>, start_symbol: int, input: ref str): set<BS> {
|
||||||
var R = descend(grammar, start_symbol, 0)
|
var R = descend(grammar, start_symbol, 0)
|
||||||
var U = set<Descriptor>()
|
|
||||||
var G = map<pair<int, int>, set<Pending>>()
|
var G = map<pair<int, int>, set<Pending>>()
|
||||||
var P = map<pair<int,int>, set<int>>()
|
var P = map<pair<int,int>, set<int>>()
|
||||||
var Y = set<BS>()
|
var Y = set<BS>()
|
||||||
while R.size() != 0 {
|
|
||||||
var d = R.pop()
|
R.chaotic_closure(fun(d: Descriptor): set<Descriptor> {
|
||||||
var it = process(grammar, input, d, G, P)
|
var it = process(grammar, input, d, G, P)
|
||||||
var Rp = it.first.first
|
//var Yp = it.first.second
|
||||||
var Yp = it.first.second
|
Y += it.first.second
|
||||||
var Gp = it.second
|
var Gp = it.second
|
||||||
var Pp = it.third
|
var Pp = it.third
|
||||||
|
|
||||||
U.add(d)
|
|
||||||
var nextR = R.union(Rp) - U
|
|
||||||
R = nextR
|
|
||||||
|
|
||||||
for (var i = 0; i < Gp.keys.size; i++;) {
|
for (var i = 0; i < Gp.keys.size; i++;) {
|
||||||
if G.contains_key(Gp.keys[i]) {
|
if G.contains_key(Gp.keys[i]) {
|
||||||
G[Gp.keys[i]].add(Gp.values[i])
|
G[Gp.keys[i]].add(Gp.values[i])
|
||||||
@@ -334,8 +334,10 @@ fun fungll<T,K>(grammar: ref Grammer<T,K>, start_symbol: int, input: ref str): s
|
|||||||
P[Pp.keys[i]] = Pp.values[i]
|
P[Pp.keys[i]] = Pp.values[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Y += Yp
|
|
||||||
}
|
// Rp
|
||||||
|
return it.first.first
|
||||||
|
})
|
||||||
return Y
|
return Y
|
||||||
}
|
}
|
||||||
fun descend<T,K>(grammar: ref Grammer<T,K>, symbol: int, l: int): set<Descriptor> {
|
fun descend<T,K>(grammar: ref Grammer<T,K>, symbol: int, l: int): set<Descriptor> {
|
||||||
|
|||||||
@@ -42,6 +42,14 @@
|
|||||||
(do (set-idx! n i (f (idx l i)))
|
(do (set-idx! n i (f (idx l i)))
|
||||||
(recurse f l n (+ i 1))))))
|
(recurse f l n (+ i 1))))))
|
||||||
(helper f l (array-with-len (len l)) 0)))
|
(helper f l (array-with-len (len l)) 0)))
|
||||||
|
|
||||||
|
; Huge thanks to Oleg Kiselyov for his fantastic website
|
||||||
|
; http://okmij.org/ftp/Computation/fixed-point-combinators.html
|
||||||
|
Y* (lambda (& l)
|
||||||
|
((lambda (u) (u u))
|
||||||
|
(lambda (p)
|
||||||
|
(map (lambda (li) (lambda (& x) (lapply (lapply li (p p)) x))) l))))
|
||||||
|
|
||||||
flat_map (lambda (f l)
|
flat_map (lambda (f l)
|
||||||
(let (helper (rec-lambda (f l n i)
|
(let (helper (rec-lambda (f l n i)
|
||||||
(if (= i (len l))
|
(if (= i (len l))
|
||||||
@@ -86,9 +94,11 @@
|
|||||||
vapply
|
vapply
|
||||||
Y
|
Y
|
||||||
vY
|
vY
|
||||||
|
Y*
|
||||||
quote
|
quote
|
||||||
quasiquote
|
quasiquote
|
||||||
provide
|
provide
|
||||||
|
print_through
|
||||||
)
|
)
|
||||||
insert_into_scope_let (lambda (scope_let name item) (array (idx scope_let 0) (concat (idx scope_let 1) (array name item))))
|
insert_into_scope_let (lambda (scope_let name item) (array (idx scope_let 0) (concat (idx scope_let 1) (array name item))))
|
||||||
; Gotta insert with_import into scope_let via vY combinator so it can use itself
|
; Gotta insert with_import into scope_let via vY combinator so it can use itself
|
||||||
|
|||||||
@@ -6,5 +6,7 @@ mkShell {
|
|||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
emscripten
|
emscripten
|
||||||
nodejs
|
nodejs
|
||||||
|
valgrind
|
||||||
|
kcachegrind
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,5 +110,11 @@ obj hash_map<T,U> (Object, Serializable) {
|
|||||||
size = 0
|
size = 0
|
||||||
data.add(map::map<T,U>())
|
data.add(map::map<T,U>())
|
||||||
}
|
}
|
||||||
|
fun pop(): util::pair<T,U> {
|
||||||
|
for (var i = 0; i < data.size; i++;)
|
||||||
|
if (data[i].size() > 0)
|
||||||
|
return data[i].pop()
|
||||||
|
io::println("trying to pop out of an empty hash_map")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,5 +127,21 @@ obj hash_set<T> (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
fun pop(): T {
|
||||||
|
return data.pop().first
|
||||||
|
}
|
||||||
|
fun union(other: hash_set<T>): hash_set<T> {
|
||||||
|
for_each(fun(i: T) {
|
||||||
|
other.add(i)
|
||||||
|
})
|
||||||
|
return other
|
||||||
|
}
|
||||||
|
fun operator-(items: ref hash_set<T>): hash_set<T> {
|
||||||
|
var to_ret.copy_construct(this): hash_set<T>
|
||||||
|
items.for_each(fun(i: T) {
|
||||||
|
to_ret.remove(i)
|
||||||
|
})
|
||||||
|
return to_ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ obj map<T,U> (Object, Serializable) {
|
|||||||
fun remove(key: ref T) {
|
fun remove(key: ref T) {
|
||||||
var idx = keys.find(key)
|
var idx = keys.find(key)
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
util::error("trying to remove nonexistant key-value!")
|
return;
|
||||||
keys.remove(idx)
|
keys.remove(idx)
|
||||||
values.remove(idx)
|
values.remove(idx)
|
||||||
}
|
}
|
||||||
@@ -123,5 +123,8 @@ obj map<T,U> (Object, Serializable) {
|
|||||||
}
|
}
|
||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
|
fun pop(): util::pair<T,U> {
|
||||||
|
return util::make_pair(keys.pop(), values.pop())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,9 +149,7 @@ obj set<T> (Object, Serializable) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
fun pop(): T {
|
fun pop(): T {
|
||||||
var to_ret = data.last()
|
return data.pop()
|
||||||
data.remove(data.size-1)
|
|
||||||
return to_ret
|
|
||||||
}
|
}
|
||||||
fun union(other: set<T>): set<T> {
|
fun union(other: set<T>): set<T> {
|
||||||
for (var i = 0; i < data.size; i++;)
|
for (var i = 0; i < data.size; i++;)
|
||||||
|
|||||||
@@ -384,5 +384,10 @@ obj vec<T> (Object, Serializable) {
|
|||||||
return to_ret
|
return to_ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun pop(): T {
|
||||||
|
var to_ret = data[size-1]
|
||||||
|
remove(size-1)
|
||||||
|
return to_ret
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user