@cella-lang/c 0.1.202610291320 → 0.1.202610300802
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +10 -1
- package/README.md +25 -207
- package/c.cell +0 -0
- package/index.json +117 -3859
- package/package.json +7 -6
package/CHANGES.md
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
# @cella-lang/c 的變更
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
給使用這個套件的工具看的 API 變更。雜湊(每個定義的 own/merkle,見 `index.json`)在不穩定期可能改變;下面列出改變的定義。
|
|
4
4
|
|
|
5
5
|
## 未發佈
|
|
6
6
|
|
|
7
|
+
- **不相容**:淺嵌入整個拿掉,C 程式改由深嵌入的分支服務。程式是 `@cella-lang/cfamily` 語法的 JSON(`"lang": {"k": "langC"}`),
|
|
8
|
+
入口是 `c.verdict src input fuel`、`c.types src candidates` 與除錯器(`load`、`run`、`stopKind`…、`report`);kernel 判決是
|
|
9
|
+
`kernel_verdict_in("c", "c.verdict", …)`。依賴 `@cella-lang/cfamily` 與 `@cella-lang/machine`(不再依賴 cpp)。
|
|
10
|
+
- 文字照 UTF-8(見 cfamily 的變更)。帶板子的程式判 `invalid`(Arduino 的程式是 C++)。
|
|
11
|
+
|
|
12
|
+
## 0.1.202610291317 與之前
|
|
13
|
+
|
|
14
|
+
這一段寫成時沒有照版本切開,跟著 0.1.202610291317 與之前的版本陸續發出。裡面多半是淺嵌入的 API(`cpp.IntN`、`c.Mem`、`cpp.Debugger`…),淺嵌入已整個拿掉,這些名字都不存在了,只留作紀錄。
|
|
15
|
+
|
|
7
16
|
- 跟著 cpp 的 `IType` 多了 `plain`:`counterpart` 回傳非 plain 的型別,`eqITypeRefl` 多比一個欄位。雜湊改變:用到 `IType` 的定義。
|
|
8
17
|
- **不相容**:記憶體改成一份統一記憶體(照 CH2O)。`c.Mem t`、`c.memNew t`、`c.Allocated t` 換成 `c.CMem`、`c.memNew`、`c.Allocated`;指標 `c.Ptr` 是 `c.nullP` 或 `c.cptr 配置 路徑 索引`(不再是 cpp 的指標),指向 struct 成員的指標(`c.memberPtr m p "k"`)與指向變數、陣列格的指標是同一種,收 `int*`/`char*` 的函式對它們一樣運作;越過成員或陣列邊界的指標算術是越界。
|
|
9
18
|
- 讀寫與函式庫多了明確的元素型別參數:`c.load t m q ok`、`c.store t m q v ok`、`c.addrOf t m v`、`c.declArrM t m n z`、`c.idx t …`、`c.strlen pl t m q ok`、`c.strcmp pl t …`、`c.argS t m q`、`c.readableNB t …`、`c.readK t …`、`c.writeK t …`、`c.readable2 t …`、`c.at2 t …`、`c.qsort pl t …`、`c.bsearch pl t …`、`c.memset t …`、`c.memchr t …`、`c.strchr t …`……;`c.malloc ct m n fails`、`c.calloc`、`c.realloc` 收元素的 `c.CType`(整數是 `c.ctInt t`)。struct 不再有自己的記憶體(`c.smemNew` 拿掉),`c.arrowSet`、`c.arrow` 的前置條件是 `refl`(`c.objWritableB`、`c.objOkB`)。
|
package/README.md
CHANGED
|
@@ -1,220 +1,38 @@
|
|
|
1
1
|
# @cella-lang/c
|
|
2
2
|
|
|
3
|
-
C11
|
|
3
|
+
C11 for the [Cella](https://www.npmjs.com/package/cella-lang) proof checker, as a compiled module pack: the C branch of
|
|
4
|
+
the C family's deep embedding (`@cella-lang/cfamily`). A program is checked by C11's rules and run by a small-step
|
|
5
|
+
semantics; the verdict is accept, reject or unknown, with the node and the clause of the standard.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
out-of-range shifts are undefined behaviour, and `char` may be signed or unsigned. This library defines the C semantics directly:
|
|
7
|
+
Depends on `@cella-lang/cfamily` and `@cella-lang/machine`.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
- integer promotions and the usual arithmetic conversions compute the result type (`c.addV p a b ok : c.Val (cpp.common p s t)`);
|
|
10
|
-
- every operation that can be undefined takes the condition as an argument — for concrete values `(cpp.inT refl)` (signed: no overflow),
|
|
11
|
-
`unit` (unsigned: wraps modulo 2^N), `refl` (divisor not zero), `(c.shlOk refl)` / `(c.shrOk refl)` (shift amount and, for signed `<<`,
|
|
12
|
-
a result that fits the result type);
|
|
13
|
-
- comparisons and logical operators yield an `int` 0 or 1, as in C;
|
|
14
|
-
- conversions: to `_Bool` is "not zero", to unsigned is modulo 2^N, to signed wraps (implementation-defined; as clang);
|
|
15
|
-
- platforms: `c.lp64P` (x86-64 Linux/macOS, `char` signed), `c.aarch64P` (AArch64 Linux, `char` unsigned).
|
|
9
|
+
## Programs
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
`
|
|
11
|
+
The JSON of `cfamily`'s syntax with `"lang": {"k": "langC"}`, on LP64. The branch covers the integer types with C's
|
|
12
|
+
promotions and conversions, control flow (`if`, loops, `switch`, `goto`), arrays (multi-dimensional, variable length,
|
|
13
|
+
`const`), pointers with their provenance, `malloc`, `realloc` and `free`, structs and unions, function pointers,
|
|
14
|
+
floating point and `<math.h>`, `<string.h>` and `<ctype.h>`, `printf`, `scanf` and their string and file forms,
|
|
15
|
+
`strtok`, `qsort` and `bsearch`, and standard input. A C program names no board (one that does is `invalid`: an Arduino
|
|
16
|
+
program is C++).
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
`cpp.outOfFuel` rather than assuming termination;
|
|
22
|
-
- `c.switchC p e blocks refl` — the controlling expression is promoted, `case` labels are converted to the promoted type before comparing;
|
|
23
|
-
the last argument proves the converted labels are distinct and there is at most one `default` (in `unsigned int`, `-1` and `4294967295`
|
|
24
|
-
are the same label, so `refl` fails).
|
|
18
|
+
## Entries
|
|
25
19
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```cella
|
|
34
|
-
import c
|
|
35
|
-
def p : cpp.Platform := c.lp64P
|
|
36
|
-
def n (v : Int) (ok : cpp.inTB (c.tInt p) v = true) : c.Arg := c.argV p (c.litV (c.tInt p) v ok)
|
|
37
|
-
def s : c.format p "%5d|%-+4d|%#x" [n (pos 42) refl, n (pos 7) refl, n (pos 255) refl] refl = " 42|+7 |0xff" := refl -- accept
|
|
38
|
-
def t : String := c.format p "%d %d" [n (pos 1) refl] refl -- reject: too few arguments
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Arrays: `c.Arr t` (fixed length; elements may be uninitialized). `c.zerosA t n` (`static`, `= {0}`), `c.uninitA t n` (automatic),
|
|
42
|
-
`c.initA t n [x0, …] refl` (`{…}`; missing elements are zero, too many initializers do not check). `c.at a i (c.readable refl)` reads an
|
|
43
|
-
element that is in bounds and initialized, `c.setAt a i x (c.inBounds refl)` writes in bounds; the index is a C value of any integer
|
|
44
|
-
type. `c.sizeofA p a` is `N * sizeof(T)` as a `size_t`. For loops, `c.Full t n` carries its length and "all initialized" in its type:
|
|
45
|
-
`c.getK f k h` / `c.putK f k h x` take the `h : k < n` given by a counting loop, so the body needs no separate proof of bounds.
|
|
46
|
-
|
|
47
|
-
```cella
|
|
48
|
-
import c
|
|
49
|
-
def p : cpp.Platform := c.lp64P
|
|
50
|
-
def a : c.Arr (c.tInt p) := c.initA (c.tInt p) 5 [c.litV (c.tInt p) (pos 1) refl, c.litV (c.tInt p) (pos 2) refl] refl
|
|
51
|
-
def s : c.get (c.at a (c.litV (c.tInt p) (pos 3) refl) (c.readable refl)) = pos 0 := refl -- accept: a[3] is zero
|
|
52
|
-
def t : c.Val (c.tInt p) := c.at a (c.litV (c.tInt p) (pos 5) refl) (c.readable refl) -- reject: a[5] is out of bounds
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Memory follows CH2O (Krebbers, *The C standard formalized in Coq*): a program has one memory `c.CMem` (`c.memNew` is empty), every
|
|
56
|
-
allocation is a tree of values (integers, pointers, arrays, struct and union members), and a pointer `c.Ptr` is NULL or (allocation, path,
|
|
57
|
-
index) — the path walks struct members and array cells down to an array (a scalar counts as an array of length 1, 6.5.6p7), and the index is
|
|
58
|
-
the position in it. So `&x`, `&a[i]`, `&s.k` and `p->name` are the same kind of pointer, and a function taking `int *` or `char *` works on
|
|
59
|
-
all of them. `c.addrOf t m x` is `&x`, `c.load t m q (c.derefOk refl)` is `*q` (not NULL, allocation alive, in bounds, initialized, and the
|
|
60
|
-
object has type t — reading an `int` through a `long *` is strict aliasing, 6.5p7), `c.store t m q v (c.storeOk refl)` is `*q = v`, and
|
|
61
|
-
`c.memberPtr m p "k"` is `&p->k`. Arrays decay with `c.arrToMem`; `c.ptrAdd` / `c.idx` require the result to stay inside the same array or
|
|
62
|
-
one past its end — pointer arithmetic does not cross into the next member — and `c.ptrDiff` / `c.ptrLt` require both pointers to be in
|
|
63
|
-
the same array. `c.malloc ct m n fails` takes whether the allocation fails as a parameter (the environment's choice; failure returns NULL),
|
|
64
|
-
so a verdict must hold for both outcomes — dereferencing without a NULL check does not prove. `c.calloc` zero-fills; `c.free` requires NULL
|
|
65
|
-
or a live block from `malloc`, pointed at its start. `c.toVoid` / `c.fromVoid` convert through `void*`, back to the original type only.
|
|
66
|
-
`c.loadStore` proves that `*q = v; *q` reads `v` for any memory and pointer.
|
|
67
|
-
|
|
68
|
-
```cella
|
|
69
|
-
import c
|
|
70
|
-
def t : cpp.IType := cpp.tInt cpp.lp64P
|
|
71
|
-
def r : c.Allocated := c.addrOf t c.memNew (c.litV t (pos 5) refl) -- int x = 5; int *q = &x;
|
|
72
|
-
def s : c.get (c.load t (c.amem r) (c.aptr r) (c.derefOk refl)) = pos 5 := refl -- accept: *q is 5
|
|
73
|
-
def u : c.Val t := c.load t c.memNew c.nullP (c.derefOk refl) -- reject: *NULL
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Strings are NUL-terminated `char` arrays in that memory. `c.strArr p m "abc"` is `char s[] = "abc"`, `c.strArrN p m 10 "abc" refl` is
|
|
77
|
-
`char s[10] = "abc"` (zero-filled; exactly N bytes leaves no NUL), and `c.strLit p m "abc"` is `char *s = "abc"` — a read-only allocation, so
|
|
78
|
-
writing through it does not prove. `<string.h>`: `c.strlen`, `c.strcmp`, `c.strncmp`, `c.strcpy`, `c.strncpy` (writes no NUL when the source is
|
|
79
|
-
not shorter than n), `c.strcat`, `c.strchr`; their preconditions are `c.cstrOk refl` (a NUL is reachable), `c.cstrNOk refl` (the first n bytes
|
|
80
|
-
or a NUL), and `c.strcpyOk refl refl` etc. (the destination is writable and large enough, no overlap). They work on whatever array the pointer
|
|
81
|
-
is in, a member array included (`strcpy(p->name, "Ann")`). `printf` takes strings with `c.argS t m q` for `%s` (width, `-`, precision; with a
|
|
82
|
-
precision the array needs no NUL). `<ctype.h>`: `c.isdigit`, `isalpha`, `isspace`, `isupper`, `islower`, `toupper`, `tolower`, whose argument
|
|
83
|
-
must be an `unsigned char` value or `EOF` (`c.ctypeArg refl`).
|
|
84
|
-
|
|
85
|
-
```cella
|
|
86
|
-
import c
|
|
87
|
-
def p : cpp.Platform := c.lp64P
|
|
88
|
-
def C : cpp.IType := c.tChar p
|
|
89
|
-
def r : c.Allocated := c.strLit p c.memNew "hello"
|
|
90
|
-
def s : c.format p "[%-7s]" [c.argS C (c.amem r) (c.aptr r)] refl = "[hello ]" := refl -- accept
|
|
91
|
-
def t : c.CMem := c.store C (c.amem r) (c.aptr r) (c.litV C (pos 72) refl) (c.storeOk refl) -- reject: writes a string literal
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Structs are described by their members, `c.mCons "x" (c.ctInt t) (c.mCons "next" c.ctPtr c.mNil)`, and a struct value has type
|
|
95
|
-
`c.Struct ms`; every scalar member may be uninitialized on its own. `c.initS ms [c.iInt x, …] refl` is an initializer list (missing members
|
|
96
|
-
are zero), `c.member ms "x" s` / `c.setMember ms "x" v s` access by name, and `c.scalar … refl` reads a member that has been initialized.
|
|
97
|
-
In memory, `c.varOf (c.ctStruct ms) s m` allocates a struct and `c.malloc (c.ctStruct ms) m n fails` allocates n of them; `c.arrow ms "v" m q refl`
|
|
98
|
-
is `q->v` and `c.arrowSet ms "v" x m q refl` is `q->v = x` — a `malloc`ed struct is initialized member by member, so this needs no other
|
|
99
|
-
member to be initialized. A member can also be reached through a pointer to it (`c.memberPtr`), so `swap(&s.a, &s.b)` is the same `swap` as
|
|
100
|
-
for two variables. Arrays of structs: `c.structArr`. A linked list whose every `malloc` may fail is in `tests/t_linked_list.cella`, and
|
|
101
|
-
pointers to members in `tests/t_member_ptr.cella`.
|
|
102
|
-
|
|
103
|
-
```cella
|
|
104
|
-
import c
|
|
105
|
-
def I : cpp.IType := c.tInt c.lp64P
|
|
106
|
-
def Point : c.Members := c.mCons "x" (c.ctInt I) (c.mCons "y" (c.ctInt I) c.mNil)
|
|
107
|
-
def p : c.Struct Point := c.initS Point [c.iInt (c.litV I (pos 1) refl)] refl
|
|
108
|
-
def y : c.get (c.scalar (c.member Point "y" p) refl) = pos 0 := refl -- accept: y is zero-filled
|
|
109
|
-
def u : c.Val I := c.scalar (c.member Point "y" (c.uninitS Point)) refl -- unknown: y is uninitialized (stricter than C)
|
|
110
|
-
def r : c.Allocated := c.varOf (c.ctStruct Point) p c.memNew -- struct Point s = {1};
|
|
111
|
-
def py : c.Ptr := c.memberPtr (c.amem r) (c.aptr r) "y" -- int *py = &s.y;
|
|
112
|
-
def z : c.get (c.load I (c.amem r) py (c.derefOk refl)) = pos 0 := refl -- accept: *py is 0
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Array parameters are pointers, so a function does not know the length: `int sum(int a[], int n)` takes the precondition
|
|
116
|
-
`c.readableNB t m a n = true` ("n cells after a are readable"), and `c.readK t m a n ok k h` reads `a[k]` for `h : k < n` — the function is
|
|
117
|
-
checked once for any memory and pointer, and a caller with a concrete array proves the precondition by `refl`. Writing is the same with
|
|
118
|
-
`c.writableNB` / `c.writeK`, and `c.writableAfterWriteK` keeps the precondition through a loop. Pointers can be stored in memory
|
|
119
|
-
(`c.addrOfPtr`, `c.loadP` for `*pp`), and `c.mkArgv p ["prog", "x"]` builds `argv` (NUL-terminated strings, a NULL at `argv[argc]`).
|
|
120
|
-
|
|
121
|
-
For a debugger, `c.ptrText names m q` shows a pointer the way the source would write it — `&x`, `a`, `&a[2]`, `a + 4`, `&s.k`, `NULL`
|
|
122
|
-
(`names` maps allocations to variable names; an unnamed allocation from `malloc` shows as `heap#b`) — and `c.varJsonPtr` gives a pointer
|
|
123
|
-
variable for the variables panel in the same JSON shape as the C++ and Python models.
|
|
124
|
-
|
|
125
|
-
Input: `c.scanf p "%d %s" [c.tgtInt t, c.tgtChars 8] st refl` reads from the input state shared with the C++ model (`cpp.ios "12 abc"`)
|
|
126
|
-
and returns what was read: `c.scanCount p r` (the number of assignments, or EOF), `c.assignInt r k t old` (the k-th assigned value, or the
|
|
127
|
-
old value when the conversion failed), `c.scannedBytes r k` and `c.scanSt r` (the rest of the input). The precondition rejects a target of the
|
|
128
|
-
wrong type, a result that does not fit (`%d` reading `99999999999`), and a `%s` that does not fit its array.
|
|
129
|
-
|
|
130
|
-
Multi-dimensional arrays: `c.arr2ToMem t m R C inits refl` declares `T a[R][C]` (nested or flat initializers), and `c.at2 t m a R C i j hi hj ok`
|
|
131
|
-
reads `a[i][j]` with the bounds checked per dimension — `a[0][C]` is out of bounds for the inner array even though it is inside the object.
|
|
132
|
-
A function taking `int a[][C]` gets `c.readable2 t m a n C = true` and reads with `c.read2K`.
|
|
133
|
-
|
|
134
|
-
Floating point: `c.Double` and `c.Float` are IEEE 754 binary64 and binary32 (shared with the C++ model). `c.dlit m e` is the literal
|
|
135
|
-
m × 10^e; `c.toInt t x (c.truncOk refl)` truncates toward zero with the result required to fit; division needs a nonzero divisor.
|
|
136
|
-
`printf` takes doubles through `c.argF` (`%f %e %g` with flags, width and precision), `scanf` reads them into `c.tgtFloat`, and
|
|
137
|
-
`c.sqrt`, `floor`, `ceil`, `round`, `trunc`, `pow`, `fmod`, `fabs`, `exp`, `log`, `log10`, `log2`, `exp2`, `sin`, `cos`, `tan`, `asin`, `acos`,
|
|
138
|
-
`atan`, `atan2`, `expm1`, `log1p`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `cbrt`, `hypot` follow `<math.h>` with correctly rounded results (the standard does not require a correctly rounded libm).
|
|
139
|
-
|
|
140
|
-
Function pointers: a signature `c.sig [c.fInt t, …] r` describes the type; C functions return `Option` (`none` is undefined
|
|
141
|
-
behavior in that call, e.g. `c.addM` overflowing). `c.fnOf "f" s f` takes `&f`, `c.fnCast` converts (the pointer remembers the
|
|
142
|
-
function it points to), and `c.call2 s p x y refl` calls through it — the proof says the pointer is not NULL, its type matches the
|
|
143
|
-
function, and the call is defined. `c.qsort` and `c.bsearch` take a comparator `c.FnPtr (c.cmpSig p t)` that must be a consistent
|
|
144
|
-
total order on the array.
|
|
145
|
-
|
|
146
|
-
Memory functions: `c.realloc m q n fails ok` keeps the first min(old, n) cells and ends the old allocation (failure is a
|
|
147
|
-
parameter, as with `malloc`; `n = 0` is not in the subset). `c.memcpy`, `c.memmove` and `c.memset` count elements, not bytes;
|
|
148
|
-
`memcpy` requires the two ranges not to overlap.
|
|
149
|
-
|
|
150
|
-
Unions: `c.ctUnion ms` uses the same member list as a struct. A `c.Union ms` remembers which member was written last;
|
|
151
|
-
`c.uset` writes a member and `c.uget ms k u refl` reads it only if it is that member (reading another member reinterprets
|
|
152
|
-
bytes in C, which the model does not represent). `c.initU ms [c.iField "k" v] refl` is `= {.k = v}`.
|
|
153
|
-
|
|
154
|
-
More of `<string.h>`: `c.strstr`, `c.strrchr`, `c.strncat` (reads at most n bytes of the source), and `c.memcmp` / `c.memchr`
|
|
155
|
-
on character arrays (on `int` arrays `memcmp` compares bytes in memory order, so its sign depends on the representation).
|
|
156
|
-
|
|
157
|
-
Tokens and lines: `scanf` supports `%[...]` (scan sets, `^` for the complement); `c.strtok` makes the hidden state of
|
|
158
|
-
`strtok` an explicit value — pass `c.tokInit` the first time and the previous `c.tokState` (with a NULL string) afterwards.
|
|
159
|
-
|
|
160
|
-
Formatting into memory: `c.sprintf` and `c.snprintf` write `c.format`'s output into a buffer (the output must fit and must not
|
|
161
|
-
overlap a `%s` argument; `snprintf` truncates to n − 1 bytes and returns the full length); `c.sscanf` reads from a string in memory.
|
|
162
|
-
|
|
163
|
-
Character and line I/O: `c.putchar`, `c.puts`, `c.getchar` (EOF at the end of input) and `c.fgets` (at most n − 1 bytes,
|
|
164
|
-
keeping the newline) share the `cpp.IOS` state with `printf` and `scanf`.
|
|
165
|
-
|
|
166
|
-
Number conversions: `c.atoi` (overflow is undefined, so the result must fit), `c.strtol` (base 0 or 2–36, clamps to
|
|
167
|
-
`LONG_MAX` / `LONG_MIN` and reports where it stopped), `c.abs` and `c.labs` (the most negative value is excluded).
|
|
168
|
-
|
|
169
|
-
Variable length arrays: `c.vla t m n ok` declares `T a[n]` with a run-time length that must be positive, and `c.vla2` declares
|
|
170
|
-
`T a[r][c]`; the elements start uninitialized.
|
|
171
|
-
|
|
172
|
-
Const objects: `c.constArrToMem` and `c.constAddrOf` allocate read-only storage, so writing through a pointer that cast the
|
|
173
|
-
`const` away (or passing the array to a function that writes it) is rejected.
|
|
174
|
-
|
|
175
|
-
Random numbers: the sequence of `rand` is implementation-defined, so it is a parameter (`c.RandEnv`) and a verdict holds for
|
|
176
|
-
every environment — e.g. `rand() % 6 + 1` is between 1 and 6 for any `RAND_MAX` ≥ 32767 and any sequence.
|
|
177
|
-
|
|
178
|
-
Files: `c.FState` is the file system (an environment given by `c.fsInit`) plus the open files. `c.fopen` takes a `fails`
|
|
179
|
-
parameter like `malloc`, so the NULL check is required; `c.fscanf`, `c.fgetsF`, `c.fgetc`, `c.fprintf`, `c.fputs` and
|
|
180
|
-
`c.fclose` require the handle to be open in a suitable mode.
|
|
181
|
-
|
|
182
|
-
`goto`: a function body is a table of labeled blocks (`c.withLabels`); `c.gotoS "l"` leaves nested loops and ifs like a
|
|
183
|
-
`return` and resumes at block `l`, and `c.retJ` is the real return. Labels live at the top level of the body.
|
|
184
|
-
|
|
185
|
-
Length modifiers `z`, `j` and `t` (`printf("%zu", strlen(s))`) use the LP64 types: `size_t` is `unsigned long`, `ptrdiff_t` and
|
|
186
|
-
`intmax_t` are `long`.
|
|
187
|
-
|
|
188
|
-
`sizeof`: `c.sizeofV pl ct` computes sizes from a type descriptor (struct padding follows the LP64 ABI, which is
|
|
189
|
-
implementation-defined); `c.strspn`, `c.strcspn` and `c.strpbrk` complete the common `<string.h>` functions.
|
|
190
|
-
|
|
191
|
-
The integer core shared by the C family (type descriptors, platforms, promotions) comes from `@cella-lang/cpp`; C's value type is its own,
|
|
192
|
-
and its relation to C++'s is a proved path on the fragment where both languages agree.
|
|
193
|
-
|
|
194
|
-
```cella
|
|
195
|
-
import c
|
|
196
|
-
def p : cpp.Platform := c.lp64P
|
|
197
|
-
def x : c.Val (c.tInt p) := c.addV p (c.litV (c.tInt p) (pos 2) refl) (c.litV (c.tInt p) (pos 3) refl) (cpp.inT refl) -- accept
|
|
198
|
-
def y : c.Val (c.tInt p) := c.shlV p (c.litV (c.tInt p) (pos 1) refl) (c.litV (c.tInt p) (pos 31) refl) (c.shlOk refl) -- reject: 1 << 31 does not fit int
|
|
199
|
-
```
|
|
20
|
+
- `c.verdict src input fuel`: the verdict JSON (format in `@cella-lang/cfamily`); `input` is standard input, `fuel`
|
|
21
|
+
bounds the steps. A verdict proved by the kernels: `kernel_verdict_in("c", "c.verdict", …)` in `cella-lang`.
|
|
22
|
+
- `c.types src candidates`: the type query (format in `@cella-lang/cfamily`).
|
|
23
|
+
- The debugger, for `cella-lang/dap`: `load`, `run`, `stopConf`, `stopKind`, `stopNode`, `stopOut`, `stopErr`,
|
|
24
|
+
`stopDetail`, `divergences`, `feed`, `globals`, `frames`, `setVarErr`, `setVarConf`, `env`; and `report input fuel
|
|
25
|
+
session`, a whole run with all the input given at once.
|
|
200
26
|
|
|
201
27
|
## Loading
|
|
202
28
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
import init, { init_stdlib_cached, load_module_pack, load_library_pack, check } from 'cella-lang';
|
|
208
|
-
import assets from 'cella-lang/assets';
|
|
209
|
-
// 1. the standard modules it and its dependencies need: index.requires["cella-lang"].modules
|
|
210
|
-
for (const m of JSON.parse(index).requires['cella-lang'].modules) load_module_pack(await bytes(assets.module(m)));
|
|
211
|
-
// 2. the packages it depends on, in order: index.requires.packages (each with its own index.json)
|
|
212
|
-
load_library_pack(cppIndex, 'cpp', await bytes(cppPackUrl));
|
|
213
|
-
// 3. the library itself
|
|
214
|
-
const r = JSON.parse(load_library_pack(index, 'c', await bytes(new URL('./c.cell', libUrl))));
|
|
215
|
-
if (!r.ok) throw new Error(r.error);
|
|
216
|
-
```
|
|
29
|
+
Load the packs into the `cella-lang` build named by `index.json` (`checkerHash`, `cbfVersion`; the `peerDependencies`
|
|
30
|
+
pin it): the standard modules in `index.requires["cella-lang"].modules`, the packages in `index.requires.packages`
|
|
31
|
+
(each the same way), then this package's modules in the order of `index.modules.c.deps`. `cella-lang`'s README
|
|
32
|
+
(*Official packages*) has the code.
|
|
217
33
|
|
|
218
34
|
## Per-definition hashes
|
|
219
35
|
|
|
220
|
-
`index.json` lists, for every definition, `own` (its own content) and `merkle` (its content
|
|
36
|
+
`index.json` lists, for every definition, `own` (its own content) and `merkle` (its content and everything it depends
|
|
37
|
+
on). A definition whose `merkle` did not change between two versions means the same; a changed one is listed in
|
|
38
|
+
`CHANGES.md`.
|
package/c.cell
CHANGED
|
Binary file
|