io.Writer 는 핸들 하나짜리 enum 이다. 참조도 컨텍스트 포인터도 담지 않으므로 Copy 이고 자유롭게 오간다 (SPEC 5 R8). fmt 는 sink 를 소유하지 않는다 -- 호출자가 버퍼를 주고 앞에서 몇 바이트가 쓰였는지 돌려받는다. lowering 에 추가: enum 변이 상수, match, 정수 캐스트, 문자열 이스케이프. 프론트엔드 정밀도 하나: 항상 빠져나가는 분기의 상태를 병합하지 않는다. 그 분기가 소비한 값이 그 분기를 지나지 않은 경로에서도 소비된 것처럼 보였다. fmt_i32 가 이것 때문에 못 쓰였다. extern "c" 이름은 유닛 접두사를 붙이지 않는다. 링커가 이미 아는 이름이라는 것이 그 선언의 요점이다. run.py 199/199, exec.py 11/11.
33 lines
939 B
Plaintext
33 lines
939 B
Plaintext
unit std.fmt;
|
|
|
|
// Pure conversion. Nothing here owns a sink: the caller supplies the buffer
|
|
// and is told how many bytes at the front of it were written (SPEC 10).
|
|
|
|
pub fn fmt_u32(buf: []mut u8, v: u32) -> usize {
|
|
var tmp: [10]u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
var value: u32 = v;
|
|
var count: usize = 0;
|
|
while true {
|
|
tmp[count] = ((value % 10) as u8) + ('0' as u8);
|
|
count = count + 1;
|
|
value = value / 10;
|
|
if value == 0 { break; }
|
|
if count == 10 { break; }
|
|
}
|
|
var i: usize = 0;
|
|
while i < count {
|
|
if i < buf.n { buf[i] = tmp[count - 1 - i]; }
|
|
i = i + 1;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
pub fn fmt_i32(buf: []mut u8, v: i32) -> usize {
|
|
if v >= 0 { return fmt_u32(buf, v as u32); }
|
|
if buf.n == 0 { return 0; }
|
|
buf[0] = '-' as u8;
|
|
var rest: []mut u8 = buf[1..buf.n];
|
|
let digits: usize = fmt_u32(rest, (0 - v) as u32);
|
|
return digits + 1;
|
|
}
|