aboutsummaryrefslogtreecommitdiff
path: root/code
diff options
context:
space:
mode:
Diffstat (limited to 'code')
-rw-r--r--code/demo.odin7
-rw-r--r--code/file.odin20
-rw-r--r--code/print.odin128
-rw-r--r--code/runtime.odin18
4 files changed, 120 insertions, 53 deletions
diff --git a/code/demo.odin b/code/demo.odin
index 6a1a9396a..64af72d26 100644
--- a/code/demo.odin
+++ b/code/demo.odin
@@ -1,9 +1,6 @@
#load "basic.odin"
main :: proc() {
- str := "Hellope"
-
- println(str, true, 6.28)
-
- println([4]int{1, 2, 3, 4})
+ println("% % % %", "Hellope", true, 6.28, [4]int{1, 2, 3, 4})
+ println("%0 %1 %0", "Hellope", 34)
}
diff --git a/code/file.odin b/code/file.odin
index 7ee8770e0..dc97e909e 100644
--- a/code/file.odin
+++ b/code/file.odin
@@ -41,18 +41,18 @@ File_Standard :: type enum {
COUNT,
}
-__std_file_set := false;
-__std_files: [File_Standard.COUNT as int]File;
-file_get_standard :: proc(std: File_Standard) -> ^File {
- // using File_Standard;
- if (!__std_file_set) {
- using File_Standard
- __std_files[INPUT] .handle = GetStdHandle(STD_INPUT_HANDLE)
- __std_files[OUTPUT].handle = GetStdHandle(STD_OUTPUT_HANDLE)
- __std_files[ERROR] .handle = GetStdHandle(STD_ERROR_HANDLE)
- __std_file_set = true
+__std_files := __set_file_standards();
+
+__set_file_standards :: proc() -> [File_Standard.COUNT as int]File {
+ return [File_Standard.COUNT as int]File{
+ File{handle = GetStdHandle(STD_INPUT_HANDLE)},
+ File{handle = GetStdHandle(STD_OUTPUT_HANDLE)},
+ File{handle = GetStdHandle(STD_ERROR_HANDLE)},
}
+}
+
+file_get_standard :: proc(std: File_Standard) -> ^File {
return ^__std_files[std]
}
diff --git a/code/print.odin b/code/print.odin
index 41121dbae..2a32f3c9e 100644
--- a/code/print.odin
+++ b/code/print.odin
@@ -2,7 +2,7 @@
#load "win32.odin"
#load "file.odin"
-print_string_to_buffer :: proc(buf: ^[]byte, s: string) {
+print_byte_buffer :: proc(buf: ^[]byte, b: []byte) {
// NOTE(bill): This is quite a hack
// TODO(bill): Should I allow the raw editing of a slice by exposing its
// internal members?
@@ -14,13 +14,20 @@ print_string_to_buffer :: proc(buf: ^[]byte, s: string) {
slice := buf as ^Raw_Bytes
if slice.len < slice.cap {
- n := min(slice.cap-slice.len, len(s))
- offset := ptr_offset(slice.data, slice.len)
- memory_copy(offset, ^s[0], n)
- slice.len += n
+ n := min(slice.cap-slice.len, len(b))
+ if n > 0 {
+ offset := ptr_offset(slice.data, slice.len)
+ memory_copy(offset, ^b[0], n)
+ slice.len += n
+ }
}
}
+print_string_to_buffer :: proc(buf: ^[]byte, s: string) {
+ print_byte_buffer(buf, s as []byte)
+}
+
+
byte_reverse :: proc(b: []byte) {
n := len(b)
for i := 0; i < n/2; i++ {
@@ -357,43 +364,100 @@ type_info_is_string :: proc(info: ^Type_Info) -> bool {
return false
}
-print_to_buffer :: proc(buf: ^[]byte, args: ..any) {
- prev_string := false
- for i := 0; i < len(args); i++ {
- arg := args[i]
- is_string := arg.data != null && type_info_is_string(arg.type_info)
- if i > 0 && !is_string && !prev_string {
- // Add space between two non-string arguments
- print_space_to_buffer(buf)
+
+print_to_buffer :: proc(buf: ^[]byte, fmt: string, args: ..any) {
+ is_digit :: proc(r: rune) -> bool #inline {
+ return r >= #rune "0" && r <= #rune "9"
+ }
+
+ parse_int :: proc(s: string, offset: int) -> (int, int) {
+ result := 0
+
+ for ; offset < len(s); offset++ {
+ c := s[offset] as rune
+ if !is_digit(c) {
+ break
+ }
+
+ result *= 10
+ result += (c - #rune "0") as int
}
- print_any_to_buffer(buf, arg)
- prev_string = is_string
+
+ return result, offset
}
-}
-println_to_buffer :: proc(buf: ^[]byte, args: ..any) {
- for i := 0; i < len(args); i++ {
- arg := args[i]
- if i > 0 {
- print_space_to_buffer(buf)
+ prev := 0
+ implicit_index := 0
+
+ for i := 0; i < len(fmt); i++ {
+ r := fmt[i] as rune
+
+ if r != #rune "%" {
+ continue
+ }
+
+ print_string_to_buffer(buf, fmt[prev:i])
+ i++ // Skip %
+ if i >= len(fmt) {
+ return
}
- print_any_to_buffer(buf, arg)
+
+ next := fmt[i] as rune
+ if next == #rune "%" {
+ print_string_to_buffer(buf, "%")
+ i++
+ prev = i
+ continue
+ }
+
+ index := implicit_index
+ set_prev := true
+
+ if is_digit(next) {
+ index, i = parse_int(fmt, i)
+ }
+
+ if 0 <= index && index < len(args) {
+ print_any_to_buffer(buf, args[index])
+ implicit_index = index+1
+ } else {
+ // TODO(bill): Error check index out bounds
+ print_string_to_buffer(buf, "<invalid>")
+ }
+
+ prev = i
}
- print_nl_to_buffer(buf)
+
+ print_string_to_buffer(buf, fmt[prev:])
}
+PRINT_BUF_SIZE :: 1<<12
-print :: proc(args: ..any) {
- data: [4096]byte
+print_to_file :: proc(f: ^File, fmt: string, args: ..any) {
+ data: [PRINT_BUF_SIZE]byte
buf := data[:0]
- print_to_buffer(^buf, ..args)
- file_write(file_get_standard(File_Standard.OUTPUT), buf)
+ print_to_buffer(^buf, fmt, ..args)
+ file_write(f, buf)
}
-
-println :: proc(args: ..any) {
- data: [4096]byte
+println_to_file :: proc(f: ^File, fmt: string, args: ..any) {
+ data: [PRINT_BUF_SIZE]byte
buf := data[:0]
- println_to_buffer(^buf, ..args)
- file_write(file_get_standard(File_Standard.OUTPUT), buf)
+ print_to_buffer(^buf, fmt, ..args)
+ print_nl_to_buffer(^buf)
+ file_write(f, buf)
+}
+
+
+print :: proc(fmt: string, args: ..any) {
+ print_to_file(file_get_standard(File_Standard.OUTPUT), fmt, ..args)
+}
+print_err :: proc(fmt: string, args: ..any) {
+ print_to_file(file_get_standard(File_Standard.ERROR), fmt, ..args)
+}
+println :: proc(fmt: string, args: ..any) {
+ println_to_file(file_get_standard(File_Standard.OUTPUT), fmt, ..args)
+}
+println_err :: proc(fmt: string, args: ..any) {
+ println_to_file(file_get_standard(File_Standard.ERROR), fmt, ..args)
}
diff --git a/code/runtime.odin b/code/runtime.odin
index aedcdc9ba..5f42c39c5 100644
--- a/code/runtime.odin
+++ b/code/runtime.odin
@@ -290,17 +290,23 @@ __assert :: proc(msg: string) {
__debug_trap()
}
-__abc_error :: proc(file: string, line, column: int, index, len: int) {
- print(file, "(", line, ":", line, ") Index `", index, "` is of bounds range [0, ", len, ")\n")
+__bounds_check_error :: proc(file: string, line, column: int,
+ index, count: int) {
+ println_err("%(%:%) Index % is out of bounds range [0, %)",
+ file, line, column, index, count)
__debug_trap()
}
-__slice_expr_error :: proc(file: string, line, column: int, low, high, max: int) {
- print(file, "(", line, ":", line, ") Invalid slice indices: [", low, ":", high, ":", max, "]\n")
+__slice_expr_error :: proc(file: string, line, column: int,
+ low, high, max: int) {
+ print_err("%(%:%) Invalid slice indices: [%:%:%]\n",
+ file, line, column, low, high, max)
__debug_trap()
}
-__substring_expr_error :: proc(file: string, line, column: int, low, high: int) {
- print(file, "(", line, ":", line, ") Invalid substring indices: [", low, ":", high, "]\n")
+__substring_expr_error :: proc(file: string, line, column: int,
+ low, high: int) {
+ print_err("%(%:%) Invalid substring indices: [%:%:%]\n",
+ file, line, column, low, high)
__debug_trap()
}