Files
coolguy 676fef88fb std: 프로그램이 바깥 세상과 이야기한다 -- 파일과 명령줄
런타임에 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.
2026-08-17 07:11:56 +09:00

54 lines
1.7 KiB
Plaintext

unit std.sys;
// The few things the language cannot say for itself. The runtime provides
// them; everything else in the standard library is written in Ferro.
extern "c" fn fe_rt_write(handle: i32, bytes: *u8, len: usize) -> i32;
extern "c" fn fe_rt_alloc(n: usize) -> *u8;
extern "c" fn fe_rt_free(p: *u8);
extern "c" fn fe_rt_exit(code: i32);
extern "c" fn fe_rt_allocs() -> i32;
extern "c" fn fe_rt_frees() -> i32;
extern "c" fn fe_rt_open(path: *u8, write: i32) -> i32;
extern "c" fn fe_rt_read(handle: i32, buf: *u8, len: usize) -> i32;
extern "c" fn fe_rt_close(handle: i32);
extern "c" fn fe_rt_cmdline() -> *u8;
pub fn exit(code: i32) -> void {
unsafe { fe_rt_exit(code); }
}
pub fn raw_write(handle: i32, bytes: *u8, len: usize) -> i32 {
unsafe { return fe_rt_write(handle, bytes, len); }
}
pub fn raw_alloc(n: usize) -> *u8 {
unsafe { return fe_rt_alloc(n); }
}
pub fn raw_free(p: *u8) -> void {
unsafe { fe_rt_free(p); }
}
// How many times the allocator was asked to hand out memory, and to take it
// back. A test can insist the two agree; nothing else should care.
pub fn allocs() -> i32 { unsafe { return fe_rt_allocs(); } }
pub fn frees() -> i32 { unsafe { return fe_rt_frees(); } }
pub fn raw_open(path: *u8, write: i32) -> i32 {
unsafe { return fe_rt_open(path, write); }
}
pub fn raw_read(handle: i32, buf: *u8, len: usize) -> i32 {
unsafe { return fe_rt_read(handle, buf, len); }
}
pub fn raw_close(handle: i32) -> void {
unsafe { fe_rt_close(handle); }
}
/// The whole command line as one NUL-terminated string. Splitting it into
/// arguments is `std.io`'s job: the runtime should not know about quoting.
pub fn raw_cmdline() -> *u8 {
unsafe { return fe_rt_cmdline(); }
}