From: Brendan Hansen Date: Wed, 1 Dec 2021 17:50:25 +0000 (-0600) Subject: added standard input reader for onyx and wasi X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=c9533a4682256d53be6cc138b94b4b9deb6911b3;p=onyx.git added standard input reader for onyx and wasi --- diff --git a/core/io/reader.onyx b/core/io/reader.onyx index 3f14df9d..800313d5 100644 --- a/core/io/reader.onyx +++ b/core/io/reader.onyx @@ -218,10 +218,12 @@ read_u64 :: (use reader: ^Reader) -> u64 { return n; } -read_line :: (use reader: ^Reader, consume_newline := true, allocator := context.allocator) -> str { +read_line :: (use reader: ^Reader, consume_newline := true, allocator := context.allocator, inplace := false) -> str { reader_read_next_chunk(reader); count := start; + defer start = count; + while count < end && buffer[count] != #char "\n" { count += 1; } @@ -230,21 +232,23 @@ read_line :: (use reader: ^Reader, consume_newline := true, allocator := context count += 1; } + if inplace do return buffer[start .. count]; + out := str.{ data = raw_alloc(allocator, count * sizeof(u8)), count = count - start, }; memory.copy(out.data, buffer.data + start, count - start); - start = count; return out; } -read_word :: (use reader: ^Reader, numeric_allowed := false, allocator := context.allocator) -> str { +read_word :: (use reader: ^Reader, numeric_allowed := false, allocator := context.allocator, inplace := false) -> str { skip_whitespace(reader); reader_read_next_chunk(reader); count := start; + defer start = count; while count < end { curr := buffer[count]; if (curr >= #char "a" && curr <= #char "z") @@ -258,20 +262,22 @@ read_word :: (use reader: ^Reader, numeric_allowed := false, allocator := contex } } + if inplace do return buffer[start .. count]; + out := str.{ data = raw_alloc(allocator, count * sizeof(u8)), count = count - start, }; memory.copy(out.data, buffer.data + start, count - start); - start = count; return out; } -read_until :: (use reader: ^Reader, until: u8, skip: u32 = 0, allocator := context.allocator, consume_end := false) -> str { +read_until :: (use reader: ^Reader, until: u8, skip: u32 = 0, allocator := context.allocator, consume_end := false, inplace := false) -> str { reader_read_next_chunk(reader); count := start; + defer start = count; while count < end { curr := buffer[count]; if curr != until { @@ -284,13 +290,14 @@ read_until :: (use reader: ^Reader, until: u8, skip: u32 = 0, allocator := conte if consume_end && count < end do count += 1; + if inplace do return buffer[start .. count]; + out := str.{ data = raw_alloc(allocator, count * sizeof(u8)), count = count - start, }; memory.copy(out.data, buffer.data + start, count - start); - start = count; return out; } diff --git a/core/runtime/js.onyx b/core/runtime/js.onyx index be24ba77..3be87279 100644 --- a/core/runtime/js.onyx +++ b/core/runtime/js.onyx @@ -4,8 +4,9 @@ package runtime use package core -__output_string :: (s: str) -> u32 #foreign "host" "print_str" --- -__exit :: (status: i32) -> void #foreign "host" "exit" --- +__output_string :: (s: str) -> u32 #foreign "host" "print_str" --- +__exit :: (status: i32) -> void #foreign "host" "exit" --- +__read_from_input :: (buf: [] u8) -> u32 do return 0; // The builtin _start proc. // Sets up everything needed for execution. diff --git a/core/runtime/wasi.onyx b/core/runtime/wasi.onyx index 16deca74..417035de 100644 --- a/core/runtime/wasi.onyx +++ b/core/runtime/wasi.onyx @@ -18,6 +18,18 @@ __output_string :: (s: str) -> u32 { __exit :: (status: i32) do proc_exit(status); +__read_from_input :: (buffer: [] u8) -> i32 { + STDIN_FILENO :: 0 + + vec := IOVec.{ buf = cast(i32) buffer.data, len = buffer.count }; + read: Size; + error := fd_read(STDIN_FILENO, .{ cast(i32) ^vec, 1 }, ^read); + if error != .Success do return -1; + + return read; +} + + // The builtin _start proc. // Sets up everything needed for execution. #export "_start" () { diff --git a/core/stdio.onyx b/core/stdio.onyx index 1b611fbd..edc82140 100644 --- a/core/stdio.onyx +++ b/core/stdio.onyx @@ -108,6 +108,10 @@ byte_dump :: (ptr: rawptr, byte_count: u32, bytes_per_line := 8) { __stdio_init :: () { stdio.print_stream = io.dynamic_string_stream_make(2048, context.allocator); stdio.print_writer = io.writer_make(^stdio.print_stream); + + // This shouldn't need to be here, but because ^stdin_vtable is not a compile-time + // known value (even through it should be). + stdin.vtable = ^stdin_vtable; } @@ -121,3 +125,21 @@ __flush_stdio :: () { ^stdio.print_stream |> io.stream_flush(); } +#local stdin_vtable := io.Stream_Vtable.{ + read = (_: ^io.Stream, buffer: [] u8) -> (io.Error, u32) { + bytes_read := runtime.__read_from_input(buffer); + if bytes_read <= 0 do return .EOF, 0; + + return .None, bytes_read; + }, + + read_byte = (_: ^io.Stream) -> (io.Error, u8) { + buf: [1] u8; + bytes_read := runtime.__read_from_input(buf); + if bytes_read <= 0 do return .EOF, 0; + + return .None, buf[0]; + } +} + +stdin: io.Stream; \ No newline at end of file diff --git a/tests/aoc-2021/day01 b/tests/aoc-2021/day01 index 6ba24029..5021ac25 100644 --- a/tests/aoc-2021/day01 +++ b/tests/aoc-2021/day01 @@ -1 +1,2 @@ +Part 1: 1564 Part 2: 1611 diff --git a/tests/aoc-2021/day01.onyx b/tests/aoc-2021/day01.onyx index 9fe6f545..d1de70f9 100644 --- a/tests/aoc-2021/day01.onyx +++ b/tests/aoc-2021/day01.onyx @@ -1,5 +1,3 @@ -PART :: 2 - #load "core/std" use package core @@ -33,12 +31,12 @@ main :: (args) => { io.skip_whitespace(^reader); } - #if PART == 1 { + { // Part 1 increased_count := count_increasing(nums); printf("Part 1: {}\n", increased_count); } - #if PART == 2 { + { // Part 2 windows := array.make(i32); for i: range.{ 0, nums.count - 2 } { sum := 0; @@ -49,4 +47,4 @@ main :: (args) => { increased_count := count_increasing(windows); printf("Part 2: {}\n", increased_count); } -} \ No newline at end of file +}