// To recursively copy containers and any addresses they contain, use // 'deep-copy'. // // Invariant: After a deep-copy its ingredient and result will point to no // common addresses. // Implications: Refcounts of all data pointed to by the original ingredient // will remain unchanged. Refcounts of all data pointed to by the (newly // created) result will be 1, in the absence of cycles. // // We do handle cycles in the ingredient, however. All cycles are translated // to new cycles in the product. :(scenario deep_copy_number) def main [ local-scope x:num <- copy 34 y:num <- deep-copy x 10:bool/raw <- equal x, y ] # non-address primitives are identical +mem: storing 1 in location 10 :(scenario deep_copy_container_without_address) container foo [ x:num y:num ] def main [ local-scope a:foo <- merge 34, 35 b:foo <- deep-copy a 10:bool/raw <- equal a, b ] # containers are identical as long as they don't contain addresses +mem: storing 1 in location 10 :(scenario deep_copy_address) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:num <- copy 100/unsafe # pretend allocation *1:&:num <- copy 34 2:&:num <- deep-copy 1:&:num 10:bool <- equal 1:&:num, 2:&:num 11:bool <- equal *1:&:num, *2:&:num 2:&:num <- copy 0 ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 # the result of deep-copy gets a refcount of 1 # (its address 202 = 200 base + 2 for temporary space inside deep-copy) +run: {2: ("address" "number")} <- copy {0: "literal"} +mem: decrementing refcount of 202: 1 -> 0 +abandon: saving 202 in free-list of size 2 :(scenario deep_copy_address_to_container) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:point <- copy 100/unsafe # pretend allocation *1:&:point <- merge 34, 35 2:&:point <- deep-copy 1:&:point 10:bool <- equal 1:&:point, 2:&:point 11:bool <- equal *1:&:point, *2:&:point ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 :(scenario deep_copy_address_to_address) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:&:num <- copy 100/unsafe # pretend allocation *1:&:&:num <- copy 150/unsafe **1:&:&:num <- copy 34 2:&:&:num <- deep-copy 1:&:&:num 10:bool <- equal 1:&:&:num, 2:&:&:num 11:bool <- equal *1:&:&:num, *2:&:&:num 12:bool <- equal **1:&:&:num, **2:&:&:num ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # any addresses in it or pointed to it are also new +mem: storing 0 in location 11 # however, the non-address contents are identical +mem: storing 1 in location 12 :(scenario deep_copy_array) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 100:num <- copy 1 # pretend refcount 101:num <- copy 3 # pretend array length 1:&:@:num <- copy 100/unsafe # pretend allocation put-index *1:&:@:num, 0, 34 put-index *1:&:@:num, 1, 35 put-index *1:&:@:num, 2, 36 stash [old:], *1:&:@:num 2:&:@:num <- deep-copy 1:&:@:num stash 2:&:@:num stash [new:], *2:&:@:num 10:bool <- equal 1:&:@:num, 2:&:@:num 11:bool <- equal *1:&:@:num, *2:&:@:num ] +app: old: 3 34 35 36 +app: new: 3 34 35 36 # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 :(scenario deep_copy_container_with_address) container foo [ x:num y:&:num ] def main [ local-scope y0:&:num <- new number:type *y0 <- copy 35 a:foo <- merge 34, y0 b:foo <- deep-copy a 10:bool/raw <- equal a, b y1:&:num <- get b, y:offset 11:bool/raw <- equal y0, y1 12:num/raw <- copy *y1 ] # containers containing addresses are not identical to their deep copies +mem: storing 0 in location 10 # the addresses they contain are not identical either +mem: storing 0 in location 11 +mem: storing 35 in location 12 :(scenario deep_copy_exclusive_container_with_address) exclusive-container foo [ x:num y:&:num ] def main [ local-scope y0:&:num <- new number:type *y0 <- copy 34 a:foo <- merge 1/y, y0 b:foo <- deep-copy a 10:bool/raw <- equal a, b y1:&:num, z:bool <- maybe-convert b, y:variant 11:bool/raw <- equal y0, y1 12:num/raw <- copy *y1 ] # exclusive containers containing addresses are not identical to their deep copies +mem: storing 0 in location 10 # the addresses they contain are not identical either +mem: storing 0 in location 11 +mem: storing 34 in location 12 :(scenario deep_copy_exclusive_container_with_container_with_address) exclusive-container foo [ x:num y:bar # inline ] container bar [ x:&:num ] d
/*
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 * See LICENSE file for license details.
 */

#define TAGS \
const char *tags[] = { "dev", "work", "net", "fnord", NULL };

#define DEFMODE			dotile /* dofloat */
#define FLOATSYMBOL		"><>"
#define TILESYMBOL		"[]="

#define FONT			"-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*"
#define SELBGCOLOR		"#333366"
#define SELFGCOLOR		"#eeeeee"
#define NORMBGCOLOR		"#333333"
#define NORMFGCOLOR		"#dddddd"
#define STATUSBGCOLOR		"#222222"
#define STATUSFGCOLOR		"#9999cc"

#define MODKEY			Mod1Mask
#define MASTERW			60 /* percent */

#define KEYS \
static Key key[] = { \
	/* modifier			key		function	arguments */ \
	{ MODKEY|ShiftMask,		XK_Return,	spawn, \
		{ .cmd = "exec uxterm -bg '#111111' -fg '#eeeeee' -cr '#eeeeee' +sb -fn '"FONT"'" } }, \
	{ MODKEY,			XK_p,		spawn, \
		{ .cmd = "exe=\"$(IFS=:; for dir in $PATH; do " \
			 "for file in \"$dir\"/*; do [ -x \"$file\" ] && echo \"${file##*/}\"; done; " \
			 "done | sort -u | dmenu)\" && exec \"$exe\"" } }, \
	{ MODKEY,			XK_j,		focusnext,	{ 0 } }, \
	{ MODKEY,			XK_k,		focusprev