런타임에 open/read/close 와 명령줄을 넣었다. std.io 가 그 위에 파일 열기, 읽기, 쓰기, 그리고 명령줄을 조각으로 나누는 것을 얹는다. 인용부호 처리는 런타임이 알 일이 아니라 라이브러리가 할 일이다. 길에서 고친 것들: - *T 가 타입 시스템에 실체가 없어서 덩어리로 취급됐다. 이제 진짜 종류다 -- 주소일 뿐이고 추적할 대여도 실행할 drop 도 없는 Copy 타입. 그 결과 &u8 이 *u8 에 자동으로 맞지 않게 됐는데, 그게 맞다: R9 는 그 변환을 unsafe 안의 @ptr_cast 로만 허용한다. - raw 포인터에 정수를 더하면 더 뒤의 주소다. 소유자나 대여에는 허용하지 않는다 -- 자기 자리가 있는 것에서 걸어나가는 것이 *T 의 용도다. - @volatile_load / @volatile_store / @ptr_cast 를 내린다. - undefined 가 선언된 타입을 따른다. 없으면 손으로 타이핑할 수 있는 것보다 큰 버퍼를 선언할 방법이 아예 없었다. R8 이 정확히 동작하는 것도 확인했다: 참조성 파라미터가 둘인 함수는 슬라이스를 반환할 수 없다. 어디서 파생됐는지 시그니처가 말하지 않기 때문이다. exec.py 24/24.
38 lines
1.2 KiB
Plaintext
38 lines
1.2 KiB
Plaintext
// EXIT:0
|
|
// OUTPUT:read 64 bytes
|
|
// OUTPUT:first line: // EXIT:0
|
|
unit readfile;
|
|
import std.io;
|
|
|
|
// Reads its own source and reports the first line. A program that can open a
|
|
// file is a program that can be a compiler.
|
|
|
|
fn main() -> i32 {
|
|
var path: [64]u8 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
|
let n: usize = io.to_cstr(path[..], "fec/tests/exec/readfile.fe");
|
|
let handle: i32 = io.open_read(path[0..n]) catch |e| {
|
|
@print("cannot open\n");
|
|
return 1;
|
|
};
|
|
var buf: [64]u8 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
|
let got: usize = io.read(handle, buf[..]) catch |e| {
|
|
io.close(handle);
|
|
return 2;
|
|
};
|
|
io.close(handle);
|
|
@print("read {} bytes\n", n);
|
|
var stop: usize = 0;
|
|
while stop < got {
|
|
if buf[stop] == 10 { break; }
|
|
stop = stop + 1;
|
|
}
|
|
@print("first line: {}\n", buf[0..stop]);
|
|
return 0;
|
|
}
|