Skip to content

Commit 7514fcb

Browse files
committed
WIP
1 parent f0bd124 commit 7514fcb

25 files changed

+555
-389
lines changed

core/CPointer.savi

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
:: The caller is expected to only do this for indexes that are within
6262
:: the size of the originally allocated pointer and not to reach outside
6363
:: that bounds into memory owned by other pointers.
64-
:fun box _offset(index USize) @'ref: compiler intrinsic
64+
:fun _offset(index USize) @'ref: compiler intrinsic
6565

6666
:: Get a pointer that points to a subset of this original pointer's memory,
6767
:: starting at the given element index from the current pointer's address,
@@ -78,7 +78,7 @@
7878
:: Return an alias of the element at the given index.
7979
::
8080
:: The caller is expected to only do this for in-bounds indexes.
81-
:fun box _get_at(index USize) (@->A)'aliased: compiler intrinsic
81+
:fun _get_at(index USize) (@->A)'aliased: compiler intrinsic
8282

8383
:: Return the element at the given index, without capability aliasing.
8484
:: This lack of aliasing breaks capability safety, so the caller is expected
@@ -106,7 +106,7 @@
106106
:: you need to copy starting at some offset, use the `_offset` method first.
107107
::
108108
:: The caller is expected to only do this for in-bounds element counts.
109-
:fun box _copy_to(other @'ref, count USize) None: compiler intrinsic
109+
:fun _copy_to(other @'ref, count USize) None: compiler intrinsic
110110

111111
:: Compare the memory referenced by this pointer to that of the other pointer,
112112
:: across the byte range indicated by the given element count.
@@ -119,7 +119,7 @@
119119
:: ramifications of what kind of representation the element has in its memory.
120120
::
121121
:: The caller is expected to only do this for in-bounds element counts.
122-
:fun box _compare(other @'box, count USize) I32: compiler intrinsic
122+
:fun _compare(other @'box, count USize) I32: compiler intrinsic
123123

124124
:: Calculate the hash of the block of memory starting at this pointer's head,
125125
:: continuing through the given number of elements in that memory.
@@ -132,7 +132,7 @@
132132
:: ramifications of what kind of representation the element has in its memory.
133133
::
134134
:: The caller is expected to only do this for in-bounds element counts.
135-
:fun box _hash(count USize) USize: compiler intrinsic
135+
:fun _hash(count USize) USize: compiler intrinsic
136136

137137
:: Return True if this is a null pointer (i.e. a zero address).
138138
:fun tag is_null Bool: compiler intrinsic

core/Env.savi

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
:: distribute more limited authority objects derived from it) as needed.
1515
:new val _create(
1616
argc I32
17-
argv CPointer(CPointer(U8)'ref)'ref
18-
envp CPointer(CPointer(U8)'ref)'ref
17+
argv CPointer(CPointer(U8)'ref)'ref // TODO: val instead of ref
18+
envp CPointer(CPointer(U8)'ref)'ref // TODO: val instead of ref
1919
)
2020
@args = []
2121
i = USize[0]
@@ -41,7 +41,7 @@
4141
:let _vars Array(Pair(String))
4242

4343
:new val _from_envp(envp CPointer(CPointer(U8)'ref)'ref)
44-
@_vars = []
44+
vars = []
4545
if (envp.is_not_null) (
4646
while True (
4747
arg = envp._get_at(0)
@@ -50,12 +50,13 @@
5050
try (
5151
len = _FFI.strlen(arg).usize
5252
pair = String.val_from_cpointer(arg, len, len).split2!('=')
53-
@_vars.push(pair)
53+
vars.push(pair)
5454
)
5555

5656
envp = envp._offset(1)
5757
)
5858
)
59+
@_vars = vars
5960

6061
:fun each_pair
6162
:yields (String'val, String'val) for None

core/IntoString.savi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
:trait box IntoString
66
:: Emit a representation of this value into the given String, preserving
77
:: its isolation and returning the String with the new content appended.
8-
:fun box into_string(out String'iso) String'iso
8+
:fun into_string(out String'iso) String'iso
99

1010
:: Return a conservative estimate for how much many bytes are required to hold
1111
:: the string representation of this value when emitted with `into_string`.
@@ -14,4 +14,4 @@
1414
:: is not possible, the function should prefer to over-estimate the amount
1515
:: of space needed, because an under-estimation would result in a potentially
1616
:: costly re-allocation and copy of data in the underlying string buffer.
17-
:fun box into_string_space USize
17+
:fun into_string_space USize

core/None.savi

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
:module None
22
:is IntoString
3-
// TODO: These shouldn't need to be `:fun box` - `:fun non` should be okay.
43
:: When emitting into a string, emit nothing (i.e. an empty string).
5-
:fun box into_string(out String'iso): --out
6-
:fun box into_string_space USize: 0
4+
:fun into_string(out String'iso): --out
5+
:fun into_string_space USize: 0
76

87
:: When inspecting, print explicitly using the name `None`.
9-
:fun box inspect_into(out String'iso): out << "None", --out
8+
:fun inspect_into(out String'iso): out << "None", --out

core/U64.BCD.savi

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
:: Binary Coded Decimal (BCD) representation of an U64 integer.
2-
::
2+
::
33
:: Each digit is represented by a nibble (4 bits), requiring
44
:: a total of 80 bits for up to 20 digits of the U64.
55
:: Digits are stored in reverse order, so the the decimal `123`
@@ -19,8 +19,8 @@
1919
:let _high U64
2020
:let _low U64
2121

22-
:new (u64 U64)
23-
high U64 = 0
22+
:new val (u64 U64)
23+
high U64 = 0
2424
low U64 = 0xF
2525
ndigits U64 = 0
2626
while True (
@@ -36,11 +36,11 @@
3636
@_high = high.bit_or(ndigits.bit_shl(58))
3737
@_low = low
3838

39-
:fun box is_zero Bool
39+
:fun is_zero Bool
4040
@_low.bit_and(0xFF) == 0xF0
4141

4242
:: Converts the BCD back to an U64
43-
:fun box u64 U64
43+
:fun u64 U64
4444
n U64 = 0
4545
@each_digit -> (digit |
4646
n = (n * 10) + digit.u64
@@ -49,11 +49,11 @@
4949

5050
:: Returns the number of digits.
5151
::
52-
:fun box ndigits USize
52+
:fun ndigits USize
5353
@_high.bit_shr(58).bit_and(0b11111).usize
5454

5555
:: Returns digit at position `pos`.
56-
:fun box digit!(pos USize) U8
56+
:fun digit!(pos USize) U8
5757
// 1234 -> 0xF_4321
5858
// pos=0 -> ^-- index=3 == ndigits - (pos + 1)
5959
// pos=3 -> ^-- index=0 == ndigits - (pos + 1)
@@ -68,8 +68,8 @@
6868
@_high.bit_shr(((index - 16) * 4).u8).u8.bit_and(U8[0xF])
6969
)
7070

71-
:fun box each_digit
72-
:yields U8 for None
71+
:fun each_digit
72+
:yields U8 for None
7373
high = @_high
7474
low = @_low
7575
while (low.bit_and(0xF) != 0xF) (
@@ -78,10 +78,10 @@
7878
high = high.bit_shr(4)
7979
)
8080

81-
:fun box into_string_space USize
81+
:fun into_string_space USize
8282
@ndigits
8383

84-
:fun box into_string(out String'iso) String'iso
84+
:fun into_string(out String'iso) String'iso
8585
@each_digit -> (digit |
8686
out.push_byte('0'.u8 + digit)
8787
)

core/declarators/declarators.savi

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,8 @@
317317
:context type
318318
:begins function
319319

320-
:term cap enum (iso, val, ref, box, tag, non)
321-
:default box
320+
:term cap enum (iso, val, ref, box, tag, non, read)
321+
:default read
322322
:term name_and_params NameMaybeWithParams
323323
:term ret Type
324324
:optional
@@ -339,8 +339,8 @@
339339
:context type
340340
:begins function
341341

342-
:term cap enum (iso, val, ref, box, tag, non)
343-
:optional // TODO: :default: @type.cap
342+
:term cap enum (iso, val, ref, box, tag, non, read)
343+
:default read
344344
:term name_and_params NameMaybeWithParams
345345
:body optional
346346

@@ -350,8 +350,8 @@
350350
:context type
351351
:begins function
352352

353-
:term cap enum (iso, val, ref, box, tag, non)
354-
:optional // TODO: :default: @type.cap
353+
:term cap enum (iso, val, ref, box, tag, non, read)
354+
:default read
355355
:term params Params
356356
:optional
357357
:body optional

spec/compiler/completeness.savi.spec.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ It complains when not all fields get initialized in a constructor:
1414
```
1515
```error
1616
This constructor doesn't initialize all of its fields:
17-
:new
17+
:new ref
1818
^~~
1919
2020
- this field didn't get initialized:
@@ -52,7 +52,7 @@ It complains when a field is only conditionally initialized:
5252
```
5353
```error
5454
This constructor doesn't initialize all of its fields:
55-
:new
55+
:new ref
5656
^~~
5757
5858
- this field didn't get initialized:
@@ -104,7 +104,7 @@ It won't blow its stack on mutually recursive branching paths:
104104
```
105105
```error
106106
This constructor doesn't initialize all of its fields:
107-
:new
107+
:new ref
108108
^~~
109109
110110
- this field didn't get initialized:

spec/compiler/t_type_check.calls.savi.spec.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,13 @@ TODO: It complains when calling a `non` function with no body on a `non` referen
309309
// t_non.no_body
310310
311311
:trait TraitNon
312-
:fun box not_non String
312+
:fun not_non String
313313
:fun non with_body String: "with_body"
314314
:fun non no_body String
315315
316316
:class TraitNonClass
317317
:is TraitNon
318-
:fun box not_non String: "not_non"
318+
:fun not_non String: "not_non"
319319
:fun non no_body String: "no_body"
320320
321321
```

spec/compiler/type_check.calls.savi.spec.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ This function call doesn't meet subtyping requirements:
224224
string String'val = wrapper.immutable_string
225225
^~~~~~~~~~~~~~~~
226226
227-
- the function's required receiver capability is `val` but only a `ref` or `box` function can be auto-recovered:
227+
- the function's required receiver capability is `val` but only a `ref`, `box`, or `read` function can be auto-recovered:
228228
:fun val immutable_string: @string
229229
^~~
230230
@@ -365,6 +365,8 @@ A `let` property can only be assigned inside a constructor:
365365
^
366366
```
367367

368+
---
369+
368370
It complains when calling a `non` function with no body on a `non` reference to a trait:
369371

370372
```savi

spec/compiler/type_check.completeness.savi.spec.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,25 @@ It complains when access to the self is shared while still incomplete:
1919
any
2020
```
2121
```error
22-
This usage of `@` shares field access to the object from a constructor before all fields are initialized:
22+
The type of this expression doesn't meet the constraints imposed on it:
2323
AccessWhileIncomplete.data(@)
2424
^
2525
26-
- if this constraint were specified as `tag` or lower it would not grant field access:
26+
- it is required here to be a subtype of Any'box:
2727
:fun data(any Any'box)
2828
^~~~~~~
2929
30-
- this field didn't get initialized:
31-
:var y U64
32-
^
30+
- but the type of the receiver value was ItComplainsWhenAccessToTheSelfIsSharedWhileStillIncomplete0'tag:
31+
AccessWhileIncomplete.data(@)
32+
^
3333
34-
- this field didn't get initialized:
35-
:var z U64
36-
^
34+
- this can be reached while in an incomplete constructor (that is, before all fields are initialized) so it's not safe to share publicly here:
35+
AccessWhileIncomplete.data(@)
36+
^
37+
38+
- it can be reached from this constructor:
39+
:new ref
40+
^~~
3741
```
3842

3943
---

0 commit comments

Comments
 (0)