From 00b880e35e8cbdc564530b0257347468908f665b Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 5 Aug 2022 00:58:58 +0200 Subject: [PATCH] Nicer plus_minus --- resources/examples/plus_minus.c3 | 83 ++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/resources/examples/plus_minus.c3 b/resources/examples/plus_minus.c3 index 58b5431e9..1764efb51 100644 --- a/resources/examples/plus_minus.c3 +++ b/resources/examples/plus_minus.c3 @@ -7,35 +7,78 @@ fault TokenResult NO_MORE_TOKENS } + +// While we could have written this with libc +// the C way, let's showcase some features added to C3. +fn void main(char[][] args) +{ + // Grab a string from stdin + String s = io::stdin().getline(); + // Delete it at scope end [defer] + defer s.destroy(); + + // Grab the string as a slice. + char[] numbers = s.str(); + + // Track our current value + int val = 0; + + // Is the current state an add? + bool add = true; + + while (try char[] token = read_next(&numbers)) + { + // We're assuming well formed input here + // so just use atoi. + int i = libc::atoi(token.ptr); + + // This value is either added or subtracted from the sum. + val = add ? val + i : val - i; + + // Read an optional token. + char[]! op = read_next(&numbers); + + // If it's an error, then we're done. + if (catch op) break; + + // Let's process the operator + switch (op) + { + case "+": + add = true; + case "-": + add = false; + default: + io::println("Failed to parse expression."); + return; + } + } + io::printfln("%d", val); +} + fn char[]! read_next(char[]* remaining) { - // Skip spaces. - while (remaining.len > 0 && (*remaining)[0] == ' ') *remaining = (*remaining)[1..]; + while (remaining.len > 0 && (*remaining)[0] == ' ') + { + // Make the slice smaller + *remaining = (*remaining)[1..]; + } + + // Store the beginning of the parse char* ptr_start = remaining.ptr; usize len = 0; while (remaining.len > 0 && (*remaining)[0] != ' ') { + // Increase length len++; + + // And make the slice smaller *remaining = (*remaining)[1..]; } + + // If it's a zero length token, return an optional result. if (!len) return TokenResult.NO_MORE_TOKENS!; + + // Otherwise create a slice from the pointer start and length. return ptr_start[:len]; } - -fn void main(char[][] args) -{ - String s = io::stdin().getline(); - defer s.destroy(); - char[] numbers = s.str(); - int val = 0; - bool add = true; - while (try char[] token = read_next(&numbers)) - { - int i = libc::atoi(token.ptr); - val = add ? val + i : val - i; - char[]! op = read_next(&numbers); - if (catch op) break; - add = op[0] == '+'; - } - io::printfln("%d", val); -} \ No newline at end of file