From e36e7caffa6194135895844aae9df93d1af4b9f9 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 13 Nov 2015 14:32:21 -0800 Subject: 2432 - first stab at making ingredients immutable The rule is, an address ingredient is only modifiable if: a) it's also a product b) it's /contained-in some other ingredient+product Only if an ingredient is a modifiable can you: a) call get-address or index-address on it (the only way to write to it) b) call other recipes that also return it in a product I still don't check copies of the address. That's next. Core mu passes this check, but none of the example apps do. edit/ and sandbox/ are known to fail. --- 075duplex_list.mu | 97 ++++++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 51 deletions(-) (limited to '075duplex_list.mu') diff --git a/075duplex_list.mu b/075duplex_list.mu index 765a6a17..e98710ed 100644 --- a/075duplex_list.mu +++ b/075duplex_list.mu @@ -6,17 +6,20 @@ container duplex-list:_elem [ prev:address:duplex-list:_elem ] -recipe push-duplex x:_elem, in:address:duplex-list:_elem -> result:address:duplex-list:_elem [ +recipe push-duplex x:_elem, in:address:duplex-list:_elem -> in:address:duplex-list:_elem [ local-scope load-ingredients - result <- new {(duplex-list _elem): type} + result:address:duplex-list:_elem <- new {(duplex-list _elem): type} val:address:_elem <- get-address *result, value:offset *val <- copy x next:address:address:duplex-list:_elem <- get-address *result, next:offset *next <- copy in - reply-unless in - prev:address:address:duplex-list:_elem <- get-address *in, prev:offset - *prev <- copy result + { + break-unless in + prev:address:address:duplex-list:_elem <- get-address *in, prev:offset + *prev <- copy result + } + reply result # needed explicitly because we need to replace 'in' with 'result' ] recipe first-duplex in:address:duplex-list:_elem -> result:_elem [ @@ -83,11 +86,11 @@ scenario duplex-list-handling [ ] ] -# Inserts 'x' after 'in'. Returns some pointer into the list. -recipe insert-duplex x:_elem, in:address:duplex-list:_elem -> new-node:address:duplex-list:_elem [ +# insert 'x' after 'in' +recipe insert-duplex x:_elem, in:address:duplex-list:_elem -> in:address:duplex-list:_elem [ local-scope load-ingredients - new-node <- new {(duplex-list _elem): type} + new-node:address:duplex-list:_elem <- new {(duplex-list _elem): type} val:address:_elem <- get-address *new-node, value:offset *val <- copy x next-node:address:duplex-list:_elem <- get *in, next:offset @@ -101,11 +104,10 @@ recipe insert-duplex x:_elem, in:address:duplex-list:_elem -> new-node:address:d y <- get-address *new-node, next:offset *y <- copy next-node # if next-node is not null - reply-unless next-node, new-node + reply-unless next-node # next-node.prev = new-node y <- get-address *next-node, prev:offset *y <- copy new-node - reply new-node # just signalling something changed; don't rely on the result ] scenario inserting-into-duplex-list [ @@ -189,7 +191,7 @@ scenario inserting-after-start-of-duplex-list [ 1:address:duplex-list:character <- push-duplex 3, 1:address:duplex-list:character 1:address:duplex-list:character <- push-duplex 4, 1:address:duplex-list:character 1:address:duplex-list:character <- push-duplex 5, 1:address:duplex-list:character - 2:address:duplex-list:character <- insert-duplex 6, 1:address:duplex-list:character + 1:address:duplex-list:character <- insert-duplex 6, 1:address:duplex-list:character # check structure like before 2:address:duplex-list:character <- copy 1:address:duplex-list:character 3:character <- first-duplex 2:address:duplex-list:character @@ -219,38 +221,38 @@ scenario inserting-after-start-of-duplex-list [ ] ] -# Removes 'in' from its surrounding list. Returns some valid pointer into the -# rest of the list. +# remove 'x' from its surrounding list 'in' # -# Returns null if and only if list is empty. Beware: in that case any pointers -# to the head are now invalid. -recipe remove-duplex in:address:duplex-list:_elem -> next-node:address:duplex-list:_elem [ +# Returns null if and only if list is empty. Beware: in that case any other +# pointers to the head are now invalid. +recipe remove-duplex x:address:duplex-list:_elem/contained-in:in, in:address:duplex-list:_elem -> in:address:duplex-list:_elem [ local-scope load-ingredients # if 'in' is null, return - reply-unless in, in - next-node:address:duplex-list:_elem <- get *in, next:offset - prev-node:address:duplex-list:_elem <- get *in, prev:offset - # null in's pointers - x:address:address:duplex-list:_elem <- get-address *in, next:offset - *x <- copy 0 - x <- get-address *in, prev:offset - *x <- copy 0 + reply-unless x + next-node:address:duplex-list:_elem <- get *x, next:offset + prev-node:address:duplex-list:_elem <- get *x, prev:offset + # null x's pointers + tmp:address:address:duplex-list:_elem <- get-address *x, next:offset + *tmp <- copy 0 + tmp <- get-address *x, prev:offset + *tmp <- copy 0 + # if next-node is not null, set its prev pointer { - # if next-node is not null break-unless next-node - # next-node.prev = prev-node - x <- get-address *next-node, prev:offset - *x <- copy prev-node + tmp <- get-address *next-node, prev:offset + *tmp <- copy prev-node } + # if prev-node is not null, set its next pointer and return { - # if prev-node is not null break-unless prev-node # prev-node.next = next-node - x <- get-address *prev-node, next:offset - *x <- copy next-node - reply prev-node + tmp <- get-address *prev-node, next:offset + *tmp <- copy next-node + reply } + # if prev-node is null, then we removed the node at 'in' + # return the new head rather than the old 'in' reply next-node ] @@ -261,7 +263,7 @@ scenario removing-from-duplex-list [ 1:address:duplex-list:character <- push-duplex 4, 1:address:duplex-list:character 1:address:duplex-list:character <- push-duplex 5, 1:address:duplex-list:character 2:address:duplex-list:character <- next-duplex 1:address:duplex-list:character # 2 points at second element - 2:address:duplex-list:character <- remove-duplex 2:address:duplex-list:character + 1:address:duplex-list:character <- remove-duplex 2:address:duplex-list:character, 1:address:duplex-list:character 3:boolean <- equal 2:address:duplex-list:character, 0 # check structure like before 2:address:duplex-list:character <- copy 1:address:duplex-list:character @@ -289,8 +291,8 @@ scenario removing-from-start-of-duplex-list [ 1:address:duplex-list:character <- push-duplex 3, 1:address:duplex-list:character 1:address:duplex-list:character <- push-duplex 4, 1:address:duplex-list:character 1:address:duplex-list:character <- push-duplex 5, 1:address:duplex-list:character - # removing from head? return value matters. - 1:address:duplex-list:character <- remove-duplex 1:address:duplex-list:character + # remove from head + 1:address:duplex-list:character <- remove-duplex 1:address:duplex-list:character, 1:address:duplex-list:character # check structure like before 2:address:duplex-list:character <- copy 1:address:duplex-list:character 3:character <- first-duplex 2:address:duplex-list:character @@ -319,7 +321,7 @@ scenario removing-from-end-of-duplex-list [ # delete last element 2:address:duplex-list:character <- next-duplex 1:address:duplex-list:character 2:address:duplex-list:character <- next-duplex 2:address:duplex-list:character - 2:address:duplex-list:character <- remove-duplex 2:address:duplex-list:character + 1:address:duplex-list:character <- remove-duplex 2:address:duplex-list:character, 1:address:duplex-list:character 3:boolean <- equal 2:address:duplex-list:character, 0 # check structure like before 2:address:duplex-list:character <- copy 1:address:duplex-list:character @@ -345,22 +347,15 @@ scenario removing-from-singleton-list [ run [ 1:address:duplex-list:character <- copy 0 # 1 points to singleton list 1:address:duplex-list:character <- push-duplex 3, 1:address:duplex-list:character - 2:address:duplex-list:character <- remove-duplex 1:address:duplex-list:character - 3:address:duplex-list:character <- get *1:address:duplex-list:character, next:offset - 4:address:duplex-list:character <- get *1:address:duplex-list:character, prev:offset + 1:address:duplex-list:character <- remove-duplex 1:address:duplex-list:character, 1:address:duplex-list:character ] memory-should-contain [ - 2 <- 0 # remove returned null - 3 <- 0 # removed node is also detached - 4 <- 0 + 1 <- 0 # back to an empty list ] ] -# l:address:duplex-list <- remove-duplex-between start:address:duplex-list, end:address:duplex-list -# Remove values between 'start' and 'end' (both exclusive). Returns some valid -# pointer into the rest of the list. -# Also clear pointers back out from start/end for hygiene. -recipe remove-duplex-between start:address:duplex-list:_elem, end:address:duplex-list:_elem -> start:address:duplex-list:_elem [ +# remove values between 'start' and 'end' (both exclusive) +recipe remove-duplex-between start:address:duplex-list:_elem, end:address:duplex-list:_elem/contained-in:start -> start:address:duplex-list:_elem [ local-scope load-ingredients reply-unless start @@ -470,8 +465,8 @@ scenario remove-range-empty [ ] ] -# Inserts list beginning at 'new' after 'in'. Returns some pointer into the list. -recipe insert-duplex-range in:address:duplex-list:_elem, start:address:duplex-list:_elem -> in:address:duplex-list:_elem [ +# insert list beginning at 'new' after 'in' +recipe insert-duplex-range in:address:duplex-list:_elem, start:address:duplex-list:_elem/contained-in:in -> in:address:duplex-list:_elem [ local-scope load-ingredients reply-unless in @@ -497,7 +492,7 @@ recipe insert-duplex-range in:address:duplex-list:_elem, start:address:duplex-li *dest <- copy in ] -recipe append-duplex in:address:duplex-list:_elem, new:address:duplex-list:_elem -> in:address:duplex-list:_elem [ +recipe append-duplex in:address:duplex-list:_elem, new:address:duplex-list:_elem/contained-in:in -> in:address:duplex-list:_elem [ local-scope load-ingredients last:address:duplex-list:_elem <- last-duplex in @@ -547,7 +542,7 @@ recipe force-specialization-duplex-list-character [ 1:address:duplex-list:character <- next-duplex 1:address:duplex-list:character 1:address:duplex-list:character <- prev-duplex 1:address:duplex-list:character 1:address:duplex-list:character <- insert-duplex 2:character, 1:address:duplex-list:character - 1:address:duplex-list:character <- remove-duplex 1:address:duplex-list:character + 1:address:duplex-list:character <- remove-duplex 1:address:duplex-list:character, 1:address:duplex-list:character 1:address:duplex-list:character <- remove-duplex-between 1:address:duplex-list:character, 1:address:duplex-list:character 1:address:duplex-list:character <- insert-duplex-range 1:address:duplex-list:character, 1:address:duplex-list:character 1:address:duplex-list:character <- append-duplex 1:address:duplex-list:character, 1:address:duplex-list:character -- cgit 1.4.1-2-gfad0 2-30 00:12:24 +0000 Use single quotes in functional test stanzas' href='/danisanti/profani-tty/commit/tests/functionaltests/test_connect.c?id=7f98e013e1ba103f3c9b4606be369f49673a2711'>7f98e013 ^
a28f0d9e ^
e2fa67fa ^
79ecff1c ^

7fb00a1e ^
db9376d8 ^


a48b9fce ^
db9376d8 ^
5aab876a ^
7f98e013 ^


db9376d8 ^







6640a089 ^
a48b9fce ^
db9376d8 ^
a522d022 ^
db9376d8 ^

37600846 ^
f17afcf5 ^
37600846 ^
a48b9fce ^
37600846 ^
a48b9fce ^
7f98e013 ^
37600846 ^


a48b9fce ^



7f98e013 ^
37600846 ^


a48b9fce ^



7f98e013 ^
37600846 ^



a522d022 ^
f8c5ed57 ^

7f98e013 ^
f8c5ed57 ^



a522d022 ^
37600846 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95