Files
c3c/resources/examples/plus_minus.c3
2023-01-11 18:00:08 +01:00

85 lines
1.6 KiB
C

module test;
import std::io;
import libc;
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(String[] args)
{
// Grab a string from stdin
VarString s = io::stdin().getline();
// Delete it at scope end [defer]
defer s.destroy();
// Grab the string as a slice.
String numbers = s.str();
// Track our current value
int val = 0;
// Is the current state an add?
bool add = true;
while (try String 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.
String! 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::printfn("%d", val);
}
fn String! read_next(String* remaining)
{
while (remaining.len > 0 && (*remaining)[0] == ' ')
{
// Make the slice smaller
*remaining = (*remaining)[1..];
}
// Store the beginning of the parse
char* ptr_start = remaining.ptr;
usz 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];
}