mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Merge branch 'master' of https://github.com/matias-eduardo/Odin
This commit is contained in:
+12
-12
@@ -104,13 +104,13 @@ jobs:
|
|||||||
run: ./odin check examples/all -vet -strict-style -target:linux_arm64
|
run: ./odin check examples/all -vet -strict-style -target:linux_arm64
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
build_windows:
|
build_windows:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2022
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: build Odin
|
- name: build Odin
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
./build.bat 1
|
./build.bat 1
|
||||||
- name: Odin version
|
- name: Odin version
|
||||||
run: ./odin version
|
run: ./odin version
|
||||||
@@ -121,65 +121,65 @@ jobs:
|
|||||||
- name: Odin check
|
- name: Odin check
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
odin check examples/demo -vet
|
odin check examples/demo -vet
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Odin run
|
- name: Odin run
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
odin run examples/demo
|
odin run examples/demo
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Odin run -debug
|
- name: Odin run -debug
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
odin run examples/demo -debug
|
odin run examples/demo -debug
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Odin check examples/all
|
- name: Odin check examples/all
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
odin check examples/all -strict-style
|
odin check examples/all -strict-style
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Core library tests
|
- name: Core library tests
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
cd tests\core
|
cd tests\core
|
||||||
call build.bat
|
call build.bat
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Vendor library tests
|
- name: Vendor library tests
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
cd tests\vendor
|
cd tests\vendor
|
||||||
call build.bat
|
call build.bat
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Odin internals tests
|
- name: Odin internals tests
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
cd tests\internal
|
cd tests\internal
|
||||||
call build.bat
|
call build.bat
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Odin documentation tests
|
- name: Odin documentation tests
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
cd tests\documentation
|
cd tests\documentation
|
||||||
call build.bat
|
call build.bat
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: core:math/big tests
|
- name: core:math/big tests
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
cd tests\core\math\big
|
cd tests\core\math\big
|
||||||
call build.bat
|
call build.bat
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
- name: Odin check examples/all for Windows 32bits
|
- name: Odin check examples/all for Windows 32bits
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
odin check examples/all -strict-style -target:windows_i386
|
odin check examples/all -strict-style -target:windows_i386
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_windows:
|
build_windows:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2022
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: build Odin
|
- name: build Odin
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
./build.bat 1 1
|
./build.bat 1 1
|
||||||
- name: Odin run
|
- name: Odin run
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||||
odin run examples/demo
|
odin run examples/demo
|
||||||
- name: Copy artifacts
|
- name: Copy artifacts
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<img src="https://img.shields.io/badge/platforms-Windows%20|%20Linux%20|%20macOS-green.svg">
|
<img src="https://img.shields.io/badge/platforms-Windows%20|%20Linux%20|%20macOS-green.svg">
|
||||||
</a>
|
</a>
|
||||||
<br>
|
<br>
|
||||||
<a href="https://discord.gg/odinlang">
|
<a href="https://discord.com/invite/sVBPHEv">
|
||||||
<img src="https://img.shields.io/discord/568138951836172421?logo=discord">
|
<img src="https://img.shields.io/discord/568138951836172421?logo=discord">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/odin-lang/odin/actions">
|
<a href="https://github.com/odin-lang/odin/actions">
|
||||||
|
|||||||
+1
-1
@@ -157,7 +157,7 @@ run_demo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
have_which() {
|
have_which() {
|
||||||
if ! [ -x "$(command -v which)" ]; then
|
if ! command -v which > /dev/null 2>&1 ; then
|
||||||
panic "Could not find \`which\`"
|
panic "Could not find \`which\`"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,25 @@ package bufio
|
|||||||
|
|
||||||
import "core:io"
|
import "core:io"
|
||||||
|
|
||||||
// Loadahead_Reader provides io lookahead.
|
// Lookahead_Reader provides io lookahead.
|
||||||
// This is useful for tokenizers/parsers.
|
// This is useful for tokenizers/parsers.
|
||||||
// Loadahead_Reader is similar to bufio.Reader, but unlike bufio.Reader, Loadahead_Reader's buffer size
|
// Lookahead_Reader is similar to bufio.Reader, but unlike bufio.Reader, Lookahead_Reader's buffer size
|
||||||
// will EXACTLY match the specified size, whereas bufio.Reader's buffer size may differ from the specified size.
|
// will EXACTLY match the specified size, whereas bufio.Reader's buffer size may differ from the specified size.
|
||||||
// This makes sure that the buffer will not be accidentally read beyond the expected size.
|
// This makes sure that the buffer will not be accidentally read beyond the expected size.
|
||||||
Loadahead_Reader :: struct {
|
Lookahead_Reader :: struct {
|
||||||
r: io.Reader,
|
r: io.Reader,
|
||||||
buf: []byte,
|
buf: []byte,
|
||||||
n: int,
|
n: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
lookahead_reader_init :: proc(lr: ^Loadahead_Reader, r: io.Reader, buf: []byte) -> ^Loadahead_Reader {
|
lookahead_reader_init :: proc(lr: ^Lookahead_Reader, r: io.Reader, buf: []byte) -> ^Lookahead_Reader {
|
||||||
lr.r = r
|
lr.r = r
|
||||||
lr.buf = buf
|
lr.buf = buf
|
||||||
lr.n = 0
|
lr.n = 0
|
||||||
return lr
|
return lr
|
||||||
}
|
}
|
||||||
|
|
||||||
lookahead_reader_buffer :: proc(lr: ^Loadahead_Reader) -> []byte {
|
lookahead_reader_buffer :: proc(lr: ^Lookahead_Reader) -> []byte {
|
||||||
return lr.buf[:lr.n]
|
return lr.buf[:lr.n]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ lookahead_reader_buffer :: proc(lr: ^Loadahead_Reader) -> []byte {
|
|||||||
// lookahead_reader_peek returns a slice of the Lookahead_Reader which holds n bytes
|
// lookahead_reader_peek returns a slice of the Lookahead_Reader which holds n bytes
|
||||||
// If the Lookahead_Reader cannot hold enough bytes, it will read from the underlying reader to populate the rest.
|
// If the Lookahead_Reader cannot hold enough bytes, it will read from the underlying reader to populate the rest.
|
||||||
// NOTE: The returned buffer is not a copy of the underlying buffer
|
// NOTE: The returned buffer is not a copy of the underlying buffer
|
||||||
lookahead_reader_peek :: proc(lr: ^Loadahead_Reader, n: int) -> ([]byte, io.Error) {
|
lookahead_reader_peek :: proc(lr: ^Lookahead_Reader, n: int) -> ([]byte, io.Error) {
|
||||||
switch {
|
switch {
|
||||||
case n < 0:
|
case n < 0:
|
||||||
return nil, .Negative_Read
|
return nil, .Negative_Read
|
||||||
@@ -58,13 +58,13 @@ lookahead_reader_peek :: proc(lr: ^Loadahead_Reader, n: int) -> ([]byte, io.Erro
|
|||||||
// lookahead_reader_peek_all returns a slice of the Lookahead_Reader populating the full buffer
|
// lookahead_reader_peek_all returns a slice of the Lookahead_Reader populating the full buffer
|
||||||
// If the Lookahead_Reader cannot hold enough bytes, it will read from the underlying reader to populate the rest.
|
// If the Lookahead_Reader cannot hold enough bytes, it will read from the underlying reader to populate the rest.
|
||||||
// NOTE: The returned buffer is not a copy of the underlying buffer
|
// NOTE: The returned buffer is not a copy of the underlying buffer
|
||||||
lookahead_reader_peek_all :: proc(lr: ^Loadahead_Reader) -> ([]byte, io.Error) {
|
lookahead_reader_peek_all :: proc(lr: ^Lookahead_Reader) -> ([]byte, io.Error) {
|
||||||
return lookahead_reader_peek(lr, len(lr.buf))
|
return lookahead_reader_peek(lr, len(lr.buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// lookahead_reader_consume drops the first n populated bytes from the Lookahead_Reader.
|
// lookahead_reader_consume drops the first n populated bytes from the Lookahead_Reader.
|
||||||
lookahead_reader_consume :: proc(lr: ^Loadahead_Reader, n: int) -> io.Error {
|
lookahead_reader_consume :: proc(lr: ^Lookahead_Reader, n: int) -> io.Error {
|
||||||
switch {
|
switch {
|
||||||
case n == 0:
|
case n == 0:
|
||||||
return nil
|
return nil
|
||||||
@@ -78,6 +78,6 @@ lookahead_reader_consume :: proc(lr: ^Loadahead_Reader, n: int) -> io.Error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
lookahead_reader_consume_all :: proc(lr: ^Loadahead_Reader) -> io.Error {
|
lookahead_reader_consume_all :: proc(lr: ^Lookahead_Reader) -> io.Error {
|
||||||
return lookahead_reader_consume(lr, lr.n)
|
return lookahead_reader_consume(lr, lr.n)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,6 +227,14 @@ writer_to_stream :: proc(b: ^Writer) -> (s: io.Stream) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writer_to_stream converts a Writer into an io.Stream
|
||||||
|
writer_to_writer :: proc(b: ^Writer) -> (s: io.Writer) {
|
||||||
|
s.stream_data = b
|
||||||
|
s.stream_vtable = &_writer_vtable
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
|
|||||||
@@ -27,27 +27,28 @@ Bit_Array_Iterator :: struct {
|
|||||||
word_idx: int,
|
word_idx: int,
|
||||||
bit_idx: uint,
|
bit_idx: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In:
|
Wraps a `Bit_Array` into an Iterator
|
||||||
- ba: ^Bit_Array - the array to iterate over
|
|
||||||
|
|
||||||
Out:
|
Inputs:
|
||||||
- it: ^Bit_Array_Iterator - the iterator that holds iteration state
|
- ba: Pointer to the Bit_Array
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- it: Iterator struct
|
||||||
*/
|
*/
|
||||||
make_iterator :: proc (ba: ^Bit_Array) -> (it: Bit_Array_Iterator) {
|
make_iterator :: proc (ba: ^Bit_Array) -> (it: Bit_Array_Iterator) {
|
||||||
return Bit_Array_Iterator { array = ba }
|
return Bit_Array_Iterator { array = ba }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In:
|
Returns the next bit, including its set-state. ok=false once exhausted
|
||||||
- it: ^Bit_Array_Iterator - the iterator struct that holds the state.
|
|
||||||
|
|
||||||
Out:
|
Inputs:
|
||||||
- set: bool - the state of the bit at `index`
|
- it: The iterator that holds the state.
|
||||||
- index: int - the next bit of the Bit_Array referenced by `it`.
|
|
||||||
- ok: bool - `true` if the iterator returned a valid index,
|
Returns:
|
||||||
`false` if there were no more bits
|
- set: `true` if the bit at `index` is set.
|
||||||
|
- index: The next bit of the Bit_Array referenced by `it`.
|
||||||
|
- ok: `true` if the iterator can continue, `false` if the iterator is done
|
||||||
*/
|
*/
|
||||||
iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok: bool) {
|
iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok: bool) {
|
||||||
index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias
|
index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias
|
||||||
@@ -64,39 +65,51 @@ iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok:
|
|||||||
|
|
||||||
return set, index, true
|
return set, index, true
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In:
|
Returns the next Set Bit, for example if `0b1010`, then the iterator will return index={1, 3} over two calls.
|
||||||
- it: ^Bit_Array_Iterator - the iterator struct that holds the state.
|
|
||||||
|
|
||||||
Out:
|
Inputs:
|
||||||
- index: int - the next set bit of the Bit_Array referenced by `it`.
|
- it: The iterator that holds the state.
|
||||||
- ok: bool - `true` if the iterator returned a valid index,
|
|
||||||
`false` if there were no more bits set
|
Returns:
|
||||||
|
- index: The next *set* bit of the Bit_Array referenced by `it`.
|
||||||
|
- ok: `true` if the iterator can continue, `false` if the iterator is done
|
||||||
*/
|
*/
|
||||||
iterate_by_set :: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) {
|
iterate_by_set :: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) {
|
||||||
return iterate_internal_(it, true)
|
return iterate_internal_(it, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In:
|
Returns the next Unset Bit, for example if `0b1010`, then the iterator will return index={0, 2} over two calls.
|
||||||
- it: ^Bit_Array_Iterator - the iterator struct that holds the state.
|
|
||||||
|
|
||||||
Out:
|
Inputs:
|
||||||
- index: int - the next unset bit of the Bit_Array referenced by `it`.
|
- it: The iterator that holds the state.
|
||||||
- ok: bool - `true` if the iterator returned a valid index,
|
|
||||||
`false` if there were no more unset bits
|
Returns:
|
||||||
|
- index: The next *unset* bit of the Bit_Array referenced by `it`.
|
||||||
|
- ok: `true` if the iterator can continue, `false` if the iterator is done
|
||||||
*/
|
*/
|
||||||
iterate_by_unset:: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) {
|
iterate_by_unset:: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) {
|
||||||
return iterate_internal_(it, false)
|
return iterate_internal_(it, false)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Iterates through set/unset bits
|
||||||
|
|
||||||
|
*Private*
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- it: The iterator that holds the state.
|
||||||
|
- ITERATE_SET_BITS: `true` for returning only set bits, false for returning only unset bits
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- index: The next *unset* bit of the Bit_Array referenced by `it`.
|
||||||
|
- ok: `true` if the iterator can continue, `false` if the iterator is done
|
||||||
|
*/
|
||||||
@(private="file")
|
@(private="file")
|
||||||
iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) -> (index: int, ok: bool) {
|
iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) -> (index: int, ok: bool) {
|
||||||
word := it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0
|
word := it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0
|
||||||
when ! ITERATE_SET_BITS { word = ~word }
|
when ! ITERATE_SET_BITS { word = ~word }
|
||||||
|
|
||||||
// if the word is empty or we have already gone over all the bits in it,
|
// If the word is empty or we have already gone over all the bits in it,
|
||||||
// b.bit_idx is greater than the index of any set bit in the word,
|
// b.bit_idx is greater than the index of any set bit in the word,
|
||||||
// meaning that word >> b.bit_idx == 0.
|
// meaning that word >> b.bit_idx == 0.
|
||||||
for it.word_idx < len(it.array.bits) && word >> it.bit_idx == 0 {
|
for it.word_idx < len(it.array.bits) && word >> it.bit_idx == 0 {
|
||||||
@@ -106,14 +119,14 @@ iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) ->
|
|||||||
when ! ITERATE_SET_BITS { word = ~word }
|
when ! ITERATE_SET_BITS { word = ~word }
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we are iterating the set bits, reaching the end of the array means we have no more bits to check
|
// If we are iterating the set bits, reaching the end of the array means we have no more bits to check
|
||||||
when ITERATE_SET_BITS {
|
when ITERATE_SET_BITS {
|
||||||
if it.word_idx >= len(it.array.bits) {
|
if it.word_idx >= len(it.array.bits) {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reaching here means that the word has some set bits
|
// Reaching here means that the word has some set bits
|
||||||
it.bit_idx += uint(intrinsics.count_trailing_zeros(word >> it.bit_idx))
|
it.bit_idx += uint(intrinsics.count_trailing_zeros(word >> it.bit_idx))
|
||||||
index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias
|
index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias
|
||||||
|
|
||||||
@@ -124,24 +137,21 @@ iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) ->
|
|||||||
}
|
}
|
||||||
return index, index <= it.array.max_index
|
return index, index <= it.array.max_index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In:
|
Gets the state of a bit in the bit-array
|
||||||
- ba: ^Bit_Array - a pointer to the Bit Array
|
|
||||||
- index: The bit index. Can be an enum member.
|
|
||||||
|
|
||||||
Out:
|
Inputs:
|
||||||
- res: The bit you're interested in.
|
- ba: Pointer to the Bit_Array
|
||||||
- ok: Whether the index was valid. Returns `false` if the index is smaller than the bias.
|
- index: Which bit in the array
|
||||||
|
|
||||||
The `ok` return value may be ignored.
|
Returns:
|
||||||
|
- res: `true` if the bit at `index` is set.
|
||||||
|
- ok: Whether the index was valid. Returns `false` if the index is smaller than the bias.
|
||||||
*/
|
*/
|
||||||
get :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (res: bool, ok: bool) {
|
get :: proc(ba: ^Bit_Array, #any_int index: uint) -> (res: bool, ok: bool) #optional_ok {
|
||||||
idx := int(index) - ba.bias
|
idx := int(index) - ba.bias
|
||||||
|
|
||||||
if ba == nil || int(index) < ba.bias { return false, false }
|
if ba == nil || int(index) < ba.bias { return false, false }
|
||||||
context.allocator = allocator
|
|
||||||
|
|
||||||
leg_index := idx >> INDEX_SHIFT
|
leg_index := idx >> INDEX_SHIFT
|
||||||
bit_index := idx & INDEX_MASK
|
bit_index := idx & INDEX_MASK
|
||||||
@@ -157,18 +167,36 @@ get :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator
|
|||||||
|
|
||||||
return res, true
|
return res, true
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In:
|
Gets the state of a bit in the bit-array
|
||||||
- ba: ^Bit_Array - a pointer to the Bit Array
|
|
||||||
- index: The bit index. Can be an enum member.
|
|
||||||
|
|
||||||
Out:
|
*Bypasses all Checks*
|
||||||
- ok: Whether or not we managed to set requested bit.
|
|
||||||
|
|
||||||
`set` automatically resizes the Bit Array to accommodate the requested index if needed.
|
Inputs:
|
||||||
|
- ba: Pointer to the Bit_Array
|
||||||
|
- index: Which bit in the array
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- `true` if bit is set
|
||||||
*/
|
*/
|
||||||
set :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (ok: bool) {
|
unsafe_get :: #force_inline proc(ba: ^Bit_Array, #any_int index: uint) -> bool #no_bounds_check {
|
||||||
|
return bool((ba.bits[index >> INDEX_SHIFT] >> uint(index & INDEX_MASK)) & 1)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Sets the state of a bit in the bit-array
|
||||||
|
|
||||||
|
*Conditionally Allocates (Resizes backing data when `index > len(ba.bits)`)*
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- ba: Pointer to the Bit_Array
|
||||||
|
- index: Which bit in the array
|
||||||
|
- set_to: `true` sets the bit on, `false` to turn it off
|
||||||
|
- allocator: (default is context.allocator)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- ok: Whether the set was successful, `false` on allocation failure or bad index
|
||||||
|
*/
|
||||||
|
set :: proc(ba: ^Bit_Array, #any_int index: uint, set_to: bool = true, allocator := context.allocator) -> (ok: bool) {
|
||||||
|
|
||||||
idx := int(index) - ba.bias
|
idx := int(index) - ba.bias
|
||||||
|
|
||||||
@@ -181,65 +209,97 @@ set :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator
|
|||||||
resize_if_needed(ba, leg_index) or_return
|
resize_if_needed(ba, leg_index) or_return
|
||||||
|
|
||||||
ba.max_index = max(idx, ba.max_index)
|
ba.max_index = max(idx, ba.max_index)
|
||||||
ba.bits[leg_index] |= 1 << uint(bit_index)
|
|
||||||
|
if set_to{ ba.bits[leg_index] |= 1 << uint(bit_index) }
|
||||||
|
else { ba.bits[leg_index] &= ~(1 << uint(bit_index)) }
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In:
|
Sets the state of a bit in the bit-array
|
||||||
- ba: ^Bit_Array - a pointer to the Bit Array
|
|
||||||
- index: The bit index. Can be an enum member.
|
|
||||||
|
|
||||||
Out:
|
*Bypasses all checks*
|
||||||
- ok: Whether or not we managed to unset requested bit.
|
|
||||||
|
|
||||||
`unset` automatically resizes the Bit Array to accommodate the requested index if needed.
|
Inputs:
|
||||||
|
- ba: Pointer to the Bit_Array
|
||||||
|
- index: Which bit in the array
|
||||||
*/
|
*/
|
||||||
unset :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (ok: bool) {
|
unsafe_set :: proc(ba: ^Bit_Array, bit: int) #no_bounds_check {
|
||||||
|
ba.bits[bit >> INDEX_SHIFT] |= 1 << uint(bit & INDEX_MASK)
|
||||||
idx := int(index) - ba.bias
|
|
||||||
|
|
||||||
if ba == nil || int(index) < ba.bias { return false }
|
|
||||||
context.allocator = allocator
|
|
||||||
|
|
||||||
leg_index := idx >> INDEX_SHIFT
|
|
||||||
bit_index := idx & INDEX_MASK
|
|
||||||
|
|
||||||
resize_if_needed(ba, leg_index) or_return
|
|
||||||
|
|
||||||
ba.max_index = max(idx, ba.max_index)
|
|
||||||
ba.bits[leg_index] &= ~(1 << uint(bit_index))
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
|
Unsets the state of a bit in the bit-array. (Convienence wrapper for `set`)
|
||||||
|
|
||||||
|
*Conditionally Allocates (Resizes backing data when `index > len(ba.bits)`)*
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- ba: Pointer to the Bit_Array
|
||||||
|
- index: Which bit in the array
|
||||||
|
- allocator: (default is context.allocator)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- ok: Whether the unset was successful, `false` on allocation failure or bad index
|
||||||
*/
|
*/
|
||||||
create :: proc(max_index: int, min_index := 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok {
|
unset :: #force_inline proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (ok: bool) {
|
||||||
|
return set(ba, index, false, allocator)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Unsets the state of a bit in the bit-array
|
||||||
|
|
||||||
|
*Bypasses all Checks*
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- ba: Pointer to the Bit_Array
|
||||||
|
- index: Which bit in the array
|
||||||
|
*/
|
||||||
|
unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check {
|
||||||
|
b.bits[bit >> INDEX_SHIFT] &= ~(1 << uint(bit & INDEX_MASK))
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
|
||||||
|
|
||||||
|
*Allocates (`new(Bit_Array) & make(ba.bits)`)*
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- max_index: maximum starting index
|
||||||
|
- min_index: minimum starting index (used as a bias)
|
||||||
|
- allocator: (default is context.allocator)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- ba: Allocates a bit_Array, backing data is set to `max-min / 64` indices, rounded up (eg 65 - 0 allocates for [2]u64).
|
||||||
|
*/
|
||||||
|
create :: proc(max_index: int, min_index: int = 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok {
|
||||||
context.allocator = allocator
|
context.allocator = allocator
|
||||||
size_in_bits := max_index - min_index
|
size_in_bits := max_index - min_index
|
||||||
|
|
||||||
if size_in_bits < 1 { return {}, false }
|
if size_in_bits < 1 { return {}, false }
|
||||||
|
|
||||||
legs := size_in_bits >> INDEX_SHIFT
|
legs := size_in_bits >> INDEX_SHIFT
|
||||||
|
if size_in_bits & INDEX_MASK > 0 {legs+=1}
|
||||||
|
bits, err := make([dynamic]u64, legs)
|
||||||
|
ok = err == mem.Allocator_Error.None
|
||||||
res = new(Bit_Array)
|
res = new(Bit_Array)
|
||||||
|
res.bits = bits
|
||||||
res.bias = min_index
|
res.bias = min_index
|
||||||
res.max_index = max_index
|
res.max_index = max_index
|
||||||
res.free_pointer = true
|
res.free_pointer = true
|
||||||
return res, resize_if_needed(res, legs)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Sets all bits to `false`.
|
Sets all values in the Bit_Array to zero.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- ba: The target Bit_Array
|
||||||
*/
|
*/
|
||||||
clear :: proc(ba: ^Bit_Array) {
|
clear :: proc(ba: ^Bit_Array) {
|
||||||
if ba == nil { return }
|
if ba == nil { return }
|
||||||
mem.zero_slice(ba.bits[:])
|
mem.zero_slice(ba.bits[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Releases the memory used by the Bit Array.
|
Deallocates the Bit_Array and its backing storage
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- ba: The target Bit_Array
|
||||||
*/
|
*/
|
||||||
destroy :: proc(ba: ^Bit_Array) {
|
destroy :: proc(ba: ^Bit_Array) {
|
||||||
if ba == nil { return }
|
if ba == nil { return }
|
||||||
@@ -248,9 +308,8 @@ destroy :: proc(ba: ^Bit_Array) {
|
|||||||
free(ba)
|
free(ba)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Resizes the Bit Array. For internal use.
|
Resizes the Bit Array. For internal use. Provisions needed capacity+1
|
||||||
If you want to reserve the memory for a given-sized Bit Array up front, you can use `create`.
|
If you want to reserve the memory for a given-sized Bit Array up front, you can use `create`.
|
||||||
*/
|
*/
|
||||||
@(private="file")
|
@(private="file")
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ opt_write_start :: proc(w: io.Writer, opt: ^Marshal_Options, c: byte) -> (err: i
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert comma seperation and write indentations
|
// insert comma separation and write indentations
|
||||||
opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) -> (err: io.Error) {
|
opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) -> (err: io.Error) {
|
||||||
switch opt.spec {
|
switch opt.spec {
|
||||||
case .JSON, .JSON5:
|
case .JSON, .JSON5:
|
||||||
@@ -461,7 +461,7 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int)
|
|||||||
if opt.pretty {
|
if opt.pretty {
|
||||||
io.write_byte(w, '\n') or_return
|
io.write_byte(w, '\n') or_return
|
||||||
} else {
|
} else {
|
||||||
// comma seperation necessary for non pretty output!
|
// comma separation necessary for non pretty output!
|
||||||
io.write_string(w, ", ") or_return
|
io.write_string(w, ", ") or_return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-5
@@ -4,29 +4,59 @@ package fmt
|
|||||||
import "core:runtime"
|
import "core:runtime"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
import "core:io"
|
import "core:io"
|
||||||
|
import "core:bufio"
|
||||||
|
|
||||||
// fprint formats using the default print settings and writes to fd
|
// fprint formats using the default print settings and writes to fd
|
||||||
fprint :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
|
fprint :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
|
||||||
w := io.to_writer(os.stream_from_handle(fd))
|
buf: [1024]byte
|
||||||
|
b: bufio.Writer
|
||||||
|
defer bufio.writer_flush(&b)
|
||||||
|
|
||||||
|
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||||
|
w := bufio.writer_to_writer(&b)
|
||||||
return wprint(w=w, args=args, sep=sep)
|
return wprint(w=w, args=args, sep=sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fprintln formats using the default print settings and writes to fd
|
// fprintln formats using the default print settings and writes to fd
|
||||||
fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
|
fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
|
||||||
w := io.to_writer(os.stream_from_handle(fd))
|
buf: [1024]byte
|
||||||
|
b: bufio.Writer
|
||||||
|
defer bufio.writer_flush(&b)
|
||||||
|
|
||||||
|
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||||
|
|
||||||
|
w := bufio.writer_to_writer(&b)
|
||||||
return wprintln(w=w, args=args, sep=sep)
|
return wprintln(w=w, args=args, sep=sep)
|
||||||
}
|
}
|
||||||
// fprintf formats according to the specified format string and writes to fd
|
// fprintf formats according to the specified format string and writes to fd
|
||||||
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
||||||
w := io.to_writer(os.stream_from_handle(fd))
|
buf: [1024]byte
|
||||||
|
b: bufio.Writer
|
||||||
|
defer bufio.writer_flush(&b)
|
||||||
|
|
||||||
|
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||||
|
|
||||||
|
w := bufio.writer_to_writer(&b)
|
||||||
return wprintf(w, fmt, ..args)
|
return wprintf(w, fmt, ..args)
|
||||||
}
|
}
|
||||||
fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) -> (n: int, err: io.Error) {
|
fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) -> (n: int, err: io.Error) {
|
||||||
w := io.to_writer(os.stream_from_handle(fd))
|
buf: [1024]byte
|
||||||
|
b: bufio.Writer
|
||||||
|
defer bufio.writer_flush(&b)
|
||||||
|
|
||||||
|
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||||
|
|
||||||
|
w := bufio.writer_to_writer(&b)
|
||||||
return wprint_type(w, info)
|
return wprint_type(w, info)
|
||||||
}
|
}
|
||||||
fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
|
fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
|
||||||
w := io.to_writer(os.stream_from_handle(fd))
|
buf: [1024]byte
|
||||||
|
b: bufio.Writer
|
||||||
|
defer bufio.writer_flush(&b)
|
||||||
|
|
||||||
|
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||||
|
|
||||||
|
w := bufio.writer_to_writer(&b)
|
||||||
return wprint_typeid(w, id)
|
return wprint_typeid(w, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -353,14 +353,14 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
|
|||||||
|
|
||||||
// Run the Miller-Rabin test with base 2 for the BPSW test.
|
// Run the Miller-Rabin test with base 2 for the BPSW test.
|
||||||
internal_set(b, 2) or_return
|
internal_set(b, 2) or_return
|
||||||
if !internal_int_prime_miller_rabin(a, b) or_return { return }
|
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
|
||||||
|
|
||||||
// Rumours have it that Mathematica does a second M-R test with base 3.
|
// Rumours have it that Mathematica does a second M-R test with base 3.
|
||||||
// Other rumours have it that their strong L-S test is slightly different.
|
// Other rumours have it that their strong L-S test is slightly different.
|
||||||
// It does not hurt, though, beside a bit of extra runtime.
|
// It does not hurt, though, beside a bit of extra runtime.
|
||||||
|
|
||||||
b.digit[0] += 1
|
b.digit[0] += 1
|
||||||
if !internal_int_prime_miller_rabin(a, b) or_return { return }
|
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
|
||||||
|
|
||||||
// Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite
|
// Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite
|
||||||
// slow so if speed is an issue, set `USE_MILLER_RABIN_ONLY` to use M-R tests with
|
// slow so if speed is an issue, set `USE_MILLER_RABIN_ONLY` to use M-R tests with
|
||||||
@@ -369,9 +369,9 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
|
|||||||
if !miller_rabin_only {
|
if !miller_rabin_only {
|
||||||
if miller_rabin_trials >= 0 {
|
if miller_rabin_trials >= 0 {
|
||||||
when MATH_BIG_USE_FROBENIUS_TEST {
|
when MATH_BIG_USE_FROBENIUS_TEST {
|
||||||
if !internal_int_prime_frobenius_underwood(a) or_return { return }
|
if !(internal_int_prime_frobenius_underwood(a) or_return) { return }
|
||||||
} else {
|
} else {
|
||||||
if !internal_int_prime_strong_lucas_selfridge(a) or_return { return }
|
if !(internal_int_prime_strong_lucas_selfridge(a) or_return) { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,7 +410,7 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
|
|||||||
// We did bases 2 and 3 already, skip them
|
// We did bases 2 and 3 already, skip them
|
||||||
for ix := 2; ix < p_max; ix += 1 {
|
for ix := 2; ix < p_max; ix += 1 {
|
||||||
internal_set(b, _private_prime_table[ix])
|
internal_set(b, _private_prime_table[ix])
|
||||||
if !internal_int_prime_miller_rabin(a, b) or_return { return }
|
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
|
||||||
}
|
}
|
||||||
} else if miller_rabin_trials > 0 {
|
} else if miller_rabin_trials > 0 {
|
||||||
// Perform `miller_rabin_trials` M-R tests with random bases between 3 and "a".
|
// Perform `miller_rabin_trials` M-R tests with random bases between 3 and "a".
|
||||||
@@ -490,7 +490,7 @@ internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials := int(-1), miller_ra
|
|||||||
ix -= 1
|
ix -= 1
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !internal_int_prime_miller_rabin(a, b) or_return { return }
|
if !(internal_int_prime_miller_rabin(a, b) or_return) { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,20 +3,21 @@ package linalg
|
|||||||
import "core:builtin"
|
import "core:builtin"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
|
|
||||||
radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
to_radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||||
when IS_ARRAY(T) {
|
when IS_ARRAY(T) {
|
||||||
for i in 0..<len(T) {
|
for i in 0..<len(T) {
|
||||||
out[i] = degrees * RAD_PER_DEG
|
out[i] = degrees[i] * RAD_PER_DEG
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out = degrees * RAD_PER_DEG
|
out = degrees * RAD_PER_DEG
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
|
||||||
|
to_degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||||
when IS_ARRAY(T) {
|
when IS_ARRAY(T) {
|
||||||
for i in 0..<len(T) {
|
for i in 0..<len(T) {
|
||||||
out[i] = radians * DEG_PER_RAD
|
out[i] = radians[i] * DEG_PER_RAD
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out = radians * DEG_PER_RAD
|
out = radians * DEG_PER_RAD
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) -
|
|||||||
case .None: // Ignore
|
case .None: // Ignore
|
||||||
case .Fixed:
|
case .Fixed:
|
||||||
io.write_string(w, "#soa[", &n) or_return
|
io.write_string(w, "#soa[", &n) or_return
|
||||||
io.write_i64(w, i64(info.soa_len), 10 &n) or_return
|
io.write_i64(w, i64(info.soa_len), 10) or_return
|
||||||
io.write_byte(w, ']', &n) or_return
|
io.write_byte(w, ']', &n) or_return
|
||||||
write_type(w, info.soa_base_type, &n) or_return
|
write_type(w, info.soa_base_type, &n) or_return
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -71,7 +71,32 @@ Returns:
|
|||||||
builder_make_len_cap :: proc(len, cap: int, allocator := context.allocator) -> (res: Builder, err: mem.Allocator_Error) #optional_allocator_error {
|
builder_make_len_cap :: proc(len, cap: int, allocator := context.allocator) -> (res: Builder, err: mem.Allocator_Error) #optional_allocator_error {
|
||||||
return Builder{buf=make([dynamic]byte, len, cap, allocator) or_return }, nil
|
return Builder{buf=make([dynamic]byte, len, cap, allocator) or_return }, nil
|
||||||
}
|
}
|
||||||
// overload simple `builder_make_*` with or without len / cap parameters
|
/*
|
||||||
|
Produces a String Builder
|
||||||
|
|
||||||
|
*Allocates Using Provided Allocator*
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strings"
|
||||||
|
builder_make_example :: proc() {
|
||||||
|
sb := strings.builder_make()
|
||||||
|
strings.write_byte(&sb, 'a')
|
||||||
|
strings.write_string(&sb, " slice of ")
|
||||||
|
strings.write_f64(&sb, 3.14,'g',true) // See `fmt.fmt_float` byte codes
|
||||||
|
strings.write_string(&sb, " is ")
|
||||||
|
strings.write_int(&sb, 180)
|
||||||
|
strings.write_rune(&sb,'°')
|
||||||
|
the_string :=strings.to_string(sb)
|
||||||
|
fmt.println(the_string)
|
||||||
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
a slice of +3.14 is 180°
|
||||||
|
|
||||||
|
*/
|
||||||
builder_make :: proc{
|
builder_make :: proc{
|
||||||
builder_make_none,
|
builder_make_none,
|
||||||
builder_make_len,
|
builder_make_len,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
@(deprecated="Prefer clone. It now returns an optional allocator error")
|
@(deprecated="Prefer clone. It now returns an optional allocator error")
|
||||||
clone_safe :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) {
|
clone_safe :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) {
|
||||||
return clone(s, allocator, loc)
|
return clone(s, allocator, loc)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Clones a string and appends a null-byte to make it a cstring
|
Clones a string and appends a null-byte to make it a cstring
|
||||||
@@ -263,7 +263,7 @@ compare :: proc(lhs, rhs: string) -> (result: int) {
|
|||||||
return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs)
|
return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Returns the byte offset of the rune `r` in the string `s`, -1 when not found
|
Checks if rune `r` in the string `s`
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
- s: The input string
|
- s: The input string
|
||||||
@@ -629,7 +629,7 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
@(deprecated="Prefer join. It now returns an optional allocator error")
|
@(deprecated="Prefer join. It now returns an optional allocator error")
|
||||||
join_safe :: proc(a: []string, sep: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) {
|
join_safe :: proc(a: []string, sep: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) {
|
||||||
return join(a, sep, allocator)
|
return join(a, sep, allocator)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Returns a combined string from the slice of strings `a` without a separator
|
Returns a combined string from the slice of strings `a` without a separator
|
||||||
@@ -689,7 +689,7 @@ The concatenated string, and an error if allocation fails
|
|||||||
*/
|
*/
|
||||||
@(deprecated="Prefer concatenate. It now returns an optional allocator error")
|
@(deprecated="Prefer concatenate. It now returns an optional allocator error")
|
||||||
concatenate_safe :: proc(a: []string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) {
|
concatenate_safe :: proc(a: []string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) {
|
||||||
return concatenate(a, allocator)
|
return concatenate(a, allocator)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Returns a substring of the input string `s` with the specified rune offset and length
|
Returns a substring of the input string `s` with the specified rune offset and length
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ selection_delete :: proc(s: ^State) {
|
|||||||
|
|
||||||
translate_position :: proc(s: ^State, pos: int, t: Translation) -> int {
|
translate_position :: proc(s: ^State, pos: int, t: Translation) -> int {
|
||||||
is_continuation_byte :: proc(b: byte) -> bool {
|
is_continuation_byte :: proc(b: byte) -> bool {
|
||||||
return b <= 0x80 && b < 0xc0
|
return b >= 0x80 && b < 0xc0
|
||||||
}
|
}
|
||||||
is_space :: proc(b: byte) -> bool {
|
is_space :: proc(b: byte) -> bool {
|
||||||
return b == ' ' || b == '\t' || b == '\n'
|
return b == ' ' || b == '\t' || b == '\n'
|
||||||
@@ -410,4 +410,4 @@ perform_command :: proc(s: ^State, cmd: Command) {
|
|||||||
case .Select_Line_Start: select_to(s, .Soft_Line_Start)
|
case .Select_Line_Start: select_to(s, .Soft_Line_Start)
|
||||||
case .Select_Line_End: select_to(s, .Soft_Line_End)
|
case .Select_Line_End: select_to(s, .Soft_Line_End)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ struct BuildContext {
|
|||||||
String microarch;
|
String microarch;
|
||||||
BuildModeKind build_mode;
|
BuildModeKind build_mode;
|
||||||
bool generate_docs;
|
bool generate_docs;
|
||||||
|
bool custom_optimization_level;
|
||||||
i32 optimization_level;
|
i32 optimization_level;
|
||||||
bool show_timings;
|
bool show_timings;
|
||||||
TimingsExportFormat export_timings_format;
|
TimingsExportFormat export_timings_format;
|
||||||
@@ -1272,6 +1273,12 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
|
|||||||
gb_exit(1);
|
gb_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bc->ODIN_DEBUG && !bc->custom_optimization_level) {
|
||||||
|
// NOTE(bill): when building with `-debug` but not specifying an optimization level
|
||||||
|
// default to `-o:none` to improve the debug symbol generation by default
|
||||||
|
bc->optimization_level = -1; // -o:none
|
||||||
|
}
|
||||||
|
|
||||||
bc->optimization_level = gb_clamp(bc->optimization_level, -1, 2);
|
bc->optimization_level = gb_clamp(bc->optimization_level, -1, 2);
|
||||||
|
|
||||||
// ENFORCE DYNAMIC MAP CALLS
|
// ENFORCE DYNAMIC MAP CALLS
|
||||||
@@ -1285,9 +1292,6 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef LINK_FLAG_X64
|
|
||||||
#undef LINK_FLAG_386
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
|
|||||||
@@ -1688,6 +1688,8 @@ gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) {
|
|||||||
if (is_type_integer(type)) {
|
if (is_type_integer(type)) {
|
||||||
error_line("\tSuggestion: Did you mean to use the bitwise not operator '~'?\n");
|
error_line("\tSuggestion: Did you mean to use the bitwise not operator '~'?\n");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
o->type = t_untyped_bool;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
+15
-8
@@ -378,6 +378,17 @@ gb_internal void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, T
|
|||||||
rw_mutex_unlock(&ctx->info->gen_types_mutex);
|
rw_mutex_unlock(&ctx->info->gen_types_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool check_constant_parameter_value(Type *type, Ast *expr) {
|
||||||
|
if (!is_type_constant_type(type)) {
|
||||||
|
gbString str = type_to_string(type);
|
||||||
|
defer (gb_string_free(str));
|
||||||
|
error(expr, "A parameter must be a valid constant type, got %s", str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
|
gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params,
|
||||||
bool *is_polymorphic_,
|
bool *is_polymorphic_,
|
||||||
Ast *node, Array<Operand> *poly_operands) {
|
Ast *node, Array<Operand> *poly_operands) {
|
||||||
@@ -477,10 +488,8 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
|
|||||||
type = t_invalid;
|
type = t_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_type_param && !is_type_constant_type(type)) {
|
if (!is_type_param && check_constant_parameter_value(type, params[i])) {
|
||||||
gbString str = type_to_string(type);
|
// failed
|
||||||
error(params[i], "A parameter must be a valid constant type, got %s", str);
|
|
||||||
gb_string_free(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope *scope = ctx->scope;
|
Scope *scope = ctx->scope;
|
||||||
@@ -1757,10 +1766,8 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
|
|||||||
p->flags &= ~FieldFlag_by_ptr;
|
p->flags &= ~FieldFlag_by_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_type_constant_type(type) && !is_type_polymorphic(type)) {
|
if (!is_type_polymorphic(type) && check_constant_parameter_value(type, params[i])) {
|
||||||
gbString str = type_to_string(type);
|
// failed
|
||||||
error(params[i], "A parameter must be a valid constant type, got %s", str);
|
|
||||||
gb_string_free(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
|
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
|
||||||
|
|||||||
@@ -436,6 +436,32 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal void syntax_error_with_verbose_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||||
|
global_error_collector.count.fetch_add(1);
|
||||||
|
|
||||||
|
mutex_lock(&global_error_collector.mutex);
|
||||||
|
// NOTE(bill): Duplicate error, skip it
|
||||||
|
if (pos.line == 0) {
|
||||||
|
error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
|
||||||
|
error_out_va(fmt, va);
|
||||||
|
error_out("\n");
|
||||||
|
} else if (global_error_collector.prev != pos) {
|
||||||
|
global_error_collector.prev = pos;
|
||||||
|
error_out_pos(pos);
|
||||||
|
if (has_ansi_terminal_colours()) {
|
||||||
|
error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
|
||||||
|
}
|
||||||
|
error_out_va(fmt, va);
|
||||||
|
error_out("\n");
|
||||||
|
show_error_on_line(pos, end);
|
||||||
|
}
|
||||||
|
mutex_unlock(&global_error_collector.mutex);
|
||||||
|
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) {
|
||||||
|
gb_exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
|
||||||
if (global_warnings_as_errors()) {
|
if (global_warnings_as_errors()) {
|
||||||
syntax_error_va(pos, end, fmt, va);
|
syntax_error_va(pos, end, fmt, va);
|
||||||
@@ -515,6 +541,14 @@ gb_internal void syntax_warning(Token const &token, char const *fmt, ...) {
|
|||||||
va_end(va);
|
va_end(va);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal void syntax_error_with_verbose(TokenPos pos, TokenPos end, char const *fmt, ...) {
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
syntax_error_with_verbose_va(pos, end, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gb_internal void compiler_error(char const *fmt, ...) {
|
gb_internal void compiler_error(char const *fmt, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
|
|||||||
@@ -514,6 +514,9 @@ gb_internal bool lb_is_matrix_simdable(Type *t) {
|
|||||||
// it's not aligned well enough to use the vector instructions
|
// it's not aligned well enough to use the vector instructions
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ((mt->Matrix.row_count & 1) ^ (mt->Matrix.column_count & 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (elem->kind == Type_Basic) {
|
if (elem->kind == Type_Basic) {
|
||||||
switch (elem->Basic.kind) {
|
switch (elem->Basic.kind) {
|
||||||
@@ -2833,7 +2836,7 @@ gb_internal lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue cons
|
|||||||
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
|
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
|
||||||
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
|
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
|
||||||
lb_emit_store(p, ptr, addr);
|
lb_emit_store(p, ptr, addr);
|
||||||
lb_emit_store(p, idx, index);
|
lb_emit_store(p, idx, lb_emit_conv(p, index, t_int));
|
||||||
|
|
||||||
return lb_addr_load(p, v);
|
return lb_addr_load(p, v);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1035,12 +1035,16 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
|||||||
case BuildFlag_OptimizationMode: {
|
case BuildFlag_OptimizationMode: {
|
||||||
GB_ASSERT(value.kind == ExactValue_String);
|
GB_ASSERT(value.kind == ExactValue_String);
|
||||||
if (value.value_string == "none") {
|
if (value.value_string == "none") {
|
||||||
|
build_context.custom_optimization_level = true;
|
||||||
build_context.optimization_level = -1;
|
build_context.optimization_level = -1;
|
||||||
} else if (value.value_string == "minimal") {
|
} else if (value.value_string == "minimal") {
|
||||||
|
build_context.custom_optimization_level = true;
|
||||||
build_context.optimization_level = 0;
|
build_context.optimization_level = 0;
|
||||||
} else if (value.value_string == "size") {
|
} else if (value.value_string == "size") {
|
||||||
|
build_context.custom_optimization_level = true;
|
||||||
build_context.optimization_level = 1;
|
build_context.optimization_level = 1;
|
||||||
} else if (value.value_string == "speed") {
|
} else if (value.value_string == "speed") {
|
||||||
|
build_context.custom_optimization_level = true;
|
||||||
build_context.optimization_level = 2;
|
build_context.optimization_level = 2;
|
||||||
} else {
|
} else {
|
||||||
gb_printf_err("Invalid optimization mode for -o:<string>, got %.*s\n", LIT(value.value_string));
|
gb_printf_err("Invalid optimization mode for -o:<string>, got %.*s\n", LIT(value.value_string));
|
||||||
|
|||||||
+47
-3
@@ -418,6 +418,25 @@ gb_internal void error(Ast *node, char const *fmt, ...) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal void syntax_error_with_verbose(Ast *node, char const *fmt, ...) {
|
||||||
|
Token token = {};
|
||||||
|
TokenPos end_pos = {};
|
||||||
|
if (node != nullptr) {
|
||||||
|
token = ast_token(node);
|
||||||
|
end_pos = ast_end_pos(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
syntax_error_with_verbose_va(token.pos, end_pos, fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
if (node != nullptr && node->file_id != 0) {
|
||||||
|
AstFile *f = node->thread_safe_file();
|
||||||
|
f->error_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal void error_no_newline(Ast *node, char const *fmt, ...) {
|
gb_internal void error_no_newline(Ast *node, char const *fmt, ...) {
|
||||||
Token token = {};
|
Token token = {};
|
||||||
if (node != nullptr) {
|
if (node != nullptr) {
|
||||||
@@ -496,11 +515,17 @@ gb_internal Ast *ast_tag_expr(AstFile *f, Token token, Token name, Ast *expr) {
|
|||||||
|
|
||||||
gb_internal Ast *ast_unary_expr(AstFile *f, Token op, Ast *expr) {
|
gb_internal Ast *ast_unary_expr(AstFile *f, Token op, Ast *expr) {
|
||||||
Ast *result = alloc_ast_node(f, Ast_UnaryExpr);
|
Ast *result = alloc_ast_node(f, Ast_UnaryExpr);
|
||||||
|
|
||||||
|
if (expr && expr->kind == Ast_OrReturnExpr) {
|
||||||
|
syntax_error_with_verbose(expr, "'or_return' within an unary expression not wrapped in parentheses (...)");
|
||||||
|
}
|
||||||
|
|
||||||
result->UnaryExpr.op = op;
|
result->UnaryExpr.op = op;
|
||||||
result->UnaryExpr.expr = expr;
|
result->UnaryExpr.expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
|
gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
|
||||||
Ast *result = alloc_ast_node(f, Ast_BinaryExpr);
|
Ast *result = alloc_ast_node(f, Ast_BinaryExpr);
|
||||||
|
|
||||||
@@ -513,6 +538,13 @@ gb_internal Ast *ast_binary_expr(AstFile *f, Token op, Ast *left, Ast *right) {
|
|||||||
right = ast_bad_expr(f, op, op);
|
right = ast_bad_expr(f, op, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left->kind == Ast_OrReturnExpr) {
|
||||||
|
syntax_error_with_verbose(left, "'or_return' within a binary expression not wrapped in parentheses (...)");
|
||||||
|
}
|
||||||
|
if (right->kind == Ast_OrReturnExpr) {
|
||||||
|
syntax_error_with_verbose(right, "'or_return' within a binary expression not wrapped in parentheses (...)");
|
||||||
|
}
|
||||||
|
|
||||||
result->BinaryExpr.op = op;
|
result->BinaryExpr.op = op;
|
||||||
result->BinaryExpr.left = left;
|
result->BinaryExpr.left = left;
|
||||||
result->BinaryExpr.right = right;
|
result->BinaryExpr.right = right;
|
||||||
@@ -2765,6 +2797,12 @@ gb_internal Ast *parse_call_expr(AstFile *f, Ast *operand) {
|
|||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal void parse_check_or_return(Ast *operand, char const *msg) {
|
||||||
|
if (operand && operand->kind == Ast_OrReturnExpr) {
|
||||||
|
syntax_error_with_verbose(operand, "'or_return' use within %s is not wrapped in parentheses (...)", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||||
if (operand == nullptr) {
|
if (operand == nullptr) {
|
||||||
if (f->allow_type) return nullptr;
|
if (f->allow_type) return nullptr;
|
||||||
@@ -2778,6 +2816,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
|||||||
while (loop) {
|
while (loop) {
|
||||||
switch (f->curr_token.kind) {
|
switch (f->curr_token.kind) {
|
||||||
case Token_OpenParen:
|
case Token_OpenParen:
|
||||||
|
parse_check_or_return(operand, "call expression");
|
||||||
operand = parse_call_expr(f, operand);
|
operand = parse_call_expr(f, operand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2785,12 +2824,11 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
|||||||
Token token = advance_token(f);
|
Token token = advance_token(f);
|
||||||
switch (f->curr_token.kind) {
|
switch (f->curr_token.kind) {
|
||||||
case Token_Ident:
|
case Token_Ident:
|
||||||
|
parse_check_or_return(operand, "selector expression");
|
||||||
operand = ast_selector_expr(f, token, operand, parse_ident(f));
|
operand = ast_selector_expr(f, token, operand, parse_ident(f));
|
||||||
break;
|
break;
|
||||||
// case Token_Integer:
|
|
||||||
// operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs));
|
|
||||||
// break;
|
|
||||||
case Token_OpenParen: {
|
case Token_OpenParen: {
|
||||||
|
parse_check_or_return(operand, "type assertion");
|
||||||
Token open = expect_token(f, Token_OpenParen);
|
Token open = expect_token(f, Token_OpenParen);
|
||||||
Ast *type = parse_type(f);
|
Ast *type = parse_type(f);
|
||||||
Token close = expect_token(f, Token_CloseParen);
|
Token close = expect_token(f, Token_CloseParen);
|
||||||
@@ -2798,6 +2836,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_Question: {
|
case Token_Question: {
|
||||||
|
parse_check_or_return(operand, ".? based type assertion");
|
||||||
Token question = expect_token(f, Token_Question);
|
Token question = expect_token(f, Token_Question);
|
||||||
Ast *type = ast_unary_expr(f, question, nullptr);
|
Ast *type = ast_unary_expr(f, question, nullptr);
|
||||||
operand = ast_type_assertion(f, operand, token, type);
|
operand = ast_type_assertion(f, operand, token, type);
|
||||||
@@ -2813,6 +2852,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_ArrowRight: {
|
case Token_ArrowRight: {
|
||||||
|
parse_check_or_return(operand, "-> based call expression");
|
||||||
Token token = advance_token(f);
|
Token token = advance_token(f);
|
||||||
|
|
||||||
operand = ast_selector_expr(f, token, operand, parse_ident(f));
|
operand = ast_selector_expr(f, token, operand, parse_ident(f));
|
||||||
@@ -2870,11 +2910,14 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
|||||||
if (indices[0] == nullptr || indices[1] == nullptr) {
|
if (indices[0] == nullptr || indices[1] == nullptr) {
|
||||||
syntax_error(open, "Matrix index expressions require both row and column indices");
|
syntax_error(open, "Matrix index expressions require both row and column indices");
|
||||||
}
|
}
|
||||||
|
parse_check_or_return(operand, "matrix index expression");
|
||||||
operand = ast_matrix_index_expr(f, operand, open, close, interval, indices[0], indices[1]);
|
operand = ast_matrix_index_expr(f, operand, open, close, interval, indices[0], indices[1]);
|
||||||
} else {
|
} else {
|
||||||
|
parse_check_or_return(operand, "slice expression");
|
||||||
operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
|
operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
parse_check_or_return(operand, "index expression");
|
||||||
operand = ast_index_expr(f, operand, indices[0], open, close);
|
operand = ast_index_expr(f, operand, indices[0], open, close);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2882,6 +2925,7 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token_Pointer: // Deference
|
case Token_Pointer: // Deference
|
||||||
|
parse_check_or_return(operand, "dereference");
|
||||||
operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
|
operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
+5
-5
@@ -70,8 +70,8 @@ main :: proc() {
|
|||||||
test_sha3_256(&t)
|
test_sha3_256(&t)
|
||||||
test_sha3_384(&t)
|
test_sha3_384(&t)
|
||||||
test_sha3_512(&t)
|
test_sha3_512(&t)
|
||||||
test_shake_128(&t)
|
// test_shake_128(&t)
|
||||||
test_shake_256(&t)
|
// test_shake_256(&t)
|
||||||
test_keccak_512(&t)
|
test_keccak_512(&t)
|
||||||
test_whirlpool(&t)
|
test_whirlpool(&t)
|
||||||
test_gost(&t)
|
test_gost(&t)
|
||||||
@@ -79,9 +79,9 @@ main :: proc() {
|
|||||||
test_streebog_512(&t)
|
test_streebog_512(&t)
|
||||||
test_blake2b(&t)
|
test_blake2b(&t)
|
||||||
test_ripemd_160(&t)
|
test_ripemd_160(&t)
|
||||||
test_tiger_128(&t)
|
// test_tiger_128(&t)
|
||||||
test_tiger_160(&t)
|
// test_tiger_160(&t)
|
||||||
test_tiger_192(&t)
|
// test_tiger_192(&t)
|
||||||
test_sm3(&t)
|
test_sm3(&t)
|
||||||
test_skein512_256(&t)
|
test_skein512_256(&t)
|
||||||
test_skein512_512(&t)
|
test_skein512_512(&t)
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+5
-3
@@ -62,7 +62,7 @@ CRL_SIGN :: x509_cert_key_constraints(512)
|
|||||||
ENCIPHER_ONLY :: x509_cert_key_constraints(256)
|
ENCIPHER_ONLY :: x509_cert_key_constraints(256)
|
||||||
DECIPHER_ONLY :: x509_cert_key_constraints(128)
|
DECIPHER_ONLY :: x509_cert_key_constraints(128)
|
||||||
|
|
||||||
HASH_SHA1 :: "SHA1"
|
HASH_SHA1 :: "SHA-1"
|
||||||
HASH_SHA_224 :: "SHA-224"
|
HASH_SHA_224 :: "SHA-224"
|
||||||
HASH_SHA_256 :: "SHA-256"
|
HASH_SHA_256 :: "SHA-256"
|
||||||
HASH_SHA_384 :: "SHA-384"
|
HASH_SHA_384 :: "SHA-384"
|
||||||
@@ -141,10 +141,12 @@ fpe_struct :: struct{}
|
|||||||
fpe_t :: ^fpe_struct
|
fpe_t :: ^fpe_struct
|
||||||
|
|
||||||
when ODIN_OS == .Windows {
|
when ODIN_OS == .Windows {
|
||||||
foreign import botan_lib "botan.lib"
|
foreign import botan_lib "botan-3.lib"
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import botan_lib "system:botan-3"
|
||||||
} else {
|
} else {
|
||||||
foreign import botan_lib "system:botan-2"
|
foreign import botan_lib "system:botan-2"
|
||||||
}
|
}
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
@(default_calling_convention="c")
|
||||||
@(link_prefix="botan_")
|
@(link_prefix="botan_")
|
||||||
|
|||||||
+30
@@ -27,4 +27,34 @@ Notification_object :: proc(self: ^Notification) -> ^Object {
|
|||||||
@(objc_type=Notification, objc_name="userInfo")
|
@(objc_type=Notification, objc_name="userInfo")
|
||||||
Notification_userInfo :: proc(self: ^Notification) -> ^Dictionary {
|
Notification_userInfo :: proc(self: ^Notification) -> ^Dictionary {
|
||||||
return msgSend(^Dictionary, self, "userInfo")
|
return msgSend(^Dictionary, self, "userInfo")
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationName :: ^String
|
||||||
|
|
||||||
|
@(objc_class="NSNotificationCenter")
|
||||||
|
NotificationCenter :: struct{using _: Object}
|
||||||
|
|
||||||
|
|
||||||
|
@(objc_type=NotificationCenter, objc_name="alloc", objc_is_class_method=true)
|
||||||
|
NotificationCenter_alloc :: proc() -> ^NotificationCenter {
|
||||||
|
return msgSend(^NotificationCenter, NotificationCenter, "alloc")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(objc_type=NotificationCenter, objc_name="init")
|
||||||
|
NotificationCenter_init :: proc(self: ^NotificationCenter) -> ^NotificationCenter {
|
||||||
|
return msgSend(^NotificationCenter, self, "init")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(objc_type=NotificationCenter, objc_name="defaultCenter", objc_is_class_method=true)
|
||||||
|
NotificationCenter_defaultCenter :: proc() -> ^NotificationCenter {
|
||||||
|
return msgSend(^NotificationCenter, NotificationCenter, "defaultCenter")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(objc_type=NotificationCenter, objc_name="addObserver")
|
||||||
|
NotificationCenter_addObserverName :: proc(self: ^NotificationCenter, name: NotificationName, pObj: ^Object, pQueue: rawptr, block: ^Block) -> ^Object {
|
||||||
|
return msgSend(^Object, self, "addObserverName:object:queue:block:", name, pObj, pQueue, block)
|
||||||
|
}
|
||||||
|
@(objc_type=NotificationCenter, objc_name="removeObserver")
|
||||||
|
NotificationCenter_removeObserver :: proc(self: ^NotificationCenter, pObserver: ^Object) {
|
||||||
|
msgSend(nil, self, "removeObserver:", pObserver)
|
||||||
}
|
}
|
||||||
+875
File diff suppressed because it is too large
Load Diff
Vendored
+86
-6
@@ -17,6 +17,14 @@ AccelerationStructureInstanceOption :: enum u32 {
|
|||||||
NonOpaque = 3,
|
NonOpaque = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AccelerationStructureRefitOptions :: distinct bit_set[AccelerationStructureRefitOption; NS.UInteger]
|
||||||
|
AccelerationStructureRefitOption :: enum NS.UInteger {
|
||||||
|
VertexData = 0,
|
||||||
|
PerPrimitiveData = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MotionBorderMode :: enum u32 {
|
MotionBorderMode :: enum u32 {
|
||||||
Clamp = 0,
|
Clamp = 0,
|
||||||
Vanish = 1,
|
Vanish = 1,
|
||||||
@@ -148,6 +156,21 @@ BinaryArchiveError :: enum NS.UInteger {
|
|||||||
InvalidFile = 1,
|
InvalidFile = 1,
|
||||||
UnexpectedElement = 2,
|
UnexpectedElement = 2,
|
||||||
CompilationFailure = 3,
|
CompilationFailure = 3,
|
||||||
|
InternalError = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
BindingType :: enum NS.Integer {
|
||||||
|
Buffer = 0,
|
||||||
|
ThreadgroupMemory = 1,
|
||||||
|
Texture = 2,
|
||||||
|
Sampler = 3,
|
||||||
|
ImageblockData = 16,
|
||||||
|
Imageblock = 17,
|
||||||
|
VisibleFunctionTable = 24,
|
||||||
|
PrimitiveAccelerationStructure = 25,
|
||||||
|
InstanceAccelerationStructure = 26,
|
||||||
|
IntersectionFunctionTable = 27,
|
||||||
|
ObjectPayload = 34,
|
||||||
}
|
}
|
||||||
|
|
||||||
BlitOptionFlag :: enum NS.UInteger {
|
BlitOptionFlag :: enum NS.UInteger {
|
||||||
@@ -171,15 +194,16 @@ CaptureDestination :: enum NS.Integer {
|
|||||||
|
|
||||||
CommandBufferStatus :: enum NS.UInteger {
|
CommandBufferStatus :: enum NS.UInteger {
|
||||||
NotEnqueued = 0,
|
NotEnqueued = 0,
|
||||||
Enqueued = 1,
|
Enqueued = 1,
|
||||||
Committed = 2,
|
Committed = 2,
|
||||||
Scheduled = 3,
|
Scheduled = 3,
|
||||||
Completed = 4,
|
Completed = 4,
|
||||||
Error = 5,
|
Error = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBufferError :: enum NS.UInteger {
|
CommandBufferError :: enum NS.UInteger {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
Internal = 1,
|
||||||
Timeout = 2,
|
Timeout = 2,
|
||||||
PageFault = 3,
|
PageFault = 3,
|
||||||
AccessRevoked = 4,
|
AccessRevoked = 4,
|
||||||
@@ -232,6 +256,7 @@ BarrierScope :: distinct bit_set[BarrierScopeFlag; NS.UInteger]
|
|||||||
CounterSampleBufferError :: enum NS.Integer {
|
CounterSampleBufferError :: enum NS.Integer {
|
||||||
OutOfMemory = 0,
|
OutOfMemory = 0,
|
||||||
Invalid = 1,
|
Invalid = 1,
|
||||||
|
Internal = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareFunction :: enum NS.UInteger {
|
CompareFunction :: enum NS.UInteger {
|
||||||
@@ -312,6 +337,13 @@ GPUFamily :: enum NS.Integer {
|
|||||||
Common3 = 3003,
|
Common3 = 3003,
|
||||||
MacCatalyst1 = 4001,
|
MacCatalyst1 = 4001,
|
||||||
MacCatalyst2 = 4002,
|
MacCatalyst2 = 4002,
|
||||||
|
Metal3 = 5001,
|
||||||
|
}
|
||||||
|
|
||||||
|
SparsePageSize :: enum NS.Integer {
|
||||||
|
Size16 = 101,
|
||||||
|
Size64 = 102,
|
||||||
|
Size256 = 103,
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceLocation :: enum NS.UInteger {
|
DeviceLocation :: enum NS.UInteger {
|
||||||
@@ -409,6 +441,9 @@ FunctionType :: enum NS.UInteger {
|
|||||||
Kernel = 3,
|
Kernel = 3,
|
||||||
Visible = 5,
|
Visible = 5,
|
||||||
Intersection = 6,
|
Intersection = 6,
|
||||||
|
Mesh = 7,
|
||||||
|
Object = 8,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -421,15 +456,22 @@ LanguageVersion :: enum NS.UInteger {
|
|||||||
Version2_2 = 131074,
|
Version2_2 = 131074,
|
||||||
Version2_3 = 131075,
|
Version2_3 = 131075,
|
||||||
Version2_4 = 131076,
|
Version2_4 = 131076,
|
||||||
|
Version3_0 = 196608,
|
||||||
}
|
}
|
||||||
|
|
||||||
LibraryType :: enum NS.Integer {
|
LibraryType :: enum NS.Integer {
|
||||||
Executable = 0,
|
Executable = 0,
|
||||||
Dynamic = 1,
|
Dynamic = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
LibraryOptimizationLevel :: enum NS.Integer {
|
||||||
|
Default = 0,
|
||||||
|
Size = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
LibraryError :: enum NS.UInteger {
|
LibraryError :: enum NS.UInteger {
|
||||||
Unsupported = 1,
|
Unsupported = 1,
|
||||||
|
Internal = 2,
|
||||||
CompileFailure = 3,
|
CompileFailure = 3,
|
||||||
CompileWarning = 4,
|
CompileWarning = 4,
|
||||||
FunctionNotFound = 5,
|
FunctionNotFound = 5,
|
||||||
@@ -624,6 +666,8 @@ RenderStage :: enum NS.UInteger {
|
|||||||
Vertex = 0,
|
Vertex = 0,
|
||||||
Fragment = 1,
|
Fragment = 1,
|
||||||
Tile = 2,
|
Tile = 2,
|
||||||
|
Object = 3,
|
||||||
|
Mesh = 4,
|
||||||
}
|
}
|
||||||
RenderStages :: distinct bit_set[RenderStage; NS.UInteger]
|
RenderStages :: distinct bit_set[RenderStage; NS.UInteger]
|
||||||
|
|
||||||
@@ -861,6 +905,42 @@ IndexType :: enum NS.UInteger {
|
|||||||
UInt32 = 1,
|
UInt32 = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IOPriority :: enum NS.Integer {
|
||||||
|
High = 0,
|
||||||
|
Normal = 1,
|
||||||
|
Low = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
IOCommandQueueType :: enum NS.Integer {
|
||||||
|
Concurrent = 0,
|
||||||
|
Serial = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
IOError :: enum NS.Integer {
|
||||||
|
URLInvalid = 1,
|
||||||
|
Internal = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStatus :: enum NS.Integer {
|
||||||
|
Pending = 0,
|
||||||
|
Cancelled = 1,
|
||||||
|
Error = 2,
|
||||||
|
Complete = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
IOCompressionMethod :: enum NS.Integer {
|
||||||
|
Zlib = 0,
|
||||||
|
LZFSE = 1,
|
||||||
|
LZ4 = 2,
|
||||||
|
LZMA = 3,
|
||||||
|
LZBitmap = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
IOCompressionStatus :: enum NS.Integer {
|
||||||
|
Complete = 0,
|
||||||
|
Error = 1,
|
||||||
|
}
|
||||||
|
|
||||||
StepFunction :: enum NS.UInteger {
|
StepFunction :: enum NS.UInteger {
|
||||||
Constant = 0,
|
Constant = 0,
|
||||||
PerVertex = 1,
|
PerVertex = 1,
|
||||||
|
|||||||
Vendored
+12
-2
@@ -4,9 +4,11 @@ import NS "vendor:darwin/Foundation"
|
|||||||
|
|
||||||
foreign import "system:Metal.framework"
|
foreign import "system:Metal.framework"
|
||||||
|
|
||||||
CommonCounter :: ^NS.String
|
CommonCounter :: ^NS.String
|
||||||
CommonCounterSet :: ^NS.String
|
CommonCounterSet :: ^NS.String
|
||||||
DeviceNotificationName :: ^NS.String
|
DeviceNotificationName :: ^NS.String
|
||||||
|
ErrorUserInfoKey :: ^NS.ErrorUserInfoKey
|
||||||
|
ErrorDomain :: ^NS.ErrorDomain
|
||||||
|
|
||||||
foreign Metal {
|
foreign Metal {
|
||||||
@(linkage="weak") CommonCounterTimestamp: CommonCounter
|
@(linkage="weak") CommonCounterTimestamp: CommonCounter
|
||||||
@@ -36,4 +38,12 @@ foreign Metal {
|
|||||||
@(linkage="weak") DeviceWasAddedNotification: DeviceNotificationName
|
@(linkage="weak") DeviceWasAddedNotification: DeviceNotificationName
|
||||||
@(linkage="weak") DeviceRemovalRequestedNotification: DeviceNotificationName
|
@(linkage="weak") DeviceRemovalRequestedNotification: DeviceNotificationName
|
||||||
@(linkage="weak") DeviceWasRemovedNotification: DeviceNotificationName
|
@(linkage="weak") DeviceWasRemovedNotification: DeviceNotificationName
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign Metal {
|
||||||
|
@(linkage="weak") CommandBufferEncoderInfoErrorKey: ErrorUserInfoKey
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign Metal {
|
||||||
|
@(linkage="weak") IOErrorDomain: ErrorDomain
|
||||||
}
|
}
|
||||||
+7
@@ -1,6 +1,7 @@
|
|||||||
package objc_Metal
|
package objc_Metal
|
||||||
|
|
||||||
import NS "vendor:darwin/Foundation"
|
import NS "vendor:darwin/Foundation"
|
||||||
|
import "core:c"
|
||||||
|
|
||||||
@(require)
|
@(require)
|
||||||
foreign import "system:Metal.framework"
|
foreign import "system:Metal.framework"
|
||||||
@@ -11,6 +12,12 @@ foreign Metal {
|
|||||||
CopyAllDevicesWithObserver :: proc(observer: ^id, handler: DeviceNotificationHandler) -> ^NS.Array ---
|
CopyAllDevicesWithObserver :: proc(observer: ^id, handler: DeviceNotificationHandler) -> ^NS.Array ---
|
||||||
CreateSystemDefaultDevice :: proc() -> ^Device ---
|
CreateSystemDefaultDevice :: proc() -> ^Device ---
|
||||||
RemoveDeviceObserver :: proc(observer: id) ---
|
RemoveDeviceObserver :: proc(observer: id) ---
|
||||||
|
|
||||||
|
|
||||||
|
IOCompressionContextDefaultChunkSize :: proc() -> c.size_t ---
|
||||||
|
IOCreateCompressionContext :: proc(path: cstring, type: IOCompressionMethod, chuckSize: c.size_t) -> rawptr ---
|
||||||
|
IOCompressionContextAppendData :: proc(ctx: rawptr, data: rawptr, size: c.size_t) ---
|
||||||
|
IOFlushAndDestroyCompressionContext :: proc(ctx: rawptr) -> IOCompressionStatus ---
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
@@ -133,6 +133,8 @@ Region :: struct {
|
|||||||
|
|
||||||
SamplePosition :: distinct [2]f32
|
SamplePosition :: distinct [2]f32
|
||||||
|
|
||||||
|
ResourceID :: distinct u64
|
||||||
|
|
||||||
ScissorRect :: struct {
|
ScissorRect :: struct {
|
||||||
x: NS.Integer,
|
x: NS.Integer,
|
||||||
y: NS.Integer,
|
y: NS.Integer,
|
||||||
|
|||||||
+11
@@ -56,6 +56,17 @@ MetalLayer_setFramebufferOnly :: proc(self: ^MetalLayer, ok: NS.BOOL) {
|
|||||||
msgSend(nil, self, "setFramebufferOnly:", ok)
|
msgSend(nil, self, "setFramebufferOnly:", ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(objc_type=MetalLayer, objc_name="drawableSize")
|
||||||
|
MetalLayer_drawableSize :: proc(self: ^MetalLayer) -> NS.Size {
|
||||||
|
return msgSend(NS.Size, self, "drawableSize")
|
||||||
|
}
|
||||||
|
@(objc_type=MetalLayer, objc_name="setDrawableSize")
|
||||||
|
MetalLayer_setDrawableSize :: proc(self: ^MetalLayer, drawableSize: NS.Size) {
|
||||||
|
msgSend(nil, self, "setDrawableSize:", drawableSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@(objc_type=MetalLayer, objc_name="frame")
|
@(objc_type=MetalLayer, objc_name="frame")
|
||||||
MetalLayer_frame :: proc(self: ^MetalLayer) -> NS.Rect {
|
MetalLayer_frame :: proc(self: ^MetalLayer) -> NS.Rect {
|
||||||
return msgSend(NS.Rect, self, "frame")
|
return msgSend(NS.Rect, self, "frame")
|
||||||
|
|||||||
Vendored
+3
-4
@@ -26,13 +26,11 @@ import "core:c"
|
|||||||
import "core:intrinsics"
|
import "core:intrinsics"
|
||||||
|
|
||||||
when ODIN_OS == .Windows {
|
when ODIN_OS == .Windows {
|
||||||
foreign import _lib "SDL2.lib"
|
foreign import lib "SDL2.lib"
|
||||||
} else {
|
} else {
|
||||||
foreign import _lib "system:SDL2"
|
foreign import lib "system:SDL2"
|
||||||
}
|
}
|
||||||
|
|
||||||
lib :: _lib
|
|
||||||
|
|
||||||
version :: struct {
|
version :: struct {
|
||||||
major: u8, /**< major version */
|
major: u8, /**< major version */
|
||||||
minor: u8, /**< minor version */
|
minor: u8, /**< minor version */
|
||||||
@@ -47,6 +45,7 @@ PATCHLEVEL :: 16
|
|||||||
foreign lib {
|
foreign lib {
|
||||||
GetVersion :: proc(ver: ^version) ---
|
GetVersion :: proc(ver: ^version) ---
|
||||||
GetRevision :: proc() -> cstring ---
|
GetRevision :: proc() -> cstring ---
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InitFlag :: enum u32 {
|
InitFlag :: enum u32 {
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Audio format flags.
|
* \brief Audio format flags.
|
||||||
*
|
*
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The blend mode used in SDL_RenderCopy() and drawing operations.
|
* \brief The blend mode used in SDL_RenderCopy() and drawing operations.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
/* This is a guess for the cacheline size used for padding.
|
/* This is a guess for the cacheline size used for padding.
|
||||||
* Most x86 processors have a 64 byte cache line.
|
* Most x86 processors have a 64 byte cache line.
|
||||||
* The 64-bit PowerPC processors have a 128 byte cache line.
|
* The 64-bit PowerPC processors have a 128 byte cache line.
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
RELEASED :: 0
|
RELEASED :: 0
|
||||||
PRESSED :: 1
|
PRESSED :: 1
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
GameController :: struct {}
|
GameController :: struct {}
|
||||||
|
|
||||||
GameControllerType :: enum c.int {
|
GameControllerType :: enum c.int {
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
// Gesture
|
// Gesture
|
||||||
|
|
||||||
GestureID :: distinct i64
|
GestureID :: distinct i64
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
HINT_ACCELEROMETER_AS_JOYSTICK :: "SDL_ACCELEROMETER_AS_JOYSTICK"
|
HINT_ACCELEROMETER_AS_JOYSTICK :: "SDL_ACCELEROMETER_AS_JOYSTICK"
|
||||||
HINT_ALLOW_ALT_TAB_WHILE_GRABBED :: "SDL_ALLOW_ALT_TAB_WHILE_GRABBED"
|
HINT_ALLOW_ALT_TAB_WHILE_GRABBED :: "SDL_ALLOW_ALT_TAB_WHILE_GRABBED"
|
||||||
HINT_ALLOW_TOPMOST :: "SDL_ALLOW_TOPMOST"
|
HINT_ALLOW_TOPMOST :: "SDL_ALLOW_TOPMOST"
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
Joystick :: struct {}
|
Joystick :: struct {}
|
||||||
|
|
||||||
JoystickGUID :: struct {
|
JoystickGUID :: struct {
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
Keysym :: struct {
|
Keysym :: struct {
|
||||||
scancode: Scancode, /**< SDL physical key code - see ::SDL_Scancode for details */
|
scancode: Scancode, /**< SDL physical key code - see ::SDL_Scancode for details */
|
||||||
sym: Keycode, /**< SDL virtual key code - see ::SDL_Keycode for details */
|
sym: Keycode, /**< SDL virtual key code - see ::SDL_Keycode for details */
|
||||||
|
|||||||
Vendored
+1
@@ -1,5 +1,6 @@
|
|||||||
package sdl2
|
package sdl2
|
||||||
|
|
||||||
|
|
||||||
SCANCODE_MASK :: 1<<30
|
SCANCODE_MASK :: 1<<30
|
||||||
SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> Keycode {
|
SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> Keycode {
|
||||||
return Keycode(i32(X) | SCANCODE_MASK)
|
return Keycode(i32(X) | SCANCODE_MASK)
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
MAX_LOG_MESSAGE :: 4096
|
MAX_LOG_MESSAGE :: 4096
|
||||||
|
|
||||||
LogCategory :: enum c.int {
|
LogCategory :: enum c.int {
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
MessageBoxFlag :: enum u32 {
|
MessageBoxFlag :: enum u32 {
|
||||||
_ = 0,
|
_ = 0,
|
||||||
ERROR = 4, /**< error dialog */
|
ERROR = 4, /**< error dialog */
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
MetalView :: distinct rawptr
|
MetalView :: distinct rawptr
|
||||||
|
|
||||||
@(default_calling_convention="c", link_prefix="SDL_")
|
@(default_calling_convention="c", link_prefix="SDL_")
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
Cursor :: struct {}
|
Cursor :: struct {}
|
||||||
|
|
||||||
BUTTON :: #force_inline proc "c" (X: c.int) -> c.int { return 1 << u32(X-1) }
|
BUTTON :: #force_inline proc "c" (X: c.int) -> c.int { return 1 << u32(X-1) }
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
MUTEX_TIMEDOUT :: 1
|
MUTEX_TIMEDOUT :: 1
|
||||||
MUTEX_MAXWAIT :: ~u32(0)
|
MUTEX_MAXWAIT :: ~u32(0)
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
ALPHA_OPAQUE :: 255
|
ALPHA_OPAQUE :: 255
|
||||||
ALPHA_TRANSPARENT :: 0
|
ALPHA_TRANSPARENT :: 0
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
Point :: struct {
|
Point :: struct {
|
||||||
x: c.int,
|
x: c.int,
|
||||||
y: c.int,
|
y: c.int,
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
RendererFlag :: enum u32 {
|
RendererFlag :: enum u32 {
|
||||||
SOFTWARE = 0, /**< The renderer is a software fallback */
|
SOFTWARE = 0, /**< The renderer is a software fallback */
|
||||||
ACCELERATED = 1, /**< The renderer uses hardware acceleration */
|
ACCELERATED = 1, /**< The renderer uses hardware acceleration */
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
/* RWops Types */
|
/* RWops Types */
|
||||||
RWOPS_UNKNOWN :: 0 /**< Unknown stream type */
|
RWOPS_UNKNOWN :: 0 /**< Unknown stream type */
|
||||||
RWOPS_WINFILE :: 1 /**< Win32 file */
|
RWOPS_WINFILE :: 1 /**< Win32 file */
|
||||||
|
|||||||
Vendored
+6
@@ -5,6 +5,12 @@ import "core:intrinsics"
|
|||||||
import "core:runtime"
|
import "core:runtime"
|
||||||
_, _ :: intrinsics, runtime
|
_, _ :: intrinsics, runtime
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
bool :: distinct b32
|
bool :: distinct b32
|
||||||
#assert(size_of(bool) == size_of(c.int))
|
#assert(size_of(bool) == size_of(c.int))
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
SWSURFACE :: 0 /**< Just here for compatibility */
|
SWSURFACE :: 0 /**< Just here for compatibility */
|
||||||
PREALLOC :: 0x00000001 /**< Surface uses preallocated memory */
|
PREALLOC :: 0x00000001 /**< Surface uses preallocated memory */
|
||||||
RLEACCEL :: 0x00000002 /**< Surface is RLE encoded */
|
RLEACCEL :: 0x00000002 /**< Surface is RLE encoded */
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
// General
|
// General
|
||||||
@(default_calling_convention="c", link_prefix="SDL_")
|
@(default_calling_convention="c", link_prefix="SDL_")
|
||||||
foreign lib {
|
foreign lib {
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
SYSWM_TYPE :: enum c.int {
|
SYSWM_TYPE :: enum c.int {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
WINDOWS,
|
WINDOWS,
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
Thread :: struct {}
|
Thread :: struct {}
|
||||||
|
|
||||||
threadID :: distinct c.ulong
|
threadID :: distinct c.ulong
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
TimerCallback :: proc "c" (interval: u32, param: rawptr) -> u32
|
TimerCallback :: proc "c" (interval: u32, param: rawptr) -> u32
|
||||||
TimerID :: distinct c.int
|
TimerID :: distinct c.int
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
TouchID :: distinct i64
|
TouchID :: distinct i64
|
||||||
FingerID :: distinct i64
|
FingerID :: distinct i64
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
@@ -2,6 +2,12 @@ package sdl2
|
|||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
DisplayMode :: struct {
|
DisplayMode :: struct {
|
||||||
format: u32, /**< pixel format */
|
format: u32, /**< pixel format */
|
||||||
w: c.int, /**< width, in screen coordinates */
|
w: c.int, /**< width, in screen coordinates */
|
||||||
|
|||||||
Vendored
+6
@@ -3,6 +3,12 @@ package sdl2
|
|||||||
import "core:c"
|
import "core:c"
|
||||||
import vk "vendor:vulkan"
|
import vk "vendor:vulkan"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "SDL2.lib"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:SDL2"
|
||||||
|
}
|
||||||
|
|
||||||
VkInstance :: vk.Instance
|
VkInstance :: vk.Instance
|
||||||
VkSurfaceKHR :: vk.SurfaceKHR
|
VkSurfaceKHR :: vk.SurfaceKHR
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user