Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ Cargo.lock
**/*.rs.bk
*~
*listing
mergeSort-inputSeq
mergeSort-inputSeqBig
*TikZ
*-dat
5 changes: 4 additions & 1 deletion crates/fumola/src/bin/fumola.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,10 @@ fn inspect_result(state: &mut State, result: Result<Value_, fumola::Error>, dept
}

fn report_error(_state: &mut State, error: fumola::Error) {
error!("Error: {:?}", error);
//for frame in state.backtrace() {
// info!("{:?}", frame);
//}
error!("{:?}", error);
}

fn read_file_if_exists(path: &str) -> Option<String> {
Expand Down
18 changes: 14 additions & 4 deletions crates/fumola_semantics/src/lib/vm_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,9 @@ fn path_base(path: &String) -> String {
}

pub mod def {

use fumola_syntax::ast;
use log::{debug};
use log::{debug, info};

use super::*;
use crate::{
Expand Down Expand Up @@ -241,6 +242,7 @@ pub mod def {
return nyi!(line!(), "import {}", path);
}
} else {
info!("Pre {:?} {:?}", active.defs().active_path.as_ref(), path);
let path = match active.defs().active_path.as_ref() {
// we are "active" at some other path that's relative to this one.
// we need to account for that.
Expand All @@ -257,13 +259,14 @@ pub mod def {
prefix
}
};
info!("Post {:?} {:?}", active.defs().active_path.as_ref(), path);
(active.package().clone(), path)
};
let path = crate::vm_types::ModulePath {
package_name: package_name.clone(),
local_path: local_path.clone(),
};
log::debug!(
log::info!(
"`import {}` resolves as `import {:?}`. Attemping to import...",
path0,
path
Expand All @@ -281,7 +284,11 @@ pub mod def {
stack.push_back(path.clone());
return Err(Interruption::ImportCycle(stack));
} else {
info!("Pre {:?}", active.defs().active_path);
active.defs().active_path = Some(path_base(&local_path));
info!("Post {:?}", active.defs().active_path);

info!("Pushing {:?}", path);
active.module_files().import_stack.push_back(path.clone());
};
let importing_package = active.package().clone();
Expand Down Expand Up @@ -331,9 +338,12 @@ pub mod def {
active.defs().leave_context(saved, &ctxid);
*active.package() = importing_package;
if let Some(top_path) = active.module_files().import_stack.pop_back() {
info!("Popping {:?}", top_path);
match active.module_files().import_stack.head() {
Some(active_module_path) => {
active.defs().active_path = Some(active_module_path.local_path.clone())
info!("Top module {:?}", active_module_path);
info!("Path of top {:?}", path_base(&active_module_path.local_path));
active.defs().active_path = Some(path_base(&active_module_path.local_path))
}
None => active.defs().active_path = None,
};
Expand All @@ -357,7 +367,7 @@ pub mod def {
}
}
};
log::debug!("`import {}` Success.", path0);
log::info!("`import {}` Success.", path0);
Ok(mf.def())
}

Expand Down
19 changes: 19 additions & 0 deletions fumola/collections/Counters.fumola
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module {
public func ptr (symbol:Symbol) {
prim "adaptonPointer" (symbol);
};
public func get (symbol:Symbol) {
(prim "adaptonPeek" (ptr symbol))
};
public func inc (symbol:Symbol) {
let p = ptr(symbol);
switch (prim "adaptonPeek" p) {
case null {
prim "adaptonPoke" (p, 1);
};
case (?n) {
prim "adaptonPoke" (p, n + 1);
};
}
}
}
65 changes: 65 additions & 0 deletions fumola/collections/LazyList.fumola
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import Counters "Counters";

module {

#[listing(23)]
public type LazyListCell<X> = {
element : X;
symbol : Symbol;
next : LazyList_<X>;
};

#[listing]
public type LazyList<X> = ?LazyListCell<X>;

#[listing]
public type LazyList_<X> = Pointer<Thunk<LazyList<X>>>;

#[listing(69)]
public func merge(xs : LazyList<X>, ys : LazyList<X>) : LazyList<X> {
switch (xs, ys) {
case (_, null) xs;
case (null, _) ys;
case (?xc, ?yc) {
Counters.inc `merge;
if (xc.element <= yc.element) {
?{ element=xc.element; symbol=xc.symbol; next = xc.symbol := thunk { merge(force(xc.next), ?yc) } }
} else {
?{ element=yc.element; symbol=yc.symbol; next = yc.symbol := thunk { merge(?xc, force(yc.next)) } }
}
};
}
};

#[listing]
public func takeN(l : LazyList<X>, len : Nat) : [(Symbol, X)] {
if (len == 0) { return [] };
switch (force l) {
case null [];
case (?lc) {
[(lc.symbol, lc.element)] # takeN(lc.next, len - 1)
}
}
};

#[listing]
public func takeAll(l : LazyList<X>) : [(Symbol, X)] {
switch (force l) {
case null [];
case (?lc) {
[(lc.symbol, lc.element)] # takeAll(lc.next)
}
}
};

#[listing]
public func takeOne(l : LazyList<X>) : [(Symbol, X)] {
switch (force l) {
case null [];
case (?lc) {
[(lc.symbol, lc.element)]
}
}
};

}
31 changes: 31 additions & 0 deletions fumola/collections/List.fumola
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module {

#[listing(33)]
public type List<X> = ?{
element : X;
symbol : Symbol;
next : Pointer<List<X>>
};

#[listing]
public func fromIter(iter : Iter<(Symbol, X)>) : List<X> {
switch (iter.next()) {
case null null;
case (?(symbol, element)) {
?{symbol; element; next=fromIter(iter)}
}
}
};

public func testFromIter() {
let list = fromIter([(1,1), (2,2), (3,3)].vals());
assert (list!.symbol == 1);
assert (list!.element == 1);
assert (list!.next!.symbol == 2);
assert (list!.next!.element == 2);
assert (list!.next!.next!.symbol == 3);
assert (list!.next!.next!.element == 3);
assert (list!.next!.next!.next == null);
};

}
144 changes: 8 additions & 136 deletions fumola/collections/SeqTree.fumola
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
module {
public module Counters {
public func ptr (symbol:Symbol) {
prim "adaptonPointer" (symbol);
};
public func get (symbol:Symbol) {
(prim "adaptonPeek" (ptr symbol))
};
public func inc (symbol:Symbol) {
let p = ptr(symbol);
switch (prim "adaptonPeek" p) {
case null {
prim "adaptonPoke" (p, 1);
};
case (?n) {
prim "adaptonPoke" (p, n + 1);
};
}
};
};
import List "List";
import LazyList "LazyList";

module {

#[listing(30)]
public type SeqTree<X> = {
#empty;
Expand All @@ -42,42 +26,6 @@ module {
symbol : Symbol
};

#[listing(33)]
public type List<X> = ?{
element : X;
symbol : Symbol;
next : Pointer<List<X>>
};

#[listing(23)]
public type LazyListCell<X> = {
element : X;
symbol : Symbol;
next : LazyList_<X>;
};

#[listing]
public type LazyList<X> = ?LazyListCell<X>;

#[listing]
public type LazyList_<X> = Pointer<Thunk<LazyList<X>>>;

#[listing(69)]
public func merge(xs : LazyList<X>, ys : LazyList<X>) : LazyList<X> {
switch (xs, ys) {
case (_, null) xs;
case (null, _) ys;
case (?xc, ?yc) {
Counters.inc `merge;
if (xc.element <= yc.element) {
?{ element=xc.element; symbol=xc.symbol; next = xc.symbol := thunk { merge(force(xc.next), ?yc) } }
} else {
?{ element=yc.element; symbol=yc.symbol; next = yc.symbol := thunk { merge(?xc, force(yc.next)) } }
}
};
}
};

#[listing]
public func reduceUp<X,Y>(
t : SeqTree<X>,
Expand Down Expand Up @@ -112,66 +60,15 @@ module {
},
func(symbol:Symbol, xs:LazyList<X>, ys:LazyList<X>) : LazyList<X> {
do within space (`merge-symbol) {
merge(xs, ys)
LazyList.merge(xs, ys)
}
},
)
}}};

#[listing]
public func listFromIter(iter : Iter<(Symbol, X)>) : List<X> {
switch (iter.next()) {
case null null;
case (?(symbol, element)) {
?{symbol; element; next=listFromIter(iter)}
}
}
};

#[listing]
public func takeN(l : LazyList<X>, len : Nat) : [(Symbol, X)] {
if (len == 0) { return [] };
switch (force l) {
case null [];
case (?lc) {
[(lc.symbol, lc.element)] # takeN(lc.next, len - 1)
}
}
};

#[listing]
public func takeAll(l : LazyList<X>) : [(Symbol, X)] {
switch (force l) {
case null [];
case (?lc) {
[(lc.symbol, lc.element)] # takeAll(lc.next)
}
}
};

#[listing]
public func takeOne(l : LazyList<X>) : [(Symbol, X)] {
switch (force l) {
case null [];
case (?lc) {
[(lc.symbol, lc.element)]
}
}
};

public func listFromIterTest() {
let list = listFromIter([(1,1), (2,2), (3,3)].vals());
assert (list!.symbol == 1);
assert (list!.element == 1);
assert (list!.next!.symbol == 2);
assert (list!.next!.element == 2);
assert (list!.next!.next!.symbol == 3);
assert (list!.next!.next!.element == 3);
assert (list!.next!.next!.next == null);
};

public func fromArray<X>(array : [(Symbol, X)]) : ?SeqTree_<X> {
fromList(listFromIter(array.vals()))
fromList(List.fromIter(array.vals()))
};

#[listing]
Expand Down Expand Up @@ -254,42 +151,17 @@ module {
if (x < 0) -x else x
};

func maxChoice3(xdiff : Nat, x : ?(Nat, Nat), ydiff : Nat, y : ?(Nat, Nat), zdiff : Nat, z : ?(Nat, Nat)) : ?(Nat, Nat) {
if (xdiff >= ydiff and xdiff >= zdiff) { x }
else if (ydiff >= xdiff and ydiff >= zdiff) { y }
else z
};

func maxChoice2(xdiff : Nat, x : ?(Nat, Nat), ydiff : Nat, y : ?(Nat, Nat)) : ?(Nat, Nat) {
if (xdiff >= ydiff) x else y
};

func leastBalance(x : ?(Nat, Nat), y : ?(Nat, Nat), z : ?(Nat, Nat)) : ?(Nat, Nat) {
switch (x, y, z) {
case (null, null, z) z;
case (null, y, null) y;
case (x, null, null) x;
case (?(x1, x2), ?(y1, y2), null) { maxChoice2(abs(x1 - x2), x, abs(y1 - y2), y) };
case (?(x1, x2), null, ?(y1, y2)) { maxChoice2(abs(x1 - x2), x, abs(y1 - y2), y) };
case (?(x1, x2), null, ?(y1, y2)) { maxChoice2(abs(x1 - x2), x, abs(y1 - y2), y) };
case (?(x1, x2), ?(y1, y2), ?(z1, z2)) {
maxChoice3(abs(x1 - x2), x, abs(y1 - y2), y, abs(z1 - z2), z)
}
}
};

#[listing]
public func metrics<X>(tree : Pointer<SeqTree<X>>) {
switch (@ tree) {
case (#empty) { { depth=0; size=0; leastBalance=null } };
case (#element(e)) { { depth=1; size=1; leastBalance=null } };
case (#empty) { { depth=0; size=0; } };
case (#element(e)) { { depth=1; size=1; } };
case (#binary(b)) {
let ml = metrics(b.left);
let mr = metrics(b.right);
{
depth = max(ml.depth, mr.depth) + 1;
size = ml.size + mr.size;
leastBalance = leastBalance(ml.leastBalance, mr.leastBalance, ?(ml.size, mr.size))
}
};
}
Expand Down
1 change: 1 addition & 0 deletions fumola/examples/mergeSort/Counters.fumola
Loading
Loading