Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/development/std/os.nct

os.nct

//! Common internal OS error model.
//!
//! Target-specific boundaries convert raw platform error values into OSError.
//! User-facing modules expose only the built-in `error` payload from fallible
//! APIs; OSError and OSErrorKind stay behind `pub(nocter)` visibility.

pub(nocter) enum Platform {
    macos
    linux
    windows
}

pub(nocter) enum OSErrorKind {
    interrupted
    would_block
    not_found
    permission_denied
    already_exists
    invalid_input
    broken_pipe
    timed_out
    unsupported
    unknown
}

pub(nocter) copy struct OSError {
    pub platform: Platform
    pub code: i32
    pub kind: OSErrorKind
}

#target: "arm64-darwin"
pub(nocter) copy struct SyscallResult {
    pub value: usize
    pub errno: i32
}

#target: "arm64-darwin"
pub(nocter) copy struct Errno {
    pub code: i32
}

#target: "arm64-darwin"
pub(nocter) func errno(code: i32): Errno {
    return Errno { code: code }
}

#target: "arm64-darwin"
pub(nocter) func error_from_errno(error: Errno): OSError {
    return OSError {
        platform: Platform.macos,
        code: error.code,
        kind: kind_from_errno(error),
    }
}

#target: "arm64-darwin"
pub(nocter) func kind_from_errno(error: Errno): OSErrorKind {
    // Darwin errno values used by the std syscall wrappers.
    if error.code == 4 {
        return OSErrorKind.interrupted
    }
    if error.code == 35 {
        return OSErrorKind.would_block
    }
    if error.code == 2 {
        return OSErrorKind.not_found
    }
    if error.code == 20 {
        return OSErrorKind.not_found
    }
    if error.code == 1 {
        return OSErrorKind.permission_denied
    }
    if error.code == 13 {
        return OSErrorKind.permission_denied
    }
    if error.code == 17 {
        return OSErrorKind.already_exists
    }
    if error.code == 9 {
        return OSErrorKind.invalid_input
    }
    if error.code == 14 {
        return OSErrorKind.invalid_input
    }
    if error.code == 21 {
        return OSErrorKind.invalid_input
    }
    if error.code == 22 {
        return OSErrorKind.invalid_input
    }
    if error.code == 32 {
        return OSErrorKind.broken_pipe
    }
    if error.code == 60 {
        return OSErrorKind.timed_out
    }
    if error.code == 45 {
        return OSErrorKind.unsupported
    }
    return OSErrorKind.unknown
}

// Darwin syscall number constants belong in this module. The exact constant
// list is filled in as each wrapper is implemented.

#target: "arm64-darwin"
pub(nocter) func darwin_sys_open(): usize {
    return 0x02000005
}

#target: "arm64-darwin"
pub(nocter) func darwin_sys_close(): usize {
    return 0x02000006
}

#target: "arm64-darwin"
pub(nocter) func darwin_sys_fcntl(): usize {
    return 0x0200005c
}

#target: "arm64-darwin"
pub(nocter) func darwin_f_getpath(): usize {
    return 50
}

#target: "arm64-darwin"
pub(nocter) func darwin_max_path_len(): usize {
    return 1024
}

#target: "arm64-darwin"
pub(nocter) primitive syscall0(number: usize): SyscallResult

#target: "arm64-darwin"
pub(nocter) primitive syscall1(
    number: usize,
    a0: usize,
): SyscallResult

#target: "arm64-darwin"
pub(nocter) primitive syscall2(
    number: usize,
    a0: usize,
    a1: usize,
): SyscallResult

#target: "arm64-darwin"
pub(nocter) primitive syscall3(
    number: usize,
    a0: usize,
    a1: usize,
    a2: usize,
): SyscallResult

#target: "arm64-darwin"
pub(nocter) primitive syscall4(
    number: usize,
    a0: usize,
    a1: usize,
    a2: usize,
    a3: usize,
): SyscallResult

#target: "arm64-darwin"
pub(nocter) primitive syscall5(
    number: usize,
    a0: usize,
    a1: usize,
    a2: usize,
    a3: usize,
    a4: usize,
): SyscallResult

#target: "arm64-darwin"
pub(nocter) primitive syscall6(
    number: usize,
    a0: usize,
    a1: usize,
    a2: usize,
    a3: usize,
    a4: usize,
    a5: usize,
): SyscallResult

#target: "arm64-darwin"
pub(nocter) primitive trap(): never

#target: "arm64-darwin"
pub(nocter) primitive unreachable(): never