Skip to main content

Input, conversions & results

read_line() reads one line from standard input and returns result<string>. parse_int(text) and parse_float(text) return result<int> and result<float>. Failures are values: the program chooses whether to retry, report an error, or stop.

show "What is your name?"
assign line as read_line()
if is_ok(line) {
show "Hello, " + unwrap(line) + "!"
} else {
if is_eof(line) {
show "Goodbye."
} else {
show error_message(line)
}
}

Result values​

A result contains an integer status and a scalar payload. Its annotation is result<int>, result<float>, result<bool>, or result<string>. Results can be stored, reassigned, passed to functions, and returned. Payload types must match exactly; nested results, array payloads, and implicit result conversions are unsupported.

OperationMeaning
ok(value)Successful result; infers its scalar payload type
err<int>(8)Failed integer result with an explicit status; also accepts float, bool, string
is_ok(result)True when status is zero
is_eof(result)True when status is 1
error_code(result)Integer status, including zero for success
error_message(result)Owned string describing the status
unwrap(result)Extracts a successful payload; exits 1 with a checked runtime diagnostic on error

Check is_ok before unwrap. Results cannot be printed directly with show. String payloads retain the existing value semantics: copying a result preserves its text even if the original is reassigned. Storage is cleaned up automatically. There is no try propagation operator or general user-defined enum system yet. err is a reserved keyword; the built-in function names cannot be redeclared.

function positive(text: string) -> result<int> {
assign parsed as parse_int(text)
if is_ok(parsed) {
assign value as unwrap(parsed)
if value > 0 { return ok(value) }
return err<int>(8)
}
return parsed
}
assign value as positive("42")
if is_ok(value) { show unwrap(value) }

Error codes​

Codeerror_messageMeaning
0No errorSuccessful result
1End of inputNo bytes remain before another line starts
2Invalid numberInvalid integer or decimal floating syntax
3Value out of rangeNumeric overflow/underflow, or input size overflow
4Input/output errorReading stdin or flushing the prompt failed
5Input is not valid UTF-8Invalid UTF-8, or invalid Windows console UTF-16
6Input contains a NUL byteEmbedded NUL is unsupported
7Memory allocation failedThe input or parsing helper could not allocate
8–2147483647Unknown errorApplication-defined codes; handle them in your program

err<T>(code) requires an integer in 1–2147483647. An invalid code triggers a checked runtime failure. Codes 1–7 are reserved for the built-in meanings.

Line behavior​

read_line() flushes stdout before reading, so a preceding show prompt is visible even through a pipe. It removes LF and the CR immediately preceding LF. An empty line succeeds with ""; a final line without a newline also succeeds. A subsequent read returns EOF. A trailing CR without LF remains in the string.

Input must be UTF-8 without NUL. Rejected lines, including lines whose buffer allocation fails, are consumed through LF or EOF so a retry starts at the next line. An I/O failure returns immediately. Input length grows with available memory. Windows console input uses wide-character reads converted to UTF-8; redirected input uses binary byte reads. Ordinary output retains host CRT behavior.

Explicit conversions​

parse_int accepts ASCII whitespace around optional +/- and decimal digits, within signed 64-bit range. It rejects fractions, hexadecimal notation, internal spaces, separators, and non-ASCII digits or whitespace.

parse_float accepts a decimal number with optional sign, decimal point, and exponent, including 42, .5, 5., and 1e-3. It trims ASCII whitespace, uses the C numeric locale, and rejects trailing text, hexadecimal numbers, commas, NaN, and infinity. Overflow and libc-reported underflow produce code 3.

to_string(value) accepts int, float, bool, and string. Integers use signed decimal; booleans use true/false; strings preserve their contents. Floats use locale-independent %.17g, so ordinary finite values retain enough precision for a parse round trip. Subnormal values may fail the underflow check when parsed; non-finite calculation results format as text but cannot be parsed. show retains its existing %.15g float formatting. No implicit conversion is added.

assign parsed as parse_int(" 42 ")
if is_ok(parsed) {
show "Count: " + to_string(unwrap(parsed))
} else {
show "Try again: " + error_message(parsed)
}

Ordinary string copies, concatenation, error_message, and to_string still use checked fatal allocation diagnostics. Recoverable input does not make all allocation or arithmetic failures recoverable.

Interactive example and implementation​

Rebuild Cheeku to use the new syntax and built-ins:

cargo build --locked --release
./target/release/cheeku examples/temperature.chuchu -o temperature
./temperature

On Windows use target\release\cheeku.exe and -o temperature.exe. The converter source retries invalid numbers, rejects temperatures below absolute zero with application error 8, and exits on quit or EOF.

The compiler embeds a small C11 runtime and compiles it with the configured host Clang driver when needed; there is no separate runtime installation. Ordinary programs that use none of these native helpers keep their existing link path. The high-level compile_source/compile_file APIs link helpers automatically. Low-level object API users must write chuchu::runtime::c_source() to a .c file and compile/link it alongside objects that reference those helpers.

LLVM represents results as { i32 status, payload }; debugger fields are named code and value. Native integration tests cover input, conversion, result ownership, error recovery, and O0–O3 behavior. The debugger smoke script inspects integer and string result fields. For allocator accounting and injected failures:

python3 .github/scripts/io-memory-smoke.py --compiler target/release/cheeku \
--clang /path/to/llvm/bin/clang --sanitize

This implementation was validated locally on macOS ARM64. The shared CI includes the native input/conversion tests for macOS ARM64/Intel, Linux x64 GNU, and Windows x64 MSVC; results for this revision on the other hosts remain pending. Interactive Windows console input also requires native manual validation.